<reponame>yamf0/TradingBot<gh_stars>1-10
# @package "name of the strategy"
# "name of the strategy" "description of the strategy"
# @author "Author of the strategy"

from enum import Flag

from numpy.lib.twodim_base import triu
from tradingBot.src.mktStrategy.mktStrategyINF import mktStrategyINF
from tradingBot.src.mktStrategy.exitStrategies import *
import json
import pandas as pd
import sys
import numpy as np
sys.path.insert(0, r'')


class cross(mktStrategyINF):
    
    def __init__(self, strategy=None, exitStrat=None, dataAnalysisObj=None, coinBotObj=None, pctTP=None, pctSL=None):
        
        self.indicators = [
            {"indicator": "EMA", "period": 3, "interval": [1, 'h']},
            {"indicator": "EMA", "period": 6, "interval": [1, 'h']},
            {"indicator": "EMA", "period": 50, "interval": [1, 'h']}
            ]
        self.interval = [1, 'h']
        
        self.tradeOpen = False
        self.openTradeInfo = {}
        self.mktAnal = dataAnalysisObj
        self.coinBotObj = coinBotObj
        self.strategy = strategy
        self.indicators, self.interval = self.chgIndParam(self.indicators,
                                                          self.interval, self.strategy)
        self.indicIDs = self.crtIndic(self.indicators)
        
        self.enterLong = False
        self.enterShort = False
        
        # Exit Strategy is created
        module = globals()[exitStrat]
        self.exitStrat = getattr(module, exitStrat)(strategy=self, pctTP=pctTP, pctSL=pctSL)

    def analData(self, pos=-1):
        # @fn analData
        # @brief Abstract method that analizes the candles and indicators.
        # @return side Value indicating if strategy is in a "Long" or "Short".
        # @return flag Value returning True or False, depending on strategy analysis.

        data = self.actlData()
        print(self.interval)
        print(data["candles"].iloc[pos]["close"])
        ### Enter Code for comparing candles and indicators here ###
        #pos = pos - 2
        ema3 = data["indic_0"].iloc[pos]
        ema3_1 = data["indic_0"].iloc[(pos - 1)]
        ema3_2 = data["indic_0"].iloc[(pos - 2)]
        ema6 = data["indic_1"].iloc[pos]
        ema6_1 = data["indic_1"].iloc[pos - 1]
        ema50 = data["indic_2"].iloc[pos]
        ema50_1 = data["indic_2"].iloc[pos - 1]
        ema50_2 = data["indic_2"].iloc[pos - 2]
        
        print("EMA 3 tmstp {} val {}".format(ema3["timestamp"], ema3["value"]))
        print("EMA 6 tmstp {} val {}".format(ema6["timestamp"], ema6["value"]))
        print("EMA 50 tmstp {} val {}".format(ema50["timestamp"], ema50["value"]))
        print("EMA 3_1 tmstp {} val {}".format(ema3_1["timestamp"], ema3_1["value"]))
        print("EMA 6_1 tmstp {} val {}".format(ema6_1["timestamp"], ema6_1["value"]))
        print("EMA 50_1 tmstp {} val {}".format(ema50_1["timestamp"], ema50_1["value"]))
        print("EMA 3_2 tmstp {} val {}".format(ema3_2["timestamp"], ema3_2["value"]))
        print("EMA 50_2 tmstp {} val {}".format(ema50_2["timestamp"], ema50_2["value"]))
        
        em3_50_over = False
        em3_50_under = False
        em6_50_over = False 
        em6_50_under = False

        if (ema3.value * 1.002) > ema50.value and ((ema3_1.value * 0.998) < ema50_1.value or (ema3_2.value * 0.998) < ema50_2.value): 
            em3_50_over = True
        elif (ema3.value * 0.998) < ema50.value and ((ema3_1.value * 1.002) > ema50_1.value or (ema3_2.value * 1.002) > ema50_2.value):
            em3_50_under = True
        
        if (ema6.value * 1.002) > ema50.value and (ema6_1.value * 0.998) < ema50_1.value: 
            em6_50_over = True
        elif (ema6.value * 0.998) < ema50.value and (ema6_1.value * 1.002) > ema50_1.value:
            em6_50_under = True

        if em3_50_over == True and em6_50_over == True:
            self.enterLong = True
        elif em3_50_under == True and em6_50_under == True:
            self.enterShort = True
        else:
            self.enterLong = False
            self.enterShort = False
        ############################################################
    
    def enterTradeAnal(self, pos=-1):
        data = self.actlData()
        
        if self.enterLong:
            side = "Long"
            flag = True
        elif self.enterShort:
            side = "Short"
            flag = True
        else:
            side = "null"
            flag = False
 
        if flag:
            self.openTradeInfo = {
                "entryTimestamp": data["candles"].iloc[pos].timestamp,
                "entryPrice": data["candles"].iloc[pos].close,
                "typeOfTrade": side,
                "newPrice": data["candles"].iloc[pos].close,        
                "signalTimestamp": self.coinBotObj.tmstp               
            }
            self.tradeOpen = True
        
        return side, flag

    def setFlag(self, pos=-1):
        # @fn setFlag
        # @brief Abstract method that returns a flag depending on the strategy conditions.
        # @return side Value indicating if strategy is in a "Long" or "Short".
        # @return flag Value returning True or False, depending on strategy analysis.
        self.analData(pos=pos)

        if not self.tradeOpen:
            #No trade is currently open
            side, flag = self.enterTradeAnal(pos=pos)
        else:
            side, flag = self.exitStrat.exitTradeAnal(pos=pos, 
                data=self.actlData(), openTradeInfo=self.openTradeInfo, enterShort=self.enterShort, 
                enterLong=self.enterLong)
            if flag and self.enterLong == self.enterShort:
                self.tradeOpen = False
        return side, flag

    def actlData(self):
        # @fn actlData
        # @brief Return the data from each indicator.
        # @return data Returns in a dictionary the candles and indicators data in a pandas dataframe format.

        data = {}
        candles = getattr(self.coinBotObj, self.interval)
        data["candles"] = pd.DataFrame.from_dict(candles, orient='columns').drop(columns=['_id'])
        for val in ["open", "close", "high", "low", "volume"]:
            data["candles"][val] = pd.to_numeric(data["candles"][val])
        indicIntevalsData = []
        for interval in self.indiIntvls:
            indicIntevalsData.append(getattr(self.mktAnal, "indic_" + interval))
        for indicInterval in indicIntevalsData:
            for indicator in indicInterval["indicators"]:
                if indicator['id'] in self.indicIDs:
                    i = self.indicIDs.index(indicator['id'])
                    data['indic_{}'.format(i)] = pd.DataFrame.from_dict(indicator["data"], orient='columns')
        return data

    def chgIndParam(self, indicators, interval, strategy):
        # @fn analData
        # @brief Abstract method that checks if there were changes in the default indicators and changes them acordingly.
        # @param indicators The default indicators list of the strategy.
        # @param interval The default interval of the strategy.
        # @param strategy Array containing the new strategy indicator parameters. If there are no changes, it willbe Null
        # @return indicators Returns default indicators if strategy=Null. Else, returns indicators with the new parameters
        # @return interval Returns default interval if strategy=Null. Else, returns new interval.

        self.indiIntvls = []
        if not strategy == None:
            interval = self.mktAnal._getIntvl(strategy["mainInterval"])
            for i in range(0, len(indicators)):
                indicators[i]["period"] = strategy["period"][i]
                indicators[i]["interval"] = strategy["interval"][i]
        else:
            interval = self.mktAnal._getIntvl(interval)
        for i in range(0, len(indicators)):
            intv = self.mktAnal._getIntvl(indicators[i]["interval"])
            if intv not in self.indiIntvls:
                self.indiIntvls.append(intv)
        return indicators, interval

    def crtIndic(self, indicators):
        # @fn analData
        # @brief Abstract method that creates the indicators using the mktAnal object.
        # @param indicators The default or actualized indicators list of the strategy.
        # @return indicIDs Array with the IDs of all indicators created. (e.g., ["35BB1d", "45ATR1d"])

        indicIDs = []
        for indic in indicators:
            interval = self.mktAnal._getIntvl(indic["interval"])
            self.mktAnal.newIndicator(indicator=indic["indicator"],
                                      period=indic["period"], interval=indic["interval"])
            indicIDs.append(str(indic["period"]) +
                            indic["indicator"] + interval)
        return indicIDs

