| Overall Statistics |
|
Total Trades 21 Average Win 125.10% Average Loss -6.97% Compounding Annual Return 249.198% Drawdown 28.000% Expectancy 6.581 Net Profit 898.933% Sharpe Ratio 3.356 Probabilistic Sharpe Ratio 94.560% Loss Rate 60% Win Rate 40% Profit-Loss Ratio 17.95 Alpha 0.786 Beta 0.515 Annual Standard Deviation 0.504 Annual Variance 0.254 Information Ratio -0.129 Tracking Error 0.491 Treynor Ratio 3.279 Total Fees $4042.15 Estimated Strategy Capacity $12000000.00 Lowest Capacity Asset BTCUSD XJ |
from QuantConnect.Indicators import *
import decimal as d
from pykalman import KalmanFilter
import numpy as np
### <summary>
### In this example we are looking for price to breakout above the bollinger bands
### and look to buy when we see that. We hold our position until price touches the
### middle band of the bollinger bands.
###
# ----------------------------------------
CRYPTO = 'BTCUSD'; PERIODSHORT = 10; PERIOD = 30; PERIODLONG = 30; LEV = 1.0;
# ----------------------------------------
class BollingerBreakoutAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1) #Set Start Date
self.SetEndDate(2021, 11, 1) #Set End Date
self.SetCash(10000) #Set Strategy Cash
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
# define crypto we want to trade on
# ETHUSD, LTCUSD or BTCUSD
#self.target_crypto = "ETHUSD"
self.target_crypto = "BTCUSD"
self.crypto = self.AddCrypto(self.target_crypto, Resolution.Daily).Symbol
self.rollingWindow = RollingWindow[TradeBar](PERIODLONG)
self.Consolidate(self.crypto, Resolution.Daily, self.CustomBarHandler)
self.SetWarmUp(1*PERIODLONG, Resolution.Daily)
# create a momentum indicator over 3 days
#self.mom = self.MOMP(self.target_crypto, 3)
self.mom = self.MOM(self.target_crypto, 3)
#self.fastavg = self.EMA(self.target_crypto, 3);
self.slowmom = self.MOM(self.target_crypto, 30);
#self.sslowmom = self.ROC(self.target_crypto, 60);
self.sslowmom = self.MOM(self.target_crypto, 60);
# Plot Momentum
self.PlotIndicator(
"Indicators",
self.mom
)
# set warmup period
#self.SetWarmUp(20)
def CustomBarHandler(self, bar):
self.rollingWindow.Add(bar)
def OnData(self, data):
if not self.rollingWindow.IsReady: return
L = np.flipud(np.array([self.rollingWindow[i].Low for i in range(PERIOD)]))
self.kf = KalmanFilter(transition_matrices = [1],
observation_matrices = [1],
initial_state_mean = 0,
initial_state_covariance = 1,
observation_covariance=1,
transition_covariance=.01)
kf,_ = self.kf.filter(L)
self.Plot(self.crypto, "Price", self.Securities[self.crypto].Price)
self.Plot(self.crypto, "Kalman", kf[-1])
holdings = self.Portfolio[self.target_crypto].Quantity
price = self.Securities[self.target_crypto].Close
fastmom = self.mom.Current.Value
slowmom = self.slowmom.Current.Value
sslowmom = self.sslowmom.Current.Value
mom = sslowmom + (slowmom) + (2 * fastmom)
# buy if price closes above upper bollinger band
if holdings <= 0:
#if price > self.Bolband.UpperBand.Current.Value:
if price > kf[-1] and mom > 0:
self.SetHoldings(self.target_crypto, 1.0)
# sell if price closes below middle bollinger band
#if holdings > 0 and price < self.Bolband.MiddleBand.Current.Value:
#if holdings > 0 and price < fastavg:
if holdings >= 0:
if price < kf[-1] and mom < 0:
self.Liquidate()