Overall Statistics
Total Trades
35
Average Win
0.99%
Average Loss
-0.74%
Compounding Annual Return
8.314%
Drawdown
3.300%
Expectancy
0.654
Net Profit
8.361%
Sharpe Ratio
1.173
Probabilistic Sharpe Ratio
56.003%
Loss Rate
29%
Win Rate
71%
Profit-Loss Ratio
1.34
Alpha
0.069
Beta
-0.007
Annual Standard Deviation
0.059
Annual Variance
0.004
Information Ratio
0.578
Tracking Error
0.165
Treynor Ratio
-10.172
Total Fees
$9288.87
from QuantConnect.Indicators import *
import numpy as np
from datetime import datetime, timedelta
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score, accuracy_score
import sklearn as sk
import pandas as pd

class RSISwingRejection(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1) #Set End Date
        self.SetCash(10000000)  # Set Strategy Cash
        
        self.tickers = ["GOLD", "TSLA", "TREE", "YELP", "RYN"] #Selected stocks
        self.percent = 1/(len(self.tickers)) #Proportion of stock selection
        
        self.rsiDict = {}
        self.symbolDataBySymbol = {}
        
        self.returns = pd.DataFrame(columns=['Stock', 'Date', 'Holdings', 'RSI'])
        
        #Adding equity, the RSI, symbol data, and initializing a rolling window for each stock
        for symbol in self.tickers:
            self.AddEquity(symbol, Resolution.Daily)
            rsi = self.RSI(symbol, 14, MovingAverageType.Simple, Resolution.Daily)
            symbolData = SymbolData(symbol, rsi)
            self.symbolDataBySymbol[symbol] = symbolData
            self.rsiDict[symbol] = RollingWindow[float](14)
        
        #Warm-up the data for 30 days
        self.SetWarmUp(timedelta(days = 30))
        
    def OnData(self, data):
        
        #Make sure nothing is going on when warming up the data
        if self.IsWarmingUp: 
            return
        
        #Add the RSI values of each stock within the rolling window
        for symbol, symbolData in self.symbolDataBySymbol.items(): #For all securities in self.stocks
            rsi = symbolData.RSI
            self.rsiDict[symbol].Add(rsi.Current.Value)
        
            #If a stock has not been invested in
            
            if not self.Portfolio.Invested:
                
                #Overbought RSI Swing Rejection
                
                #RSI needs to surpass the 70 threshold
                if rsi.Current.Value > 70:
                    
                    #After the previous point, RSI must be between 45 and 55 (this is a self-selected range)
                    for x in range(self.rsiDict[symbol].Count):
                        if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] > 45 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] < 55:
                            
                            #Thereafter, RSI returns to a range between 65 and 70
                            for z in range(self.rsiDict[symbol].Count - x):
                                if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] > 65 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] < 70:
                                    
                                    #Trigger! Setup a short posiiton with the percent variable 
                                    self.SetHoldings(symbol, -self.percent)
            
                #Oversold RSI Swing Rejection
                
                #RSI needs to fall below the 30 threshold
                elif rsi.Current.Value < 30:
                    
                    #After the previous point, must be between 45 and 55
                    for x in range(self.rsiDict[symbol].Count):
                        if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] > 45 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] < 55:
                            
                            #Thereafter, RSI returns to a range between 30 and 35
                            for z in range(self.rsiDict[symbol].Count - x):
                                if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] > 30 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] < 35:
                                    
                                    #Trigger! Setup a long position with the percent variable
                                    self.SetHoldings(symbol, self.percent)
        
            #If a stock has been invested in
            
            else:
                #If there is a long position, liquidate when RSI returns to 45
                if self.Portfolio[symbol].IsLong:
                    if rsi.Current.Value > 45:
                        self.Liquidate(symbol)
                #If there is a short position, liquidate when RSI returns to 55        
                if self.Portfolio[symbol].IsShort:
                    if rsi.Current.Value < 55:
                        self.Liquidate(symbol)
                        
            new_row = ({'Stock': str(symbol), 'Date': self.Time, 'Holdings' : self.Portfolio[symbol].HoldingsValue,
                        'RSI' : rsi.Current.Value})
            self.returns = self.returns.append(new_row, ignore_index = True)
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from QuantConnect.Indicators import *
import numpy as np
from datetime import datetime, timedelta
from sklearn import linear_model
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import mean_squared_error, r2_score, accuracy_score
import sklearn as sk
import pandas as pd
import json