# @package "name of the strategy"
# "name of the strategy" "description of the strategy"
# @author "Author of the strategy"

from enum import Flag

from numpy.lib.twodim_base import triu
from tradingBot.src.mktStrategy.mktStrategyINF import mktStrategyINF
from tradingBot.src.mktStrategy.exitStrategies import *
import json
import pandas as pd
import sys
import numpy as np
sys.path.insert(0, r'')


class cross(mktStrategyINF):
    
    def __init__(self, strategy=None, exitStrat=None, dataAnalysisObj=None, coinBotObj=None, pctTP=None, pctSL=None):
        
        self.indicators = [
            {"indicator": "EMA", "period": 3, "interval": [1, 'h']},
            {"indicator": "EMA", "period": 6, "interval": [1, 'h']},
            {"indicator": "EMA", "period": 50, "interval": [1, 'h']}
            ]
        self.interval = [1, 'h']
        
        self.tradeOpen = False
        self.openTradeInfo = {}
        self.mktAnal = dataAnalysisObj
        self.coinBotObj = coinBotObj
        self.strategy = strategy
        self.indicators, self.interval = self.chgIndParam(self.indicators,
                                                          self.interval, self.strategy)
        self.indicIDs = self.crtIndic(self.indicators)
        
        self.enterLong = False
        self.enterShort = False
        
        # Exit Strategy is created
        module = globals()[exitStrat]
        self.exitStrat = getattr(module, exitStrat)(strategy=self, pctTP=pctTP, pctSL=pctSL)

    def analData(self, pos=-1):
        # @fn analData
        # @brief Abstract method that analizes the candles and indicators.
        # @return side Value indicating if strategy is in a "Long" or "Short".
        # @return flag Value returning True or False, depending on strategy analysis.

        data = self.actlData()
        print(self.interval)
        print(data["candles"].iloc[pos]["close"])
        ### Enter Code for comparing candles and indicators here ###
        #pos = pos - 2
        ema3 = data["indic_0"].iloc[pos]
        ema3_1 = data["indic_0"].iloc[(pos - 1)]
        ema3_2 = data["indic_0"].iloc[(pos - 2)]
        ema6 = data["indic_1"].iloc[pos]
        ema6_1 = data["indic_1"].iloc[pos - 1]
        ema50 = data["indic_2"].iloc[pos]
        ema50_1 = data["indic_2"].iloc[pos - 1]
        ema50_2 = data["indic_2"].iloc[pos - 2]
        
        print("EMA 3 tmstp {} val {}".format(ema3["timestamp"], ema3["value"]))
        print("EMA 6 tmstp {} val {}".format(ema6["timestamp"], ema6["value"]))
        print("EMA 50 tmstp {} val {}".format(ema50["timestamp"], ema50["value"]))
        print("EMA 3_1 tmstp {} val {}".format(ema3_1["timestamp"], ema3_1["value"]))
        print("EMA 6_1 tmstp {} val {}".format(ema6_1["timestamp"], ema6_1["value"]))
        print("EMA 50_1 tmstp {} val {}".format(ema50_1["timestamp"], ema50_1["value"]))
        print("EMA 3_2 tmstp {} val {}".format(ema3_2["timestamp"], ema3_2["value"]))
        print("EMA 50_2 tmstp {} val {}".format(ema50_2["timestamp"], ema50_2["value"]))
        
        em3_50_over = False
        em3_50_under = False
        em6_50_over = False 
        em6_50_under = False

        if (ema3.value * 1.002) > ema50.value and ((ema3_1.value * 0.998) < ema50_1.value or (ema3_2.value * 0.998) < ema50_2.value): 
            em3_50_over = True
        elif (ema3.value * 0.998) < ema50.value and ((ema3_1.value * 1.002) > ema50_1.value or (ema3_2.value * 1.002) > ema50_2.value):
            em3_50_under = True
        
        if (ema6.value * 1.002) > ema50.value and (ema6_1.value * 0.998) < ema50_1.value: 
            em6_50_over = True
        elif (ema6.value * 0.998) < ema50.value and (ema6_1.value * 1.002) > ema50_1.value:
            em6_50_under = True

        if em3_50_over == True and em6_50_over == True:
            self.enterLong = True
        elif em3_50_under == True and em6_50_under == True:
            self.enterShort = True
        else:
            self.enterLong = False
            self.enterShort = False
        ############################################################
    
    def enterTradeAnal(self, pos=-1):
        data = self.actlData()
        
        if self.enterLong:
            side = "Long"
            flag = True
        elif self.enterShort:
            side = "Short"
            flag = True
        else:
            side = "null"
            flag = False
 
        if flag:
            self.openTradeInfo = {
                "entryTimestamp": data["candles"].iloc[pos].timestamp,
                "entryPrice": data["candles"].iloc[pos].close,
                "typeOfTrade": side,
                "newPrice": data["candles"].iloc[pos].close,        
                "signalTimestamp": self.coinBotObj.tmstp               
            }
            self.tradeOpen = True
        
        return side, flag

    def setFlag(self, pos=-1):
        # @fn setFlag
        # @brief Abstract method that returns a flag depending on the strategy conditions.
        # @return side Value indicating if strategy is in a "Long" or "Short".
        # @return flag Value returning True or False, depending on strategy analysis.
        self.analData(pos=pos)

        if not self.tradeOpen:
            #No trade is currently open
            side, flag = self.enterTradeAnal(pos=pos)
        else:
            side, flag = self.exitStrat.exitTradeAnal(pos=pos, 
                data=self.actlData(), openTradeInfo=self.openTradeInfo, enterShort=self.enterShort, 
                enterLong=self.enterLong)
            if flag and self.enterLong == self.enterShort:
                self.tradeOpen = False
        return side, flag

    def actlData(self):
        # @fn actlData
        # @brief Return the data from each indicator.
        # @return data Returns in a dictionary the candles and indicators data in a pandas dataframe format.

        data = {}
        candles = getattr(self.coinBotObj, self.interval)
        data["candles"] = pd.DataFrame.from_dict(candles, orient='columns').drop(columns=['_id'])
        for val in ["open", "close", "high", "low", "volume"]:
            data["candles"][val] = pd.to_numeric(data["candles"][val])
        indicIntevalsData = []
        for interval in self.indiIntvls:
            indicIntevalsData.append(getattr(self.mktAnal, "indic_" + interval))
        for indicInterval in indicIntevalsData:
            for indicator in indicInterval["indicators"]:
                if indicator['id'] in self.indicIDs:
                    i = self.indicIDs.index(indicator['id'])
                    data['indic_{}'.format(i)] = pd.DataFrame.from_dict(indicator["data"], orient='columns')
        return data

    def chgIndParam(self, indicators, interval, strategy):
        # @fn analData
        # @brief Abstract method that checks if there were changes in the default indicators and changes them acordingly.
        # @param indicators The default indicators list of the strategy.
        # @param interval The default interval of the strategy.
        # @param strategy Array containing the new strategy indicator parameters. If there are no changes, it willbe Null
        # @return indicators Returns default indicators if strategy=Null. Else, returns indicators with the new parameters
        # @return interval Returns default interval if strategy=Null. Else, returns new interval.

        self.indiIntvls = []
        if not strategy == None:
            interval = self.mktAnal._getIntvl(strategy["mainInterval"])
            for i in range(0, len(indicators)):
                indicators[i]["period"] = strategy["period"][i]
                indicators[i]["interval"] = strategy["interval"][i]
        else:
            interval = self.mktAnal._getIntvl(interval)
        for i in range(0, len(indicators)):
            intv = self.mktAnal._getIntvl(indicators[i]["interval"])
            if intv not in self.indiIntvls:
                self.indiIntvls.append(intv)
        return indicators, interval

    def crtIndic(self, indicators):
        # @fn analData
        # @brief Abstract method that creates the indicators using the mktAnal object.
        # @param indicators The default or actualized indicators list of the strategy.
        # @return indicIDs Array with the IDs of all indicators created. (e.g., ["35BB1d", "45ATR1d"])

        indicIDs = []
        for indic in indicators:
            interval = self.mktAnal._getIntvl(indic["interval"])
            self.mktAnal.newIndicator(indicator=indic["indicator"],
                                      period=indic["period"], interval=indic["interval"])
            indicIDs.append(str(indic["period"]) +
                            indic["indicator"] + interval)
        return indicIDs
