| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0.217 Tracking Error 0.086 Treynor Ratio 0 Total Fees $0.00 |
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from System.Collections.Generic import List
class main(QCAlgorithm):
def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2020, 12, 20)
#self.SetEndDate(2015,1,1) #Set End Date
self.initialcash=10000000 #Set Strategy Cash
self.totalPortfolioProfitTarget=self.initialcash/2 #means a take profit after 50% rise in portfolio value
self.SetCash(self.initialcash)
self.PercentageOfPortfolioToAllocateToEachSecurity= 0.02 # 1 means 100%
self.numOfCoarseSymbols = 10 #max number of symbols that are returned by our universe selection function
self.SetBrokerageModel(BrokerageName.Alpaca)
self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x)))
self.UniverseSettings.Resolution = Resolution.Hour # Timeframe to trade
self.UniverseSettings.Leverage = 1
self.benchmark="SPY"
self.benchmark= self.AddEquity(self.benchmark, self.UniverseSettings.Resolution)
self.SPY_EMA = self.EMA("SPY", 20, Resolution.Daily)
self.SymbolDataDictionary = {}
self.AddUniverse(self.CoarseSelectionFunction)
# schedule an event to fire on a single day of the week
#self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(15, 50), self.buy_time)
#schedule an event to Liquidate (exit all positions at the day and hours specified)
#self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.At(9, 10), self.sell_time)
def buy_time(self):
for kvp in self.SymbolDataDictionary:
symbol=self.SymbolDataDictionary[kvp]
if self.benchmark.Price > self.SPY_EMA.Current.Value :
self.SetHoldings(kvp, self.PercentageOfPortfolioToAllocateToEachSecurity) #here the actual positions are initiated, in this case the symbols are 10, so every symbol receives 10% of the Portfolio. In this case being the cash 100000$ every stock gets an allocation of 10000$.
#The three lines below are used to Debug
#self.Log(" Symbol "+ str(symbol.symbol))
#self.Log(" % Performance of the symbol "+ str(symbol.get_percentage_change()))
#self.Log(" Volume of the symbol "+ str(symbol.get_relative_volume()))
def sell_time(self):
self.Liquidate()
def CoarseSelectionFunction(self, coarse):
CoarseWithFundamental = [x for x in coarse if x.HasFundamentalData and x.Price > 1 and x.Price<50]
sortedByVolume = sorted(CoarseWithFundamental, key=lambda x: x.DollarVolume, reverse=True)
# We are going to use a dictionary to refer the object that will keep the moving averages
for kvp in sortedByVolume:
if kvp.Symbol not in self.SymbolDataDictionary:
self.SymbolDataDictionary[kvp.Symbol]=SymbolData(kvp.Symbol)
for cf in coarse:
if cf.Symbol in self.SymbolDataDictionary:
self.SymbolDataDictionary[cf.Symbol].update(cf.EndTime, cf.AdjustedPrice, kvp.DollarVolume)
#values = list(filter(lambda x: x.EMAS_ARE_OK and x.RSI_IS_OK and x.percentage_change and x.relative_volume, self.SymbolDataDictionary.values()))
#values = list(filter(lambda x: x.percentage_change,self.SymbolDataDictionary.values()))
values = list(self.SymbolDataDictionary.values())
values = sorted(values, key=lambda x: x.percentage_change and x.percentage_change>0.2, reverse=True)
#used to output instruments in the universe
for x in values:
self.Debug(str(self.Time)+' symbol: ' + str(x.symbol.Value)+" "+str(x.percentage_change))
# we need to return only the symbol objects
return [ x.symbol for x in values ] # return [ x.symbol for x in values[:self.numOfCoarseSymbols] ]
def OnData(self, data):
if self.Portfolio.Invested:
if self.Portfolio.TotalProfit > self.totalPortfolioProfitTarget:
self.Liquidate()
class SymbolData(object):
def __init__(self, symbol):
self.symbol = symbol
self.EMA1 = ExponentialMovingAverage (5)
self.EMA2 = ExponentialMovingAverage (20)
self.RSI = RelativeStrengthIndex(70)
self.PriceHistory = RollingWindow[float](2)
self.DollarVolumeHistory = RollingWindow[float](30)
#self.EMAS_ARE_OK = False
#self.RSI_IS_OK = False
self.percentage_change=0
#self.relative_volume=False
def update(self, time, value, volume):
if self.EMA1.Update(time, value) and self.EMA2.Update(time, value):
EMA1 = self.EMA1.Current.Value
EMA2 = self.EMA2.Current.Value
self.EMAS_ARE_OK = value > EMA1 and value > EMA2
if self.RSI.Update(time, value):
RSI = self.RSI.Current.Value
self.RSI_IS_OK = value > RSI
self.PriceHistory.Add(value)
self.DollarVolumeHistory.Add(volume)
if self.PriceHistory.Count>1:
self.percentage_change = (self.PriceHistory[0]-self.PriceHistory[1])/self.PriceHistory[1]
if self.DollarVolumeHistory.Count>29:
todays_volume=self.DollarVolumeHistory[0]
thirtydaysvolume=0
for i in range(0,self.DollarVolumeHistory.Count-1):
thirtydaysvolume=self.DollarVolumeHistory[i]+thirtydaysvolume
averagethirtydaysvolume=thirtydaysvolume/30 #let's divide by 30
relative_volume=(todays_volume-averagethirtydaysvolume)/averagethirtydaysvolume
if relative_volume > 2: #in this case I followed your Excel Spreadsheet example, >2
self.relative_volume=True