# source: https://raw.githubusercontent.com/rmallarapu-bc/brahma/9287745fc036c2f4c00c586e598290885c2883b9/strategies/orig/Common.py
from pandas import DataFrame
from freqtrade.strategy import (DecimalParameter, IStrategy, IntParameter)
from datetime import datetime, timedelta  # noqa
from typing import Optional, Union  # noqa
from freqtrade.persistence import Trade
import logging

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class Github_rmallarapu_bc_brahma__Common__20240229_213751(IStrategy):
    INTERFACE_VERSION: int = 3

    can_short = False
    # ROI table:
    minimal_roi = {"0": 0.1}

    # Stoploss:
    stoploss = -0.7

    # Trailing stop:
    trailing_stop = True
    trailing_stop_positive = 0.001
    trailing_stop_positive_offset = 0.01
    trailing_only_offset_is_reached = False

    timeframe = "1h"

    process_only_new_candles = False
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    protect_optimize = True
    cooldown_lookback = IntParameter(1, 240, default=5, space="protection", optimize=protect_optimize)
    max_drawdown_lookback = IntParameter(1, 288, default=12, space="protection", optimize=protect_optimize)
    max_drawdown_trade_limit = IntParameter(1, 20, default=5, space="protection", optimize=protect_optimize)
    max_drawdown_stop_duration = IntParameter(1, 288, default=12, space="protection", optimize=protect_optimize)
    max_allowed_drawdown = DecimalParameter(0.10, 0.50, default=0.20, decimals=2, space="protection",
                                            optimize=protect_optimize)
    stoploss_guard_lookback = IntParameter(1, 288, default=12, space="protection", optimize=protect_optimize)
    stoploss_guard_trade_limit = IntParameter(1, 20, default=3, space="protection", optimize=protect_optimize)
    stoploss_guard_stop_duration = IntParameter(1, 288, default=12, space="protection", optimize=protect_optimize)

    leverage_optimize = False
    leverage_num = IntParameter(low=1, high=1, default=1, space='buy', optimize=leverage_optimize)

    # Optional order type mapping.
    order_types = {
        'entry': 'limit',
        'exit': 'limit',
        'stoploss': 'limit',
        'stoploss_on_exchange': False
    }

    # Optional order time in force.
    order_time_in_force = {
        'entry': 'gtc',
        'exit': 'gtc'
    }

    @property
    def protections(self):
        return [
            {
                "method": "CooldownPeriod",
                "stop_duration_candles": 1
            },
        ]

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        return dataframe

    def leverage(self, pair: str, current_time: datetime, current_rate: float,
                 proposed_leverage: float, max_leverage: float, entry_tag: Optional[str],
                 side: str, **kwargs) -> float:
        return self.leverage_num.value

    position_adjustment_enable = True
    max_entry_position_adjustment = 2
    initial_stake = 0.5
    dca_trigger = -0.2

    def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
                            proposed_stake: float, min_stake: Optional[float], max_stake: float,
                            leverage: float, entry_tag: Optional[str], side: str,
                            **kwargs) -> float:
        return proposed_stake * self.initial_stake

    def adjust_trade_position(self, trade: Trade, current_time: datetime,
                              current_rate: float, current_profit: float,
                              min_stake: Optional[float], max_stake: float,
                              current_entry_rate: float, current_exit_rate: float,
                              current_entry_profit: float, current_exit_profit: float,
                              **kwargs) -> Optional[float]:

        count_of_entries = trade.nr_of_successful_entries

        if current_profit < self.dca_trigger and count_of_entries == 1: # auto DCA only once
            dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
            filled_entries = trade.select_filled_orders(trade.entry_side)
            stake_amount = filled_entries[0].stake_amount
            dca = stake_amount

            try:
                log.info(f"DCA: pair = {trade.pair}, "
                         f"current_time = {current_time}, "
                         f"current_rate = {current_rate}, "
                         f"current_profit = {current_profit}, "
                         f"self.dca_trigger = {self.dca_trigger}, "
                         f"self.dca_trigger / 2 = {abs(self.dca_trigger / 2.0)}, "
                         f"stake = {stake_amount}, "
                         f"new_stake = {dca}, "
                         f"self.max_entry_position_adjustment = {self.max_entry_position_adjustment}, "
                         f"count_of_entries = {count_of_entries}"
                         )
                return dca
            except Exception as e:
                return None
        else:
            return None
