Overall Statistics
Total Trades
1021
Average Win
0.57%
Average Loss
-0.45%
Compounding Annual Return
-2.411%
Drawdown
18.400%
Expectancy
-0.050
Net Profit
-11.502%
Sharpe Ratio
-0.239
Probabilistic Sharpe Ratio
0.101%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
1.26
Alpha
-0.016
Beta
-0.008
Annual Standard Deviation
0.071
Annual Variance
0.005
Information Ratio
-0.776
Tracking Error
0.186
Treynor Ratio
2.139
Total Fees
$0.00
Estimated Strategy Capacity
$1200000.00
class DeterminedRedOrangeAnt(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2015, 12, 1)  # Set Start Date
        self.SetEndDate(2020, 12, 1)
        self.SetCash(100000)  # Set Strategy Cash
        #EURUSD", "USDJPY", "GBPUSD", "AUDUSD" "USDCAD",
        #"GBPJPY", "EURUSD", "AUDUSD", "EURJPY", "EURGBP"
        
        self.Data = {}

        for ticker in ["USDCAD","EURUSD"]:
            symbol = self.AddForex(ticker, Resolution.Hour, Market.FXCM).Symbol
            self.Data[symbol] = SymbolData(self, symbol)
            
        self.stopLossLevel = -0.05 # stop loss percentage 
        self.stopProfitLevel = 0.01# stop profit percentage
            
        self.SetWarmUp(25, Resolution.Hour)


    def OnData(self, data):
        
        if self.IsWarmingUp:
            return
        
        for symbol, symbolData in self.Data.items():
            if not (data.ContainsKey(symbol) and data[symbol] is not None and symbolData.IsReady):
                continue
            
            ADX = symbolData.adx.Current.Value
            RSI = symbolData.rsi.Current.Value
            current_price = data[symbol].Close
            
            
            # Condition to begin if ADX value is greater than 25    
            if (not ADX > 25):
                  return
            
            if self.Portfolio[symbol].Invested:
                
                if self.isLong:
                    condStopProfit = (current_price - self.buyInPrice)/self.buyInPrice > self.stopProfitLevel
                    condStopLoss = (current_price - self.buyInPrice)/self.buyInPrice < self.stopLossLevel
                    if condStopProfit:
                        self.Liquidate(symbol)
                        self.Log(f"{self.Time} Long Position Stop Profit at {current_price}")
                        
                    if condStopLoss:
                        self.Liquidate(symbol)
                        self.Log(f"{self.Time} Long Position Stop Loss at {current_price}")
                else:
                    condStopProfit = (self.sellInPrice - current_price)/self.sellInPrice > self.stopProfitLevel
                    condStopLoss = (self.sellInPrice - current_price)/self.sellInPrice < self.stopLossLevel
                    if condStopProfit:
                        self.Liquidate(symbol)
                        self.Log(f"{self.Time} Short Position Stop Profit at {current_price}")
                        
                    if condStopLoss:
                        self.Liquidate(symbol)
                        self.Log(f"{self.Time} Short Position Stop Loss at {current_price}")
            
            
            
            if not self.Portfolio[symbol].Invested:
                
                lbbclose = symbolData.closeWindow[20] # self.closeWindow[20]
                lbsclose = symbolData.closeWindow[10] # self.closeWindow[10]
                
                if RSI < 50 and current_price < lbbclose and current_price > lbsclose:
                    self.SetHoldings(symbol, 1)
                    # get buy-in price for trailing stop loss/profit
                    self.buyInPrice = current_price
                    # entered long position
                    self.isLong = True
                    self.Log(f"{self.Time} Entered Long Position at {current_price}")
                        
                if RSI > 50 and current_price > lbbclose and current_price < lbsclose:
                    self.SetHoldings(symbol, -1)
                    # get sell-in price for trailing stop loss/profit
                    self.sellInPrice = current_price
                    # entered short position
                    self.isLong = False
                    self.Log(f"{self.Time} Entered Short Position at {current_price}")
                        
                    
class SymbolData:
    def __init__(self, algorithm, symbol):
        self.adx = algorithm.ADX(symbol, 14, Resolution.Hour)
        self.rsi = algorithm.RSI(symbol, 14, Resolution.Hour)
        
        self.adxWindow = RollingWindow[IndicatorDataPoint](2)   #setting the Rolling Window for the fast SMA indicator, takes two values
        self.adx.Updated += self.AdxUpdated                    #Updating those two values
        
        self.rsiWindow = RollingWindow[IndicatorDataPoint](2)   #setting the Rolling Window for the slow SMA indicator, takes two values
        self.rsi.Updated += self.RsiUpdated                    #Updating those two values
        
        self.closeWindow = RollingWindow[float](21)
        
        # Add consolidator to track rolling close prices
        self.consolidator = QuoteBarConsolidator(1)
        self.consolidator.DataConsolidated += self.CloseUpdated
        algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
        

    def AdxUpdated(self, sender, updated):
        '''Event holder to update the fast SMA Rolling Window values'''
        if self.adx.IsReady:
            self.adxWindow.Add(updated)

    def RsiUpdated(self, sender, updated):
        '''Event holder to update the slow SMA Rolling Window values'''
        if self.rsi.IsReady:
            self.rsiWindow.Add(updated)
            
            
    def CloseUpdated(self, sender, bar):
        '''Event holder to update the close Rolling Window values'''
        self.closeWindow.Add(bar.Close)
       
    @property 
    def IsReady(self):
        return self.adx.IsReady and self.rsi.IsReady and self.closeWindow.IsReady