Overall Statistics
from datetime import datetime
import decimal
import numpy as np
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Brokerages import *
from QuantConnect.Orders import *


class DynamicBreakoutAlgorithm(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2019,1,1)
        self.SetEndDate(2019,5,1)
        self.SetCash(100000)
        self.SetCash("EUR", 10000)
        self.SetCash("BTC", 1)
        self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
        self.symbolForHistoryCall = self.AddCrypto("BTCUSD", Resolution.Daily).Symbol
        self.syl = "BTCUSD"
        self.Securities["BTCUSD"].SetDataNormalizationMode(DataNormalizationMode.Raw);
        self.Schedule.On(self.DateRules.EveryDay(self.syl), self.TimeRules.BeforeMarketClose(self.syl,1),self.SetSignal)
        self.numdays = 20  
        self.ceiling,self.floor = 60,20
        self.buypoint, self.sellpoint= None, None
        self.longLiqPoint, self.shortLiqPoint, self.yesterdayclose= None, None, None
        self.SetBenchmark(self.syl)
        self.Bolband = self.BB(self.syl, self.numdays, 2, MovingAverageType.Simple, Resolution.Daily)
   
    def SetSignal(self):
        close = self.History(self.symbolForHistoryCall, 31, Resolution.Daily)['close']
        todayvol = np.std(close[1:31])
        yesterdayvol = np.std(close[0:30])
        deltavol = (todayvol - yesterdayvol) / todayvol
        self.numdays = int(round(self.numdays * (1 + deltavol)))

        if self.numdays > self.ceiling:
           self.numdays = self.ceiling
        elif self.numdays < self.floor:
            self.numdays = self.floor
        
        self.high = self.History(self.symbolForHistoryCall, self.numdays, Resolution.Daily)['high']
        self.low = self.History(self.symbolForHistoryCall, self.numdays, Resolution.Daily)['low']      

        self.buypoint = max(self.high)
        self.sellpoint = min(self.low)
        historyclose = self.History(self.symbolForHistoryCall, self.numdays, Resolution.Daily)['close'] 
        self.longLiqPoint = np.mean(historyclose)
        self.shortLiqPoint = np.mean(historyclose)
        self.yesterdayclose = historyclose.iloc[-1]
        
        # wait for our BollingerBand to fully initialize
        if not self.Bolband.IsReady: return

        holdings = self.Portfolio[self.syl].Quantity
    
        if self.yesterdayclose > self.Bolband.UpperBand.Current.Value and self.Portfolio[self.syl].Price >= self.buypoint:
            self.SetHoldings(self.syl, 1)
        elif self.yesterdayclose < self.Bolband.LowerBand.Current.Value and self.Portfolio[self.syl].Price <= self.sellpoint:
            self.SetHoldings(self.syl, -1)

        if holdings > 0 and self.Portfolio[self.syl].Price <= self.shortLiqPoint:
            self.Liquidate(self.syl)
        elif holdings < 0 and self.Portfolio[self.syl].Price >= self.shortLiqPoint:
            self.Liquidate(self.syl)
      
        self.Log(str(self.yesterdayclose)+(" # of days ")+(str(self.numdays)))
        
    def OnData(self,data):
        pass