| Overall Statistics |
|
Total Trades 817 Average Win 1.16% Average Loss -0.68% Compounding Annual Return 500.468% Drawdown 14.700% Expectancy 0.354 Net Profit 112.995% Sharpe Ratio 8.607 Probabilistic Sharpe Ratio 98.643% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.71 Alpha 3.892 Beta 0.226 Annual Standard Deviation 0.459 Annual Variance 0.211 Information Ratio 7.849 Tracking Error 0.469 Treynor Ratio 17.52 Total Fees $925.53 Estimated Strategy Capacity $6300000.00 Lowest Capacity Asset TLRY WWAWWB4P01GL |
import pandas as pd
import numpy as np
from io import StringIO
class RedditStockSentiment(QCAlgorithm):
def Initialize(self):
# self.SetStartDate(2016,1, 1) # Set Start Date
# self.SetEndDate(2020, 12, 31) #Set End Date
# self.SetCash(100000) # Set Strategy Cash
self.SetStartDate(2021, 1, 1)
self.SetEndDate(2021, 6, 3)
# self.SetCash(4860) # Set Strategy Cash highlow
self.SetCash(5600) # Set Strategy Cash low
self.tickers = ["TSLA", "AAPL", "SPCE", "CLOV","LULU","PLTR","TLRY","FB","MARA", "AMD"]
self.investP = 1/len(self.tickers) #Equal weight portfolio
for stock in self.tickers:
self.AddEquity(stock, Resolution.Daily)
# self.AddRiskManagement(TrailingStopRiskManagementModel(0.08)) #Risk management
self.trade = True #OnData will run when the program when the program is first executed
csv = self.Download("https://www.dropbox.com/s/vovg893xfc0berw/Reddit_Sentiment_Equity.csv?dl=1") #Downloads data
self.df = pd.read_csv(StringIO(csv)) #Read into a dataframe
self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.At(8, 30),
self.runDaily)
def OnData(self, data):
if self.trade != True:
return
#Assigns three variables with the current time(year, month, day)
algYear = self.Time.year
algMonth = self.Time.month
algDay = self.Time.day
algHour = self.Time.hour
#Iterates through the dataframe tuples
for row in self.df.itertuples():
try: #If there is an error with dates a tuple(row) then continue to the next row
date = row[-1] #Date is the index of the tuple(final colum in the dataframe)
#Date is parsed as a string and assigned to three variables
year = date[0:4]
month = date[5:7]
day = date[8:10]
hour = date[11:13]
except:
continue
#Compares current date with the date from the tuple
if ((int(year) != algYear) or (int(month) != algMonth) or (int(day) != algDay)):
continue
'''
averageSentiment is calculated by averaging the sentiment of the submission title, body text, and all comments.
This process can be very time consuming.
'''
#Assigns several variables with data from the tuple
stock = str(row[1])
averageSentiment = float(row[4])
numberOfComments = int(row[3])
score = int(row[7])
adjust = 1
#If score is low, allocate a smaller percentage to the position taken for the underlying equity
if score <= 20:
adjust = 0.5
if(averageSentiment >= 0.1) and not self.Portfolio[stock].IsLong:
self.SetHoldings(stock, self.investP*adjust, True)
if(averageSentiment <= -0.1) and not self.Portfolio[stock].IsShort:
self.SetHoldings(stock, - (self.investP*0.5)*adjust, True)
if (-0.1 < averageSentiment < 0.1):
self.Liquidate(stock)
self.trade = False
def runDaily(self):
self.trade = True