Overall Statistics |
Total Trades 6 Average Win 5.43% Average Loss -2.89% Compounding Annual Return 6.503% Drawdown 13.000% Expectancy 0.920 Net Profit 7.908% Sharpe Ratio 0.543 Probabilistic Sharpe Ratio 30.129% Loss Rate 33% Win Rate 67% Profit-Loss Ratio 1.88 Alpha 0.04 Beta 0.135 Annual Standard Deviation 0.139 Annual Variance 0.019 Information Ratio -0.635 Tracking Error 0.3 Treynor Ratio 0.559 Total Fees $6.00 Estimated Strategy Capacity $2500000.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 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 = ["FSLR", "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("200", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("50", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("close", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("SenkouA", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("SenkouB", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("Tenkan", SeriesType.Line)) self.Charts[Symbol][' TradePlot'].AddSeries(Series("Kijun", SeriesType.Line)) 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()) #self.Plot(Symbol+' TradePlot', '50', self.Indicators[Symbol]['SMA']['SMA50'].Current.Value) #self.Plot(Symbol+' TradePlot', '200', self.Indicators[Symbol]['SMA']['SMA200'].Current.Value) # Loop through our equities for Symbol in self.Equities: # Add some alias for reading ease Close= bar.Close Volume = bar.Volume 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 #self.Debug("{}: Close: {} SMA: {}".format(Symbol, Close, SMA200)) if bar.Close >= bar.Open: self.Plot(Symbol+" Volume", 'Buying Volume', Volume) else: self.Plot(Symbol+" Volume", 'Selling Volume', Volume) 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_Con1 = SMA200 < SMA50 Long_Cond2 = True Exit_Con1 = SMA200 > SMA50 Exit_Cond2 = True if not self.Securities[Symbol].Invested: # If not, the long conditions if all([Long_Con1, Long_Cond2]): # Buy! self.SetHoldings(Symbol, self.Allocate) else: if all([Exit_Con1, Exit_Cond2]): # Sell! self.Liquidate(Symbol) 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