# source: https://raw.githubusercontent.com/DOUGLASGUEDESATRIA/OSIRIS_TRADE/fe3c09567f3798d1cad6d7a306fa4f6131d91e17/user_data/strategies/OsirisDailyV2.py
"""
OSIRIS DAILY V2 — Session-Based Intraday (DOW×Hour)
====================================================
7 statistically significant DOW×Hour signals (all t-stat ≥ 2.0).
FT-aligned: signal at hour X-1, trade at hour X, 1h hold.

SCHEDULE (all hours UTC):
  Mon: 07h Long    (t=3.33)
  Tue: 13h Short   (t=2.89)
  Wed: 21h Long    (t=2.14)
  Thu: 15h Short + 19h Short + 21h Long  (t=2.54, 3.85, 4.40)
  Fri: 07h Short   (t=2.32)

7 entries/week × 10 pairs = ~70 trades/week
Backtest: +104%, Sharpe 13.33, DD 11.5%, 827 days
"""

import logging
import numpy as np
from datetime import datetime
from pandas import DataFrame

from freqtrade.strategy import IStrategy

logger = logging.getLogger(__name__)


class Github_DOUGLASGUEDESATRIA_OSIRIS_TRADE__OsirisDailyV2__20260329_060843(IStrategy):
    INTERFACE_VERSION = 3
    timeframe = "1h"
    can_short = True

    minimal_roi = {"0": 100}
    stoploss = -0.05

    trailing_stop = False
    process_only_new_candles = True
    startup_candle_count: int = 25
    max_entry_position_adjustment = 0

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['hour'] = dataframe['date'].dt.hour
        dataframe['dow'] = dataframe['date'].dt.dayofweek  # 0=Mon
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Signal at hour X-1 → FT enters at open of hour X → exits after 1h.
        Only signals with t-stat ≥ 2.0 from exhaustive 5×24 DOW×Hour scan.

        LONGS:
          Mon 07h → signal at 06h, dow=0  (t=3.33)
          Wed 21h → signal at 20h, dow=2  (t=2.14)
          Thu 21h → signal at 20h, dow=3  (t=4.40)

        SHORTS:
          Tue 13h → signal at 12h, dow=1  (t=2.89)
          Thu 15h → signal at 14h, dow=3  (t=2.54)
          Thu 19h → signal at 18h, dow=3  (t=3.85)
          Fri 07h → signal at 06h, dow=4  (t=2.32)
        """
        long_mask = np.zeros(len(dataframe), dtype=bool)

        # Mon 07h Long → sig@06, dow=0
        long_mask |= ((dataframe['dow'] == 0) & (dataframe['hour'] == 6)).values
        # Wed 21h Long → sig@20, dow=2
        long_mask |= ((dataframe['dow'] == 2) & (dataframe['hour'] == 20)).values
        # Thu 21h Long → sig@20, dow=3
        long_mask |= ((dataframe['dow'] == 3) & (dataframe['hour'] == 20)).values

        dataframe.loc[long_mask, 'enter_long'] = 1

        short_mask = np.zeros(len(dataframe), dtype=bool)

        # Tue 13h Short → sig@12, dow=1
        short_mask |= ((dataframe['dow'] == 1) & (dataframe['hour'] == 12)).values
        # Thu 15h Short → sig@14, dow=3
        short_mask |= ((dataframe['dow'] == 3) & (dataframe['hour'] == 14)).values
        # Thu 19h Short → sig@18, dow=3
        short_mask |= ((dataframe['dow'] == 3) & (dataframe['hour'] == 18)).values
        # Fri 07h Short → sig@06, dow=4
        short_mask |= ((dataframe['dow'] == 4) & (dataframe['hour'] == 6)).values

        dataframe.loc[short_mask, 'enter_short'] = 1

        return dataframe

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

    def custom_exit(self, pair: str, trade, current_time: datetime,
                    current_rate: float, current_profit: float,
                    **kwargs) -> str | bool:
        trade_duration_hours = (current_time - trade.open_date_utc).total_seconds() / 3600
        if trade_duration_hours >= 1.0:
            return "1h_exit"
        return False
