Overall Statistics
Total Trades
7
Average Win
5.18%
Average Loss
-2.89%
Compounding Annual Return
61.298%
Drawdown
24.200%
Expectancy
0.863
Net Profit
78.816%
Sharpe Ratio
2.179
Probabilistic Sharpe Ratio
76.288%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
1.79
Alpha
0.577
Beta
0.472
Annual Standard Deviation
0.319
Annual Variance
0.102
Information Ratio
1.354
Tracking Error
0.328
Treynor Ratio
1.474
Total Fees
$7.00
Estimated Strategy Capacity
$12000000.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 = ["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("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())
        Volume = bar.Volume

        #self.Plot(Symbol+" volume", 'Buying Volume', Volume)
        Close= bar.Close

        #self.Plot(Symbol+" close", 'Buying Volume', 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

        
                
        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