class RSISwingRejection(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1) #Set End Date
        self.SetCash(10000000)  # Set Strategy Cash
        
        self.tickers = ["GOLD", "TSLA", "TREE", "YELP", "RYN"] #Selected stocks
        self.percent = 1/(len(self.tickers)) #Proportion of stock selection
        
        self.rsiDict = {}
        self.symbolDataBySymbol = {}
        
        
        self.returns = pd.DataFrame(columns=['Stock', 'Date', 'Holdings', 'Price'])
        
        #Adding equity, the RSI, symbol data, and initializing a rolling window for each stock
        for symbol in self.tickers:
            self.AddEquity(symbol, Resolution.Daily)
            rsi = self.RSI(symbol, 14, MovingAverageType.Simple, Resolution.Daily)
            symbolData = SymbolData(symbol, rsi)
            self.symbolDataBySymbol[symbol] = symbolData
            self.rsiDict[symbol] = RollingWindow[float](14)

        
        #Warm-up the data for 30 day
        self.SetWarmUp(timedelta(days = 30))
        
        if self.ObjectStore.ContainsKey("MyObject"):
            self.ObjectStore.Delete("MyObject")
        
    def OnData(self, data):
        
        #Make sure nothing is going on when warming up the data
        if self.IsWarmingUp: 
            return
        
        #Add the RSI values of each stock within the rolling window
        for symbol, symbolData in self.symbolDataBySymbol.items(): #For all securities in self.stocks
            rsi = symbolData.RSI
            self.rsiDict[symbol].Add(rsi.Current.Value)
        
            #If a stock has not been invested in
            
            if not self.Portfolio.Invested:
                
                #Overbought RSI Swing Rejection
                
                #RSI needs to surpass the 70 threshold
                if rsi.Current.Value > 70:
                    
                    #After the previous point, RSI must be between 45 and 55 (this is a self-selected range)
                    for x in range(self.rsiDict[symbol].Count):
                        if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] > 45 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] < 55:
                            
                            #Thereafter, RSI returns to a range between 65 and 70
                            for z in range(self.rsiDict[symbol].Count - x):
                                if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] > 65 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] < 70:
                                    
                                    #Trigger! Setup a short posiiton with the percent variable 
                                    self.SetHoldings(symbol, -self.percent)
            
                #Oversold RSI Swing Rejection
                
                #RSI needs to fall below the 30 threshold
                elif rsi.Current.Value < 30:
                    
                    #After the previous point, must be between 45 and 55
                    for x in range(self.rsiDict[symbol].Count):
                        if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] > 45 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + 1)] < 55:
                            
                            #Thereafter, RSI returns to a range between 30 and 35
                            for z in range(self.rsiDict[symbol].Count - x):
                                if self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] > 30 and self.rsiDict[symbol][self.rsiDict[symbol].Count - (x + z + 1)] < 35:
                                    
                                    #Trigger! Setup a long position with the percent variable
                                    self.SetHoldings(symbol, self.percent)
        
            #If a stock has been invested in
            
            else:
                #If there is a long position, liquidate when RSI returns to 45
                if self.Portfolio[symbol].IsLong:
                    if rsi.Current.Value > 45:
                        self.Liquidate(symbol)
                        new_row = ({'Stock': str(symbol), 'Date': str(self.Time), 'Holdings' : self.Portfolio[symbol].HoldingsValue, 'Price': self.Securities[symbol].Price})
                        self.returns = self.returns.append(new_row, ignore_index = True)
                        #self.returns = self.returns.append(new_row, ignore_index = True)
                #If there is a short position, liquidate when RSI returns to 55        
                if self.Portfolio[symbol].IsShort:
                    if rsi.Current.Value < 55:
                        self.Liquidate(symbol)
                        new_row = ({'Stock': str(symbol), 'Date': str(self.Time), 'Holdings' : self.Portfolio[symbol].HoldingsValue, 'Price': self.Securities[symbol].Price})
                        self.returns = self.returns.append(new_row, ignore_index = True)
                        #self.returns = self.returns.append(new_row, ignore_index = True)
                        
                #new_row = ({'Stock': str(symbol), 'Date': str(self.Time), 'Holdings' : self.Portfolio[symbol].HoldingsValue, 'Price': self.Securities[symbol].Price})
                #self.returns = self.returns.append(new_row, ignore_index = True)
        
    def OnEndOfAlgorithm(self):
        self.returns = self.returns.sort_values(by = ["Date"])
        self.returns = self.returns.to_dict()
        save_json = json.dumps(self.returns)
        self.ObjectStore.Save("MyObject", save_json)
        load_object = json.loads(self.ObjectStore.Read("MyObject"))
        self.Debug(load_object)
        
class SymbolData:
    #Contains data specific to a symbol required by this model
    def __init__(self, symbol, rsi):
        self.Symbol = symbol
        self.RSI = rsi
        
    #def Regression(self):
    #    self.alphas_betas = {'GOLD':[a,b],'TSLA':[a,b],'TREE':[a,b],'YELP':[a,b],'RYN':[a,b]}
    #    alpha_beta = self.alphas_betas[str(symbol)]
    #    alpha = alpha_beta[0]
    #    beta = alpha_beta[1]
    #    ab_list = [results.intercept_,results.coef_[0,0], results.coef_[0,1]]
    #    self.Debug(ab_list)
    #    symbol = df['Stock'].iloc[0]
    #    self.alphas_betas[symbol] = ab_list 
        
    #IS Curve 
    #returns_dfs = pd.DataFrame(new_row[3]) #ERROR 
    #scores = []
    #model_scores = []
    #for df in returns_dfs:
    #    model_one = df[["Year1"]].astype(float)
    #    model_two = df[["Year1", "Year2"]].astype(float)
    #    model_three = df[["Year1", "Year2", "Year3"]].astype(float)
        
    #    y = df[["Returns"]].astype(float)
        
    #    models = (model_one, model_two, model_three)
        
    #    for x in models:
    #        regression_model = linear_model.LinearRegression()
    #        results_one = regression_model.fit(x,y)
    #        model_score = results_one.score(x,y)
    #    model_scores.append(scores)
    #    scores = []
        
    #models_avg=[]
    #avg = 0
    #for i in range (0,2):
    #    for j in range (0,5):
    #        avg = avg + model_scores[j][i]
    #    avg = avg / 5 
    #    models_avg.append(avg)
    #    avg = 0
    #print(models_avg)
    #df = pd.DataFrame(models_avg, columns=['avgerror'])
    #df.plot()