Overall Statistics
Total Trades
7
Average Win
28.13%
Average Loss
-0.15%
Compounding Annual Return
27.876%
Drawdown
39.100%
Expectancy
122.720
Net Profit
63.522%
Sharpe Ratio
0.896
Probabilistic Sharpe Ratio
35.985%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
184.58
Alpha
0.281
Beta
0.009
Annual Standard Deviation
0.315
Annual Variance
0.099
Information Ratio
0.513
Tracking Error
0.342
Treynor Ratio
29.79
Total Fees
$64.59
class CalmFluorescentPinkChicken(QCAlgorithm):

    def Initialize(self):
        # backtest 
        self.SetStartDate(2018, 1, 1)  
        self.SetEndDate(2020,1,1) 
        self.SetCash(100000)  # Set Strategy Cash
        self.roku= self.AddEquity("ROKU", Resolution.Daily)
        
        self.Settings.FreePortfolioValuePercentage = 0 #0.025
    
        # define a 10-period daily RSI indicator with shortcut helper method
        self.rsi = self.RSI("ROKU", 30, MovingAverageType.Wilders, Resolution.Daily)
        # self.rsi = self.RSI("ROKU", 30, MovingAverageType.Wilders, Resolution.Daily)

        
        history = self.History(["ROKU"], 30, Resolution.Daily)
        for time, row in history.loc["ROKU"].iterrows():
            self.rsi.Update(time, row["close"])
        
    

    def OnData(self, data):

        if not self.rsi.IsReady:
            return;
        # get the current RSI value
        rsi_roku_value = self.rsi.Current.Value
        
        #MovingAverageType.Wilders
        # In-sample data: start date: 2018/1/1 (warm up for 1 month)
        # Only long: return 63.36 % ; SR: 0.895
        if rsi_roku_value > 60:
            self.Liquidate();

        if rsi_roku_value < 40:
            quantity = self.CalculateOrderQuantity("ROKU", 1)
            self.Log(f"Price is : {self.Securities['ROKU'].Price}")
            self.Log(f"Quantity: {quantity}")
            p = PortfolioTarget.Percent(self, self.roku.Symbol, 1, True)
            self.Log(f"P: {p.Quantity}")
            #self.SetHoldings("ROKU", 1)
            self.MarketOrder("ROKU", quantity)



        # MovingAverageType.Simple
        # In-sample data: start date: 2018/1/1 (warm up for 1 month)
        # Best return: only long with (enter,exit) = (40,60)
        '''
        # Only short: return -80.32%; SR:-0.843
        if rsi_roku_value > 70:
            self.SetHoldings("ROKU", -1)  

        if rsi_roku_value < 30:
            self.Liquidate();
        
        
        # Only long: return 59.89%; SR: 0.873
        if rsi_roku_value > 70:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)        
                
        
        # Short and long:return -68.65 %; SR:0.542
        if rsi_roku_value > 70:
            self.SetHoldings("ROKU", -1)
        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)
        
        
        # Only long: return 54.06%; SR: 0.711
        if rsi_roku_value > 75:
            self.Liquidate();

        if rsi_roku_value < 35:
            self.SetHoldings("ROKU", 1) 
            
         # Only long: return 54.06%; SR: 0.711
        if rsi_roku_value > 75:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)   
            
         # Only long: return 65.86%; SR: 0.939
        if rsi_roku_value > 68:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)
        
        
        # Only long: return 39.44%; SR: 0.655
        if rsi_roku_value > 65:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)
           
        # Only long: return -2.36%; SR: 0.177
        if rsi_roku_value > 68:
            self.Liquidate();

        if rsi_roku_value < 35:
            self.SetHoldings("ROKU", 1)
        
        # Only long: return 68.83 % ; SR: 0.816
        if rsi_roku_value > 60:
            self.Liquidate();

        if rsi_roku_value < 40:
            self.SetHoldings("ROKU", 1)

        
        # Out-sample data: start date: 2019/1/1 (warm up for 1 month)
        # Best return: only long with (enter,exit) = (40,68)
        
        # Only long: return 49.44 %; SR: 0.655
        if rsi_roku_value > 65:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)
          
        # Only long: return 60.77  %; SR: 1.834
        if rsi_roku_value > 70:
            self.Liquidate();

        if rsi_roku_value < 30:
            self.SetHoldings("ROKU", 1)
        
        
        # Only long: return 191.20 %; SR: 3.669
        if rsi_roku_value > 60:
            self.Liquidate();

        if rsi_roku_value < 40:
            self.SetHoldings("ROKU", 1)
        '''
class CalmFluorescentPinkChicken(QCAlgorithm):

    def Initialize(self):
        # backtest for past 3 years
        self.SetStartDate(2019, 2, 21)  
        self.SetEndDate(2021,2,21) 
        self.SetCash(100000)  # Set Strategy Cash
        self.AddEquity("DIA", Resolution.Daily)

        # define a 10-period daily RSI indicator with shortcut helper method
        self.rsi = self.RSI("DIA", 10, MovingAverageType.Simple, Resolution.Daily)

        history = self.History(["DIA"], 10, Resolution.Daily)
        for time, row in history.loc["DIA"].iterrows():
            self.rsi.Update(time, row["close"])
        

    def OnData(self, data):

        if not self.rsi.IsReady:
            return;
        # get the current RSI value
        rsi_dia_value = self.rsi.Current.Value
        # get the current average gain of rsi
        # average_gain = self.rsi.AverageGain.Current.Value
        # get the current average loss of rsi
        # average_loss = self.rsi.AverageLoss.Current.Value
        
        # self.Debug("twest"+strlen(self.rsi))
        if rsi_dia_value > 70:
            self.SetHoldings("DIA", -1)
        if rsi_dia_value < 30:
            self.SetHoldings("DIA", 1)