Overall Statistics
Total Trades
92
Average Win
8.42%
Average Loss
-5.50%
Compounding Annual Return
47.981%
Drawdown
22.400%
Expectancy
-0.367
Net Profit
3.816%
Sharpe Ratio
1.08
Probabilistic Sharpe Ratio
46.590%
Loss Rate
75%
Win Rate
25%
Profit-Loss Ratio
1.53
Alpha
2.326
Beta
-5.161
Annual Standard Deviation
0.885
Annual Variance
0.784
Information Ratio
0.734
Tracking Error
0.941
Treynor Ratio
-0.185
Total Fees
$0.00
Estimated Strategy Capacity
$3500000.00
Lowest Capacity Asset
EURNZD 8G
class HyperActiveApricotFalcon(QCAlgorithm):

    def Initialize(self):
        #General Information
        self.SetStartDate(2021, 6, 27)
        self.SetEndDate(2021, 7, 31)
        self.SetCash(100000) 
        self.pair = 'EURNZD'
        self.forex = self.AddForex(self.pair, Resolution.Minute, Market.Oanda).Symbol
        self.quantity = 100000
        
        # Set Take Profit and Stop Loss Here
        self.tp = 0.002
        self.sl = 0.0015
        
        # Long / Short - True = Live
        self.Long = True
        self.Short = False
        
        # Set number of open positions allowed at a time
        self.numtrades = 10
        
        ''' Takeprofit and stoploss not working '''
        self.takeprofit = []
        self.stoploss = []
        self.numshares = []
        self.takeprofitpos = {}
        self.stoplosspos = {}
        
        # Indicators
        self.rsi = RelativeStrengthIndex(14, MovingAverageType.Wilders)
        self.macdfiveminute = MovingAverageConvergenceDivergence(12, 26, 9, MovingAverageType.Exponential)
        self.macdonehour = MovingAverageConvergenceDivergence(12, 26, 9, MovingAverageType.Exponential)
        self.atr = AverageTrueRange(14, MovingAverageType.Wilders)
        self.emafast = ExponentialMovingAverage(9)
        self.emaslow = ExponentialMovingAverage(50)

        # One Hour Consolidator and Indicator Registrations
        oneHourConsolidator = QuoteBarConsolidator(timedelta(minutes=60))
        oneHourConsolidator.DataConsolidated += self.OneHourBarHandler
        self.SubscriptionManager.AddConsolidator(self.pair, oneHourConsolidator)
        self.RegisterIndicator(self.pair, self.macdonehour, oneHourConsolidator)
        
        # Five Minute Consolidator and Indicator Registrations
        fiveMinuteConsolidator = QuoteBarConsolidator(timedelta(minutes=5))
        fiveMinuteConsolidator.DataConsolidated += self.FiveMinuteBarHandler
        self.SubscriptionManager.AddConsolidator(self.pair, fiveMinuteConsolidator)
        self.RegisterIndicator(self.pair, self.rsi, fiveMinuteConsolidator)
        self.RegisterIndicator(self.pair, self.macdonehour, oneHourConsolidator)
        self.RegisterIndicator(self.pair, self.atr, fiveMinuteConsolidator)
        self.RegisterIndicator(self.pair, self.macdfiveminute, fiveMinuteConsolidator)#.Updated += self.FiveMinuteBarHandler
        self.RegisterIndicator(self.pair, self.emafast, fiveMinuteConsolidator)
        self.RegisterIndicator(self.pair, self.emaslow, fiveMinuteConsolidator)
        
        self.macdLastHourWindow = RollingWindow[float](2)
        
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.BeforeMarketClose(self.pair), self.WeekendLiquidation)
        
        self.fiveminbaropen = 0
        self.SetWarmUp(50)
        
        self.lastfiveminutemacdvalues = []
        self.lastonehourmacdvalues = []
        self.removekeys = []
        
        self.counter = 0
        self.tpsl = {}
        
        self.macdLastFiveBar = None

    def OneHourBarHandler(self, sender, consolidated):
        self.macdLastHourWindow.Add(self.macdonehour.Current.Value)
        
    def FiveMinuteBarHandler(self, sender, consolidated):
        if not self.macdonehour.IsReady:
            return
        
        if self.macdLastFiveBar == None or self.macdLastHourWindow.Count <= 1:
            self.macdLastFiveBar = self.macdfiveminute.Current.Value
            return
        
        Close = (consolidated.Bid.Close+consolidated.Ask.Close)/2
        Open = (consolidated.Bid.Open+consolidated.Ask.Open)/2
        Low = (consolidated.Bid.Low+consolidated.Ask.Low)/2
        High = (consolidated.Bid.High+consolidated.Ask.High)/2
        Price = consolidated.Price
            
        # Limit number of open trades
        if len(self.tpsl) >= self.numtrades:
            return
        
        emaFast = self.emafast.Current.Value
        emaSlow = self.emaslow.Current.Value
        rsiValue = self.rsi.Current.Value
        macdFive = self.macdfiveminute.Current.Value
        
        # Entry Long
        if self.Long and Close > emaFast and Open > emaFast and Close < Open and emaSlow < emaFast and rsiValue < 63 and rsiValue > 58:
            self.GoLong(Close)
                                            
        # Entry Short
        elif self.Short and Close < emaFast and Open < emaFast and Close > Open and emaSlow > emaFast and rsiValue > 38 and rsiValue < 45:
            self.GoShort(Close)

        # Record MACD values to compare at next datapoint
        self.macdLastFiveBar = self.macdfiveminute.Current.Value
        
        # Order Tickets
        self.entryTicket = None
        self.SLTicket = None
        self.TPTicket = None
        
    def GoLong(self, Close):
        FiveMACDdifference = self.macdfiveminute.Current.Value - self.macdfiveminute.Signal.Current.Value
        HourMACDdifference = self.macdonehour.Current.Value - self.macdonehour.Signal.Current.Value
        if self.entryTicket == None:
            if self.macdfiveminute.Current.Value > .00005:
                # MACD Current > MACD 1 Bar Ago ( 5 minute and 1 hour )
                if self.macdfiveminute.Current.Value > self.macdLastFiveBar and self.macdonehour.Current.Value > self.macdLastHourWindow[self.macdLastHourWindow.Count-1]:
                    # ATR > .00025
                    if self.atr.Current.Value > .00025:
                        # MACD Difference > 0 ( 5 minute and 1 hour )
                        if self.macdfiveminute.Current.Value - self.macdfiveminute.Signal.Current.Value > 0 and self.macdonehour.Current.Value - self.macdonehour.Signal.Current.Value > -.0001:
                            self.BuyPrice = Close
                            self.SLPrice = self.BuyPrice - .0015
                            self.TPPrice = self.BuyPrice + .002
                            self.entryTicket = self.LimitOrder(self.pair, self.quantity, self.BuyPrice)
                            self.Debug(f"MACD Value : {self.macdfiveminute.Current.Value}")
                            self.Debug(f"5 Minute MACD Difference : {FiveMACDdifference}")
                            self.Debug(f"1 Hour MACD Difference : {HourMACDdifference}")
                            self.Debug(f"1 Hour MACD Value : {self.macdonehour.Current.Value}")
                            self.Debug(f"1 Hour MACD Signal : {self.macdonehour.Signal.Current.Value}")
                        
    def GoShort(self, Close):
        if self.macdfiveminute.Current.Value < -.00005:
            # MACD Current > MACD 1 Bar Ago ( 5 minute and 1 hour )
            if self.macdfiveminute.Current.Value < self.macdLastFiveBar and self.macdonehour.Current.Value < self.macdLastHourWindow[self.macdLastHourWindow.Count-1]:
                # ATR > .00025
                if self.atr.Current.Value > .00025:
                    # MACD Difference < 0 ( 5 minute and 1 hour )
                    if self.macdfiveminute.Current.Value - self.macdfiveminute.Signal.Current.Value < 0 and self.macdonehour.Current.Value - self.macdonehour.Signal.Current.Value < 0:
                        self.counter += 1
                        self.MarketOrder(self.pair, -self.quantity, False, str(self.macdfiveminute.Current.Value) + " " + str(self.macdLastFiveBar))
                        tp = Close-self.tp
                        sl = Close+self.sl
                        self.tpsl[self.counter] = [tp, sl, False]
    
    def WeekendLiquidation(self):
        self.Liquidate()
        self.tpsl = {}
    
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status == OrderStatus.Filled:
            return
        
        if self.entryTicket != None and self.entryTicket.OrderId == orderevent.OrderId:
           # Enter stop loss order
           self.SLTicket = self.StopMarketOrder( self.pair, self.quantity, self.SLPrice)
           # Enter limit order 
           self.TPTicket = self.LimitOrder( self.pair, self.quantity, self.TPPrice)
        
        # Cancel Stop Loss Ticket if Take Profit Price is reached
        elif self.TPTicket != None and self.TPTicket.OrderId == orderevent.OrderId:
            self.SLTicket.cancel()
            
           # Cancel Take Profit Ticket if Stop Loss Price is reached
        elif self.SLTicket != None and self.SLTicket.OrderId == orderevent.OrderId:
            self.TPTicket.cancel()
            self.entryTicket = None