| Overall Statistics |
|
Total Trades 6 Average Win 32.04% Average Loss -5.17% Compounding Annual Return 44.996% Drawdown 20.200% Expectancy 3.800 Net Profit 57.131% Sharpe Ratio 1.941 Probabilistic Sharpe Ratio 73.724% Loss Rate 33% Win Rate 67% Profit-Loss Ratio 6.20 Alpha 0.421 Beta 0.31 Annual Standard Deviation 0.256 Annual Variance 0.066 Information Ratio 0.785 Tracking Error 0.32 Treynor Ratio 1.602 Total Fees $6.00 Estimated Strategy Capacity $13000000.00 |
### <summary>
### Simple SMA Strategy intended to provide a minimal algorithm example using
### one indicator with the most basic plotting
### </summary>
from datetime import timedelta
from System.Drawing import Color
class SMAAlgorithm(QCAlgorithm):
# 1 - Add the FANG stocks (Facebook, Amazon, , Netflix, Google)
# 2 - Cycle through stocks
# 3 - Cycle through list adding each equity
# 3 - Create an indicator dict like backtrader
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.'''
# Set our main strategy parameters
self.SetStartDate(2020,1,1) # Set Start Date
#self.SetEndDate(2018,1,1) # Set End Date
self.SetCash(10000) # Set Strategy Cash
SMA_Period = 14 # SMA Look back period
self.SMA_OB = 75 # SMA Overbought level
self.SMA_OS = 50 # SMA Oversold level
self.Allocate = 0.20 # Percentage of captital to allocate
self.Equities = ["TSLA", "FB"]
#self.smaDaily = SMA(symbol, 200, Resolution.Daily)
self.Indicators = dict()
self.Charts = dict()
self.Consolidators = dict()
# Find more symbols here: http://quantconnect.com/data
for Symbol in self.Equities:
self.Consolidators[Symbol] = dict()
self.AddEquity(Symbol, Resolution.Minute)
# Each Equity requires its own consoilidator! See:
# https://www.quantconnect.com/forum/discussion/1936/multiple-consolidators/p1
# https://www.quantconnect.com/forum/discussion/1587/multiple-symbol-indicator-values-in-consolidated-bar-handler/p1
# ------------------------
# Create our consolidators
self.Consolidators[Symbol]['onDayCon'] = TradeBarConsolidator(timedelta(days=1))
self.Consolidators[Symbol]['minutesCon'] = TradeBarConsolidator(timedelta(minutes=20))
# Register our Handlers
self.Consolidators[Symbol]['onDayCon'].DataConsolidated += self.onDay
self.Consolidators[Symbol]['minutesCon'].DataConsolidated += self.minutes20
self.Indicators[Symbol] = dict()
self.Indicators[Symbol]['SMA'] = dict()
self.Indicators[Symbol]['Ichimoku'] = dict()
self.Indicators[Symbol]['SMA']['SMA200'] = self.SMA(Symbol, 200, Resolution.Daily)
self.Indicators[Symbol]['SMA']['SMA50'] = self.SMA(Symbol, 50, Resolution.Daily)
self.Indicators[Symbol]['Ichimoku'] = self.ICHIMOKU(Symbol,9, 26, 26, 52, 26, 26, Resolution.Daily)
# Register the indicaors with our stock and consolidator
self.RegisterIndicator(Symbol, self.Indicators[Symbol]['SMA']['SMA50'], self.Consolidators[Symbol]['onDayCon'])
self.RegisterIndicator(Symbol, self.Indicators[Symbol]['SMA']['SMA200'], self.Consolidators[Symbol]['onDayCon'])
self.RegisterIndicator(Symbol, self.Indicators[Symbol]['Ichimoku'], self.Consolidators[Symbol]['onDayCon'])
# Finally add our consolidators to the subscription
# manager in order to receive updates from the engine
self.SubscriptionManager.AddConsolidator(Symbol, self.Consolidators[Symbol]['onDayCon'])
self.Charts[Symbol] = dict()
# Plot the SMA
SMAChartName = Symbol+" TradePlot"
self.Charts[Symbol][' TradePlot'] = Chart(SMAChartName, ChartType.Stacked)
self.Charts[Symbol][' TradePlot'].AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Diamond))
self.Charts[Symbol][' TradePlot'].AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.Diamond))
self.Charts[Symbol][' TradePlot'].AddSeries(Series("200", SeriesType.Line,"", Color.Red))
self.Charts[Symbol][' TradePlot'].AddSeries(Series("50", SeriesType.Line,"", Color.Blue))
self.Charts[Symbol][' TradePlot'].AddSeries(Series("close", SeriesType.Line,"", Color.Gray))
self.Charts[Symbol][' TradePlot'].AddSeries(Series("SenkouA", SeriesType.Line,"", Color.Orange))
self.Charts[Symbol][' TradePlot'].AddSeries(Series('SenkouB', SeriesType.Line,"", Color.Brown))
self.Charts[Symbol][' TradePlot'].AddSeries(Series('Tenkan', SeriesType.Line, "", Color.Turquoise))
self.Charts[Symbol][' TradePlot'].AddSeries(Series('Kijun', SeriesType.Line,"", Color.Purple))
self.AddChart(self.Charts[Symbol][' TradePlot'])
'''# Create a custom volume chart
VolChartName = Symbol+" Volume"
self.Charts[Symbol]['VOL'] = Chart(VolChartName, ChartType.Stacked)
self.Charts[Symbol]['VOL'].AddSeries(Series('Buying Volume', SeriesType.Bar))
self.Charts[Symbol]['VOL'].AddSeries(Series('Selling Volume', SeriesType.Bar))
self.AddChart(self.Charts[Symbol]['VOL'])
'''
# Ensure that the Indicator has enough data before trading.
self.SetWarmUp(timedelta(days= 200))
self.dayCount = 0
self.countMinutes = 0
def onDay(self,sender,bar):
# Make sure we are not warming up
if self.IsWarmingUp: return
Symbol = str(bar.get_Symbol())
Volume = bar.Volume
#self.Plot(Symbol+" volume", 'Buying Volume', Volume)
close= bar.Close
SMA200 = self.Indicators[Symbol]['SMA']['SMA200'].Current.Value
SMA50 = self.Indicators[Symbol]['SMA']['SMA50'].Current.Value
tenkan = self.Indicators[Symbol]['Ichimoku'].Tenkan.Current.Value
kijun = self.Indicators[Symbol]['Ichimoku'].Kijun.Current.Value
senkouA = self.Indicators[Symbol]['Ichimoku'].SenkouA.Current.Value
senkouB = self.Indicators[Symbol]['Ichimoku'].SenkouB.Current.Value
SenkouAFuture = ( self.Indicators[Symbol]['Ichimoku'].Tenkan.Current.Value + self.Indicators[Symbol]['Ichimoku'].Current.Value) / 2
SenkouBFuture = (self.Indicators[Symbol]['Ichimoku'].SenkouBMaximum.Current.Value + self.Indicators[Symbol]['Ichimoku'].SenkouBMinimum.Current.Value) / 2
self.Plot(Symbol +' TradePlot', '200', SMA200)
self.Plot(Symbol +' TradePlot', '50', SMA50)
self.Plot(Symbol +' TradePlot', 'close', close)
self.Plot(Symbol +' TradePlot', 'Tenkan', tenkan)
self.Plot(Symbol +' TradePlot', 'Kijun', kijun)
self.Plot(Symbol +' TradePlot', 'SenkouA', senkouA)
self.Plot(Symbol +' TradePlot', 'SenkouB', senkouB)
# Determine our entry and exit conditions
# Do it here to avoid long lines later
Long_Cond1 = SMA200 < SMA50
Long_Cond2 = kijun > tenkan
# above cloud
Long_Cond3 = close > senkouA
Long_Cond4 = close > senkouB
Long_Cond5 = close > SMA200
Long_Cond6 = tenkan > senkouA
Long_Cond7 = kijun > senkouB
Long_Cond8 = close > SMA50
Long_Cond9 = SenkouAFuture > SenkouBFuture
#EXIT conditions
Exit_Cond1 = kijun < close
Exit_Cond2 = close < senkouA
Exit_Cond3 = close < senkouB
if not self.Securities[Symbol].Invested:
# If not, the long conditions
if all([Long_Cond1, Long_Cond2, Long_Cond3, Long_Cond4, Long_Cond5, Long_Cond6, Long_Cond7, Long_Cond8,Long_Cond9]):
# Buy!
self.SetHoldings(Symbol, self.Allocate)
self.Plot(Symbol +' TradePlot', 'Buy', close )
else:
if self.Securities[Symbol].Invested:
if all([Exit_Cond1, Exit_Cond2, Exit_Cond3]):
# Sell!
self.Liquidate(Symbol)
self.Plot(Symbol +' TradePlot', 'Sell', close)
'''
if self.dayCount> 3 : return
self.Debug(" onDay")
Symbol = str(bar.get_Symbol())
self.Debug(Symbol)
self.Debug(bar.Close)
self.dayCount = self.dayCount + 1
'''
def minutes20(self,sender,bar):
if self.IsWarmingUp: return
#debug
'''
if self.countMinutes> 3 : return
self.Debug(" 20Minutes")
Symbol = str(bar.get_Symbol())
self.Debug(Symbol)
self.Debug(bar.Close)
self.countMinutes = self.countMinutes + 1
'''
def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
# Make sure we are not warming up
if self.IsWarmingUp: return