| Overall Statistics |
|
Total Trades 8 Average Win 0% Average Loss -7.78% Compounding Annual Return -98.101% Drawdown 99.500% Expectancy -1 Net Profit -21.215% Sharpe Ratio -1.608 Probabilistic Sharpe Ratio 4.673% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.937 Beta -0.004 Annual Standard Deviation 0.584 Annual Variance 0.341 Information Ratio -2.047 Tracking Error 0.587 Treynor Ratio 220.112 Total Fees $612.66 |
import numpy as np
### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
'''Basic template algorithm simply initializes the date range and cash'''
def Initialize(self):
self.SetStartDate(2018,7, 30) #Set Start Date
self.SetEndDate(2018,8,20) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.Crypto = ["BTCUSD","LTCUSD","ETHUSD"]
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
RSI_Period = 24 # RSI Look back period
self.RSI_OB = 65 # RSI Overbought level
self.RSI_OS = 35 # RSI Oversold level
self.Allocate = 0.30 # Percentage of captital to allocate
self.Indicators = dict()
self.Charts = dict()
self.Consolidators = dict()
for Symbol in self.Crypto:
self.Consolidators[Symbol] = dict()
self.AddCrypto(Symbol, Resolution.Hour)
# Each Equity requires its own consoilidator! See:
# Create our consolidators
self.Consolidators[Symbol]['W1 Con'] = TradeBarConsolidator(timedelta(days=5))
# Register our Handlers
self.Consolidators[Symbol]['W1 Con'].DataConsolidated += self.On_W1
self.Indicators[Symbol] = dict()
self.Indicators[Symbol]['RSI'] = dict()
self.Indicators[Symbol]['RSI']['D'] = self.RSI(Symbol, RSI_Period)
self.Indicators[Symbol]['RSI']['W'] = RelativeStrengthIndex(Symbol, RSI_Period)
# Register the indicaors with our stock and consolidator
self.RegisterIndicator(Symbol, self.Indicators[Symbol]['RSI']['W'], self.Consolidators[Symbol]['W1 Con'])
# Finally add our consolidators to the subscription
# manager in order to receive updates from the engine
self.SubscriptionManager.AddConsolidator(Symbol, self.Consolidators[Symbol]['W1 Con'])
self.Charts[Symbol] = dict()
# Plot the RSI
RSIChartName = Symbol+" RSI"
self.Charts[Symbol]['RSI'] = Chart(RSIChartName, ChartType.Stacked)
self.Charts[Symbol]['RSI'].AddSeries(Series("D1", SeriesType.Line))
self.Charts[Symbol]['RSI'].AddSeries(Series("W1", SeriesType.Line))
self.AddChart(self.Charts[Symbol]['RSI'])
# Ensure that the Indicator has enough data before trading,.
# x5 to get enough weekly data
self.SetWarmUp(RSI_Period*5)
def On_W1(self,sender,bar):
'''
This method will be called every time a new 30 minute bar is ready.
'''
# Make sure we are not warming up
if self.IsWarmingUp: return
Symbol = str(bar.get_Symbol())
self.Plot(Symbol+' RSI', 'W1', self.Indicators[Symbol]['RSI']['W'].Current.Value)
def OnData(self, data):
# Make sure we are not warming up
if self.IsWarmingUp: return
# Loop through our equities
for Symbol in self.Crypto:
# Add some alias for reading ease
Close = data[Symbol].Close
D1_RSI = self.Indicators[Symbol]['RSI']['D'].Current.Value
W1_RSI = self.Indicators[Symbol]['RSI']['W'].Current.Value
self.Debug("{}: Close: {} RSI: {}".format(Symbol, Close, D1_RSI))
self.Plot(Symbol +' RSI', 'D1', D1_RSI)
# Determine our entry and exit conditions
# Do it here to avoid long lines later
Long_Cond1 = D1_RSI < self.RSI_OS
Long_Cond2 = W1_RSI < self.RSI_OS
Exit_Cond1 = D1_RSI > self.RSI_OB
Exit_Cond2 = W1_RSI > self.RSI_OB
if not self.Securities[Symbol].Invested:
# If not, the long conditions
if all([Long_Cond1]):
# Buy!
self.SetHoldings(Symbol, self.Allocate)
else:
if all([Exit_Cond1]):
# Sell!
self.Liquidate(Symbol)