# source: https://raw.githubusercontent.com/remiotore/freqtrade/44beaeb6a420cd8e9f2e4ea93e11d6cfa192ee03/strategies/Discord_DCA.py
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from typing import Dict, List
from functools import reduce
from pandas import DataFrame
# --------------------------------

import talib.abstract as ta
import numpy as np
import freqtrade.vendor.qtpylib.indicators as qtpylib
import datetime
from technical.util import resample_to_interval, resampled_merge
from datetime import datetime, timedelta
from freqtrade.persistence import Trade
from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter
import technical.indicators as ftt
from freqtrade.exchange import timeframe_to_prev_date
import warnings
from pandas.core.common import SettingWithCopyWarning
from freqtrade.optimize.space import SKDecimal
warnings.simplefilter(action="ignore", category=SettingWithCopyWarning)


class Github_remiotore_freqtrade__Discord_DCA__20260111_210550(IStrategy):

    # Nested Hyperopt stoploss
    class HyperOpt:
        # Define a custom stoploss space.
        def stoploss_space():
            return [SKDecimal(-0.99, -0.15, decimals=2, name='stoploss')]

    INTERFACE_VERSION = 2

    DATESTAMP = 0
    Github_remiotore_freqtrade__Discord_DCA__20260111_210550_ENABLE = 1
    
    # ROI table:
    minimal_roi = {
        "0": 1000
    }

    # Stoploss:
    stoploss = -0.33

    # Trailing stop:
    trailing_stop = False
    # trailing_stop_positive = 0.001
    # trailing_stop_positive_offset = 0.01
    # trailing_only_offset_is_reached = True

    # Sell signal
    use_sell_signal = True
    sell_profit_only = False
    sell_profit_offset = 0.01
    ignore_roi_if_buy_signal = False
    
    # Optimal timeframe for the strategy
    # timeframe = '5m'
    timeframe = '4h'
    process_only_new_candles = True
    startup_candle_count = 60

    plot_config = {

    }

    # Github_remiotore_freqtrade__Discord_DCA__20260111_210550 config
    position_adjustment_enable = True 
    max_dca_orders = 2  # n - 1
    max_dca_multiplier = 7 # (2^n - 1)
    dca_trigger = 0

    # storage dict for custom info
    custom_info = { }

    # Hyperoptable parameters
    # This is where I enter my parameters for HO

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

        #This is where I enter my indicators from TALIB

        # Check if the entry already exists
        pair = metadata['pair']
        if not pair in self.custom_info:
            # Create empty entry for this pair {DATESTAMP, Github_remiotore_freqtrade__Discord_DCA__20260111_210550_ENABLE}
            self.custom_info[pair] = ['', 0] 
        
        return dataframe


    def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float,
                           rate: float, time_in_force: str, sell_reason: str, **kwargs) -> bool:
        self.custom_info[pair][self.Github_remiotore_freqtrade__Discord_DCA__20260111_210550_ENABLE] = 0
        return True

    
    def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
                            proposed_stake: float, min_stake: float, max_stake: float,
                            **kwargs) -> float:
        return proposed_stake / self.max_dca_multiplier
  

    def adjust_trade_position(self, trade: Trade, current_time: datetime,
                              current_rate: float, current_profit: float, min_stake: float,
                              max_stake: float, **kwargs):
        dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
        if(len(dataframe) < 1):
            return None
        last_candle = dataframe.iloc[-1].squeeze()

        if(self.custom_info[trade.pair][self.DATESTAMP] != last_candle['date']):
            # new candle, trigger only once per new candle
            self.custom_info[trade.pair][self.DATESTAMP] = last_candle['date']

            if(last_candle['buy_1'] == 1):
                dca_enable = self.custom_info[trade.pair][self.Github_remiotore_freqtrade__Discord_DCA__20260111_210550_ENABLE]
                self.custom_info[trade.pair][self.Github_remiotore_freqtrade__Discord_DCA__20260111_210550_ENABLE] = 1
            
                if(dca_enable):
                    filled_buys = trade.select_filled_orders('buy')
                    count_of_buys = len(filled_buys)
                    if 0 < count_of_buys <= self.max_dca_orders:
                        try:
                            # This returns first order stake size
                            stake_amount = filled_buys[0].cost
                            # This then calculates current safety order size
                            stake_amount = stake_amount * pow(0.9, count_of_buys)
                            # print("--------------------------------") 
                            # print(trade.open_date_utc)
                            # print("--------------------------------")
                            # print("count_of_buys = " + str(count_of_buys))
                            # print("stake_amount = " + str(stake_amount))
                            return stake_amount
                        except Exception as exception:
                            print("exception")
                            return None
                    return None
        return None
    

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['buy_1'] = 0
        dataframe.loc[
            (
                # These are my buy signals
            ),
                ['buy','buy_1']
            ]=(1, 1)
        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                # These are my sell signals
            ),
                'sell'
            ]=1
        return dataframe
