# source: https://raw.githubusercontent.com/matthieu-hm/freqtrade_consumer_producer_strategies/c07a9fa2989651666d896ce8b42c5e681aac4d6a/ProducerConsumerStrategy.py
import copy
import logging
import pathlib
import rapidjson
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
import talib.abstract as ta
import pandas as pd
import pandas_ta as pta
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy import merge_informative_pair
from pandas import DataFrame, Series
from functools import reduce, partial
from freqtrade.persistence import Trade, LocalTrade
from datetime import datetime, timedelta
import time
from typing import Optional
import warnings

log = logging.getLogger(__name__)
# log.setLevel(logging.DEBUG)
warnings.simplefilter(action='ignore', category=pd.errors.PerformanceWarning)

class github_matthieu_hm_freqtrade_consumer_producer_strategies__ProducerConsumerStrategy__20230330_180743(IStrategy):
    INTERFACE_VERSION: int = 3


    #############################################################
    # Strategy parameters -->

    # ROI table:
    minimal_roi = {
        "0": 100.0,
    }

    stoploss = -0.99

    # Trailing stoploss (not used)
    trailing_stop = False
    trailing_only_offset_is_reached = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.03

    use_custom_stoploss = False

    timeframe = '5m'

    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = True

    # <-- Strategy parameters
    #############################################################


    #############################################################
    # Producers / Consumer
    is_consumer = False
    process_only_new_candles = True


    def __init__(self, config: dict) -> None:
        super().__init__(config)

        if ('external_message_consumer' in self.config and 'producers' in self.config['external_message_consumer']
                and len(self.config['external_message_consumer']['producers']) > 0):
            self.is_consumer = True
            self.process_only_new_candles = False  # required for consumers


    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        if self.is_consumer:
            producer_dataframe = self.populate_indicators_from_producers(dataframe, metadata)
            return producer_dataframe

        # ... (strategy logic)
        return dataframe


    def populate_indicators_from_producers(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        pair = metadata['pair']

        for producer in self.config['external_message_consumer']['producers']:
            if (producer.name):
                # This func returns the analyzed dataframe, and when it was analyzed
                producer_dataframe, _ = self.dp.get_producer_df(pair, producer_name=producer.name)

                if not producer_dataframe.empty:
                    log.debug(f"[{metadata['pair']}] Populate indicators from producer {producer['name']}")
                    return producer_dataframe

        # No dataframe provided by any producer: minimal dataframe fallback
        # FIXME: Define default value for all indicators
        #        -> When starting with active trade, stategie callbacks that use indicators
        #           are going to throw errors
        required_columns = ['enter_long', 'enter_short', 'exit_long', 'exit_short']
        dataframe[required_columns] = 0
        log.debug(f"[{metadata['pair']}] No indicators found from producers")
        return dataframe


    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        if self.is_consumer:
            # Dataframe from populate_indicators_from_producers
            # -> indicators already populated
            # TODO: Needs to be confirmed
            return dataframe

        # ... (strategy logic)
        return dataframe


    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        if self.is_consumer:
            # Dataframe from populate_indicators_from_producers
            # -> indicators already populated
            # TODO: Needs to be confirmed
            return dataframe

        # ... (strategy logic)
        return dataframe
