# source: https://raw.githubusercontent.com/prakashrx/freqtrade/1347558ba781765a601ebe40ff77165f78b33694/user_data/strategies/ichimoku.py
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
import logging
import talib.abstract as ta
import pandas as pd
from pandas import DataFrame
import arrow
from pathlib import Path
import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.arguments import TimeRange
from freqtrade.indicator_helpers import fishers_inverse
from freqtrade.strategy.interface import IStrategy
from freqtrade.state import RunMode
from freqtrade.strategy.util import resample_to_interval, resampled_merge
from freqtrade.data.history import parse_ticker_dataframe, load_pair_history
import freqtrade.indicators as indicators

logger = logging.getLogger("github_prakashrx_freqtrade__ichimoku__20190519_071233Strategy")

class github_prakashrx_freqtrade__ichimoku__20190519_071233(IStrategy):

    cache = {}
    min_days = 30

    def get_extend_historical(self, pair: str, dataframe: DataFrame) -> DataFrame:

        if hasattr(self, 'dp'):
            if self.dp.runmode in (RunMode.LIVE, RunMode.DRY_RUN):
                min_date = dataframe['date'].min()
                if pair not in self.cache or self.cache[pair]["date"].max() < min_date:
                    logger.info(f"Downloading historical ohlc for pair: {pair})")
                    # hist = self.dp._exchange.get_history(pair=pair, ticker_interval=self.ticker_interval,
                    #                         since_ms=int(arrow.utcnow().shift(days=-60).float_timestamp) * 1000)
                    # self.cache[pair] = parse_ticker_dataframe(hist,self.ticker_interval)
                    self.cache[pair] = load_pair_history(pair, 
                                        ticker_interval=self.ticker_interval, 
                                        datadir= Path(f"user_data/data/history"),
                                        timerange=TimeRange(starttype ='date', startts=int(arrow.utcnow().shift(days=-60).float_timestamp)),
                                        refresh_pairs=True,
                                        exchange=self.dp._exchange)

                hist_df = self.cache[pair]
                min_date = dataframe['date'].min()
                return pd.concat([ hist_df[hist_df['date'] < min_date] , dataframe ])

        return dataframe

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        
        
        dataframe = self.get_extend_historical(metadata['pair'], dataframe)
        if (dataframe['date'].max() - dataframe['date'].min()).days < self.min_days:
            return dataframe

        #Default time interval
        #indicators - Hikenashi Macd
        macd = ta.MACD(dataframe, fastperiod=14, slowperiod=27, signalperiod=9)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        dataframe['macdhist'] = macd['macdhist']
        dataframe['sar'] = ta.SAR(dataframe)
        dataframe['rsi'] = ta.RSI(dataframe)

        #Daily interval
        #indicators - Macd
        dataframe_1d =  resample_to_interval(dataframe, '1d')
        macd = ta.MACD(dataframe_1d, fastperiod=14, slowperiod=27, signalperiod=15)
        dataframe_1d['macd_1d'] = macd['macd']
        dataframe_1d['macdsignal_1d'] = macd['macdsignal']
        dataframe_1d['macdhist_1d'] = macd['macdhist']
        dataframe_1d['sar_1d'] = ta.SAR(dataframe_1d, acceleration=0.15, maximum=1)
        dataframe_1d['close_1d'] = dataframe_1d['close']
        dataframe_1d['rsi_1d'] = ta.RSI(dataframe_1d)

        #4h interval
        #indicators - github_prakashrx_freqtrade__ichimoku__20190519_071233 cloud, Macd
        dataframe_4h =  resample_to_interval(dataframe, '4h')
        ichimoku = indicators.ichimoku(dataframe_4h, tenkan_sen_window=15, kijun_sen_window=27, senkou_span_offset=15, senkou_span_b_window=50)
        dataframe_4h['tenkan_sen_4h'] = ichimoku['tenkan_sen']
        dataframe_4h['kijun_sen_4h'] = ichimoku['kijun_sen']
        dataframe_4h['senkou_span_a_4h'] = ichimoku['senkou_span_a']
        dataframe_4h['senkou_span_b_4h'] = ichimoku['senkou_span_b']
        macd = ta.MACD(dataframe_4h, fastperiod=14, slowperiod=27, signalperiod=9)
        dataframe_4h['macd_4h'] = macd['macd']
        dataframe_4h['macdsignal_4h'] = macd['macdsignal']

        dataframe = resampled_merge(dataframe, dataframe_4h)
        dataframe = resampled_merge(dataframe, dataframe_1d)

        return dataframe

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

        if (dataframe['date'].max() - dataframe['date'].min()).days < self.min_days:
            dataframe['buy'] = 0
            return dataframe

        try:
            if self.dp:
                if self.dp.runmode in (RunMode.LIVE, RunMode.DRY_RUN):
                    ticker_data = self.dp._exchange.get_ticker(metadata['pair'])
                    symbol,bid,ask,last= ticker_data['symbol'],ticker_data['bid'],ticker_data['ask'],ticker_data['last']
                    
                    if(ask <=0 or bid <=0 or last <= 0):
                        dataframe['buy'] = 0
                        return dataframe

                    spread = ((ask - bid)/last) * 100
                    if(spread > 0.20):
                        dataframe['buy'] = 0
                        return dataframe
        except:
            #print(f"could not get ticker for pair: {metadata['pair']}")
            dataframe['buy'] = 0
            return dataframe

        dataframe.loc[
            (
                (
                    (dataframe['macd'] > dataframe['macdsignal']) &
                    (dataframe['macd'].shift() > dataframe['macdsignal'].shift()) &
                    (dataframe['macd_4h'] > dataframe['macdsignal_4h']) &
                    (dataframe['sar_1d'] < dataframe['open']) &
                    (dataframe['sar'] < dataframe['open']) &

                    (dataframe['macd_1d'] > dataframe['macdsignal_1d']) &
                    (dataframe['rsi'] < 75) &
                    (dataframe['open'] > dataframe['senkou_span_a_4h']) &
                    (dataframe['open'] > dataframe['senkou_span_b_4h']) &
                    (dataframe['close'] > dataframe['senkou_span_a_4h']) &
                    (dataframe['close'] > dataframe['senkou_span_b_4h'])
                )
            ),
            'buy'] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        
        if (dataframe['date'].max() - dataframe['date'].min()).days < self.min_days:
            dataframe['sell'] = 0
            return dataframe

        dataframe.loc[
            (
                #(dataframe['macd_1d'] < dataframe['macdsignal_1d'])
                 (dataframe['sar_1d'] > dataframe['open']) 
            ),
            'sell'] = 1
        return dataframe
