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