Overall Statistics
Total Trades
67
Average Win
7.85%
Average Loss
-2.54%
Compounding Annual Return
7.542%
Drawdown
23.600%
Expectancy
1.108
Net Profit
124.168%
Sharpe Ratio
0.653
Probabilistic Sharpe Ratio
9.191%
Loss Rate
48%
Win Rate
52%
Profit-Loss Ratio
3.09
Alpha
0.069
Beta
-0.011
Annual Standard Deviation
0.103
Annual Variance
0.011
Information Ratio
-0.315
Tracking Error
0.189
Treynor Ratio
-6.404
Total Fees
$166.76
# kijun= (26 period high + 26 periode low) /2

# documentation : 
#https://www.quantconnect.com/lean/documentation/topic28737.html
#https://www.quantconnect.com/forum/discussion/4507/output-of-ichimoku-indicator/p1
import numpy as np
from datetime import timedelta
from datetime import datetime
import pandas as pd


from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from QuantConnect.Data.Market import TradeBar
from System.Drawing import Color


class inchimoku(QCAlgorithm):

 

     def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        #self.SetEndDate(2021, 2, 3)
        self.SetCash(10000)
        self.symbol = "AAPL"
        
        
        self.AddEquity(self.symbol, Resolution.Daily)
        self.ichimoku = self.ICHIMOKU(self.symbol,9, 26, 26, 52, 26, 26, Resolution.Daily) 

        
       
        #self.SetWarmUp(52,Resolution.Daily)
        
        
        ichimokuPlot = Chart('ichimokuPlot')
        
        #ichimokuPlot.AddSeries(Series('Tenkan', SeriesType.Line, "", Color.Blue))
        ichimokuPlot.AddSeries(Series('Tenkan', SeriesType.Line, "", Color.Red))

        ichimokuPlot.AddSeries(Series('Kijun', SeriesType.Line, "", Color.Purple))
        #ichimokuPlot.AddSeries(Series('KijunCal', SeriesType.Line, "", Color.Green))

        ichimokuPlot.AddSeries(Series('SenkouA', SeriesType.Line, "", Color.Orange))
        ichimokuPlot.AddSeries(Series('SenkouB', SeriesType.Line, "", Color.Yellow))
        #ichimokuPlot.AddSeries(Series('SenkouACal', SeriesType.Line, "", Color.Yellow))

        ichimokuPlot.AddSeries(Series('SenkouBCal', SeriesType.Line, "", Color.White))

        ichimokuPlot.AddSeries(Series('Chikou', SeriesType.Line, "", Color.Pink))
        ichimokuPlot.AddSeries(Series('Price', SeriesType.Line, "", Color.Gray))
        ichimokuPlot.AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Green, ScatterMarkerSymbol.Triangle))
        ichimokuPlot.AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.TriangleDown))
        
        self.AddChart(ichimokuPlot)
        
        self.highestPrice = 0
        self.buyPrice = 0
        
        self.rwPrice = RollingWindow[float](26)
        self.rwKijun = RollingWindow[float](26)
        self.rwTenkan = RollingWindow[float](26)
        self.rwSenkouA = RollingWindow[float](26)
        self.rwSenkouB = RollingWindow[float](26)
        self.rwHigh = RollingWindow[float](52)
        self.rwLow = RollingWindow[float](52)
        self.rwSenkouBCal = RollingWindow[float](28) # 28# to high? should be 26
        self.rwSenkouACal = RollingWindow[float](26) #27    # should I change it? 
        

        


     def OnData(self,data):
        if data[self.symbol] is None: return
        
        self.lastClose = data[self.symbol].Close
        self.lastHigh = data[self.symbol].High
        self.lastLow = data[self.symbol].Low
        #data[self.symbol].Time
        

        
        #if self.IsWarmingUp: return
    
        if self.ichimoku.IsReady: 
            self.rwPrice.Add(self.lastClose)
            self.rwKijun.Add(self.ichimoku.Kijun.Current.Value)
            self.rwTenkan.Add(self.ichimoku.Tenkan.Current.Value)
            self.rwSenkouA.Add(self.ichimoku.SenkouA.Current.Value)
            self.rwSenkouB.Add(self.ichimoku.SenkouB.Current.Value)
            self.rwHigh.Add(self.lastHigh)
            self.rwLow.Add(self.lastLow)
            


            
            if self.rwKijun.IsReady and self.rwPrice.IsReady and self.rwTenkan.IsReady and self.rwSenkouA.IsReady and self.rwSenkouB.IsReady  and self.rwLow.IsReady and self.rwHigh.IsReady:
                
                lowestLow  = min(list(self.rwHigh))
                highestHigh = max(list(self.rwHigh))
     
     
                self.SenkouBCal = (highestHigh + lowestLow) / 2 
                
                #self.SenkouBCal= (self.ichimoku.DelayedMaximumSenkouB.Current.Value + self.ichimoku.DelayedMinimumSenkouB.Current.Value) / 2

                self.SenkouBCal= (self.ichimoku.SenkouBMaximum.Current.Value + self.ichimoku.SenkouBMinimum.Current.Value) / 2
                # correct the calculated senkou B value to be like the indicator in quantconnect.
                #differenceX=  self.SenkouBCal- self.ichimoku.SenkouB.Current.Value
                #self.SenkouBCal = differenceX + self.SenkouBCal
                

                self.rwSenkouBCal.Add(self.SenkouBCal)
                
                
                self.SenkouACal = ( self.ichimoku.Tenkan.Current.Value + self.ichimoku.Kijun.Current.Value) / 2 
                self.rwSenkouACal.Add(self.SenkouACal)
                
                if self.rwSenkouBCal.IsReady and self.rwSenkouACal.IsReady: 
                    
                    # plot
                    self.Plot("ichimokuPlot", "Tenkan", self.ichimoku.Tenkan.Current.Value)
                    self.Plot("ichimokuPlot", "Kijun", self.ichimoku.Kijun.Current.Value)
                    self.Plot("ichimokuPlot", "Price", self.lastClose)
                    self.Plot("ichimokuPlot", "Chikou", self.ichimoku.Chikou.Current.Value)
                    self.Plot("ichimokuPlot", "SenkouA", self.ichimoku.SenkouA.Current.Value)
                    self.Plot("ichimokuPlot", "SenkouB", self.ichimoku.SenkouB.Current.Value)
                    self.Plot("ichimokuPlot", "SenkouBCal", self.rwSenkouBCal[self.rwSenkouBCal.Count-1])
                    self.Plot("ichimokuPlot", "SenkouACal", self.rwSenkouACal[self.rwSenkouACal.Count-1])
                    
                    
                    # BUY strategy: 
                    # price is above cloud

                    # Chikou is higher than price below it and the cloud. 
                    if self.lastClose > self.rwPrice[25] :
                        
                        # check if there is a shadow. 
                        self.isThereShadow = False
                        i = 0
                        while i <= 25:
                            # if any of the prices from the last 26 days are inside the cloud (shadow) stop 
                            # if the price is lower than senkou A or B there is a cloud. then return
                            if self.rwPrice[i] < self.ichimoku.SenkouA.Current.Value or self.rwPrice[i] < self.ichimoku.SenkouB.Current.Value:
                                self.isThereShadow = True
                                break
                            i += 1
                            
                        # if no shadow
                        if not self.isThereShadow: 
                            
                            # is tenkan higher than kijun?
                            if self.ichimoku.Tenkan.Current.Value >= self.ichimoku.Kijun.Current.Value:
                                # is tenkan is moving up?
                                if self.ichimoku.Tenkan.Current.Value > self.rwTenkan[1]:
                                
                                    # is future cloud is green (preferebly thick)
                                    
                                    
                                    if self.SenkouACal > self.SenkouBCal: 
                                    
                                        #if not invested buy
                                        if not self.Portfolio.Invested:  
                                            self.SetHoldings(self.symbol, 1)
                                            self.Plot("ichimokuPlot", "Buy", self.lastClose)   
                                            self.buyPrice = self.lastClose
                                            
                                            self.highestPrice = 0
                                            self.stopPrice = self.buyPrice
                #sell
                # if chikou touches price, sell. or stop is hit (kijun is hit)
                # if chikou is lower than current price
                # if price 26 days ago is higher than now.
                chikouCurrent = self.lastClose 
                # or self.lastClose < self.ichimoku.Kijun.Current.Value
                #self.rwPrice[25] <= chikouCurrent:
                
                #if self.ichimoku.Kijun.Current.Value:
                #if  < self.ichimoku.Kijun.Current.Value * 0.98: 

                if  self.lastClose < self.ichimoku.Kijun.Current.Value: 
                    if self.Portfolio.Invested:
                        self.Liquidate()
                        self.Plot("ichimokuPlot", "Sell", self.lastClose)