# source: https://raw.githubusercontent.com/jskroby/auro/17a4fc5ad71a65aeaf6ed2ac1751f8f1ee70030c/freqtrade/user_data/strategies/Aurox.py
# --- Do not remove these libs ---
from freqtrade.strategy import IStrategy
from typing import Dict, List
from functools import reduce
from pandas import DataFrame
import pandas as pd
# --------------------------------

import logging
import requests
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib

import pymongo

mongo_db = pymongo.MongoClient('mongo', username='changeme', password='changeme1?',
                               port=27017)

logger = logging.getLogger(__name__)

class Github_jskroby_auro__Aurox__20240922_214514(IStrategy):
    """
        buy:
            Github_jskroby_auro__Aurox__20240922_214514 Signals Long on Specified Time-Frame
        sell:
            Github_jskroby_auro__Aurox__20240922_214514 Signals Short on Specified Time-Frame
    """

    # Minimal ROI designed for the strategy.
    # This attribute will be overridden if the config file contains "minimal_roi"
    # 1.0 = 100% ROI
    minimal_roi = {
        "0": 10.0
    }

    # Optimal stoploss designed for the strategy
    # This attribute will be overridden if the config file contains "stoploss"
    # -0.1 = -10% stoploss
    stoploss = -0.1

    # timeframe for the strategy
    timeframe = '15m'

    # timeframe for the Github_jskroby_auro__Aurox__20240922_214514 indicator
    aurox_timeframe = '1d'

    # Logic needed to query the correct timeframe from the MongoDB
    if aurox_timeframe == '30m':
        timeUnit = '30_minute'
    elif aurox_timeframe == '1h':
        timeUnit = '1_hour'
    elif aurox_timeframe == '4h':
        timeUnit = '4_hour'
    elif aurox_timeframe == '12h':
        timeUnit = '12_hour'
    elif aurox_timeframe == '1d':
        timeUnit = '1_day'
    elif aurox_timeframe == '1w':
        timeUnit = '1_week'
    else:
        timeUnit = '1_month'

    # Define dictionary that stores the Github_jskroby_auro__Aurox__20240922_214514 signal
    custom_info = {}

    def bot_loop_start(self, **kwargs) -> None:
        """
        Called at the start of the bot iteration (one loop).
        Might be used to perform pair-independent tasks
        (e.g. gather some remote resource for comparison)
        :param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
        """

        if self.config['runmode'].value in ('live', 'dry_run'):
            self.mydb = mongo_db["indicators"]
            self.mycol = self.mydb["aurox"]

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Called every loop of the bot after bot_loop_start.
        Calculates the TA indicators given the OHLCV data
        """

        # Check if the entry already exists
        if not metadata["pair"] in self.custom_info:
            # Create empty entry for this pair
            self.custom_info[metadata["pair"]] = {}

        if self.dp:
            if self.dp.runmode.value in ('live', 'dry_run'):

                try:
                    # Get Github_jskroby_auro__Aurox__20240922_214514 data for specified timeframe
                    row_data = self.mycol.find_one({"pairDisplay": metadata['pair'], "timeUnit": self.timeUnit}, sort=[( '_id', pymongo.DESCENDING)])
                    self.custom_info[metadata['pair']][self.aurox_timeframe] = row_data['signal']
                    logger.info(metadata['pair'])
                    logger.info(self.custom_info[metadata['pair']][self.aurox_timeframe])
                except:
                    logger.info(metadata['pair'])
                    logger.info("Failed to grab Github_jskroby_auro__Aurox__20240922_214514 Signal from MongoDB")

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on the Github_jskroby_auro__Aurox__20240922_214514 indicator, populates the buy signal for the dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        dataframe.loc[
            (
                (self.custom_info[metadata['pair']][self.aurox_timeframe] == 'long') &
                (dataframe['volume'] > 0) # Extra check as you don't want to trade if there is 0 volume
            ),
            'buy'] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on the Github_jskroby_auro__Aurox__20240922_214514 indicator, populates the sell signal for the dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        dataframe.loc[
            (
                (self.custom_info[metadata['pair']][self.aurox_timeframe] == 'short') & 
                (dataframe['volume'] > 0) # Extra check as you don't want to trade if there is 0 volume
            ),
            'sell'] = 1

        return dataframe
