# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/Discord_Markov.py
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from typing import Dict, List
from pandas import DataFrame
# --------------------------------
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
import pandas as pd
import statsmodels.api as sm
import time

class Github_remiotore_freqtrade__Discord_Markov__20260111_210550(IStrategy):
    stoploss = -0.05

    # Optimal timeframe for the strategy
    timeframe = '30m'

    # run 'populate_indicators' only for new candle
    process_only_new_candles = True

    # Experimental settings (configuration will overide these if set)
    use_sell_signal = True
    sell_profit_only = False
    ignore_roi_if_buy_signal = False

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        data = dataframe.copy()
        frame_size = 96  # 2 days
        len_df = len(dataframe)
        data['returns'] = np.log(data['close'] / data['close'].shift())

        data['volumeGap'] = data['volume'] / data['volume'].shift()
        data['fractHigh'] = (data['high'] - data['open']) / data['open']
        data['fractLow'] = (data['open'] - data['low']) / data['open']
        data.dropna(inplace=True)
        data = data[~data.isin([np.nan, np.inf, -np.inf]).any(1)]

        endog = data['returns'].values
        exog = data[['volumeGap', 'fractHigh', 'fractLow']].values

        start_time = time.time()
        for i in range(len_df):
            if i + frame_size < len_df:
                print_frequency = 10
                if i and i % print_frequency == 0:
                    print('----------------------')
                    print(f'{i} steps of {len_df}')
                    curr_time = time.time()
                    time_passed = round((curr_time - start_time) / 60, 2)
                    approx_mins = round((time_passed / (i / print_frequency)) * len_df / print_frequency, 2)
                    print(f'Total time passed: {time_passed} min.')
                    print(f'Approx time to finish: {approx_mins} min.')
                    print('----------------------')
                # Fit the 3-regime model
                mod_2 = sm.tsa.Github_remiotore_freqtrade__Discord_Markov__20260111_210550Regression(endog=endog[i: i + frame_size], exog=exog[i: i + frame_size], k_regimes=2)
                res_2 = mod_2.fit(search_reps=50)
                # print(len(res_2.smoothed_marginal_probabilities))
                dataframe.at[i + frame_size, 'prob_down'] = res_2.smoothed_marginal_probabilities[0][-1]
                dataframe.at[i + frame_size, 'prob_side'] = res_2.smoothed_marginal_probabilities[1][-1]
                dataframe.at[i + frame_size, 'prob_up'] = res_2.smoothed_marginal_probabilities[2][-1]

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['prob_up'] > 0.8)
                &
                (dataframe['prob_side'] < 0.5)
                &
                (dataframe['prob_down'] < 0.5)

            ),
            'buy'] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['prob_up'] < 0.5)
                &
                (dataframe['prob_side'] < 0.5)
                &
                (dataframe['prob_down'] > 0.8)

            ),
            'sell'] = 1
        return dataframe