# @package "name of the strategy" # "name of the strategy" "description of the strategy" # @author "Author of the strategy" # Exit Strategy is created # @fn analData # @brief Abstract method that analizes the candles and indicators. # @return side Value indicating if strategy is in a "Long" or "Short". # @return flag Value returning True or False, depending on strategy analysis. ### Enter Code for comparing candles and indicators here ### #pos = pos - 2 ############################################################ # @fn setFlag # @brief Abstract method that returns a flag depending on the strategy conditions. # @return side Value indicating if strategy is in a "Long" or "Short". # @return flag Value returning True or False, depending on strategy analysis. #No trade is currently open # @fn actlData # @brief Return the data from each indicator. # @return data Returns in a dictionary the candles and indicators data in a pandas dataframe format. # @fn analData # @brief Abstract method that checks if there were changes in the default indicators and changes them acordingly. # @param indicators The default indicators list of the strategy. # @param interval The default interval of the strategy. # @param strategy Array containing the new strategy indicator parameters. If there are no changes, it willbe Null # @return indicators Returns default indicators if strategy=Null. Else, returns indicators with the new parameters # @return interval Returns default interval if strategy=Null. Else, returns new interval. # @fn analData # @brief Abstract method that creates the indicators using the mktAnal object. # @param indicators The default or actualized indicators list of the strategy. # @return indicIDs Array with the IDs of all indicators created. (e.g., ["35BB1d", "45ATR1d"])