Overall Statistics |
Total Trades 250 Average Win 0.43% Average Loss -0.12% Compounding Annual Return 42.904% Drawdown 4.700% Expectancy 2.597 Net Profit 47.305% Sharpe Ratio 1.383 Loss Rate 21% Win Rate 79% Profit-Loss Ratio 3.54 Alpha 43.952 Beta -3174.121 Annual Standard Deviation 0.19 Annual Variance 0.036 Information Ratio 1.31 Tracking Error 0.19 Treynor Ratio 0 Total Fees $0.00 |
from QuantConnect.Indicators import * import decimal as d ### <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. ### class BollingerBreakoutAlgorithm(QCAlgorithm): def Initialize(self): ##################### # Backtest Settings # ##################### self.SetStartDate(2016, 6, 1) # Set Start Date self.SetEndDate(2017, 7, 1) # Set End Date self.SetCash(10000) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.GDAX) ########################### # Configurable parameters # ########################### self.target_crypto = "BTCUSD" # Can be ETHUSD, LTCUSD, BTCUSD, or BCCUSD self.indicator_name = "bollinger" # bollinger or momentum self.warmup_lookback = 20 # Number of time resolution to load self.time_resolution = Resolution.Minute # Resolution of periods/data to use # For bollinger self.moving_average_type = MovingAverageType.Exponential # See https://github.com/QuantConnect/Lean/blob/bc9af8784b02715000a2030e9757ef63b484378e/Indicators/MovingAverageType.cs self.bollinger_period = 20 self.k = 2 # For momentum self.momentum_period = 5 ############################ # Indicators and processes # ############################ # Add Symbol self.AddCrypto(self.target_crypto, self.time_resolution) if self.indicator_name == "bollinger": # Create bollinger band self.Bolband = self.BB(self.target_crypto, self.bollinger_period, self.k, self.moving_average_type, self.time_resolution) # Plot Bollinger Band self.PlotIndicator( "Indicators", self.Bolband.LowerBand, self.Bolband.MiddleBand, self.Bolband.UpperBand, ) elif self.indicator_name == "momentum": # Create a momentum indicator over 3 days self.mom = self.MOM(self.target_crypto, self.momentum_period) # Plot Momentum self.PlotIndicator( "Indicators", self.mom ) # Pump historical data into the indicators before algo start self.SetWarmUp(self.warmup_lookback,self.time_resolution) def OnData(self, data): holdings = self.Portfolio[self.target_crypto].Quantity last_price = self.Securities[self.target_crypto].Close ask_price = self.Securities[self.target_crypto].AskPrice bid_price = self.Securities[self.target_crypto].BidPrice amount = self.Portfolio.TotalPortfolioValue / last_price # Check to see if there is an open order and if it is taking too long to fill. Check to see if the ask moved # If the ask moved by > 1%, then adjust the price to the new bid/ask price. Don't make another order while there are open orders if len(self.Transactions.GetOpenOrders(self.target_crypto)) > 0: open_order = self.Transactions.GetOpenOrders(self.target_crypto)[0] self.Debug("Updating order price") if float(open_order.Price - last_price) > abs(float(open_order.Price)*.01): updateOrderFields = UpdateOrderFields() updateOrderFields.LimitPrice = last_price print("ask_price: %s bid_price: %s " % (ask_price,bid_price)) updateOrderFields.LimitPrice = ask_price if open_order.Direction > 0 else bid_price self.Transactions.GetOrderTicket(open_order.Id).Update(updateOrderFields) return if self.indicator_name == "bollinger": # buy if price closes above upper bollinger band if holdings == 0 and last_price > self.Bolband.LowerBand.Current.Value: limitOrderTicket = self.LimitOrder(self.target_crypto, amount, ask_price) # sell if price closes below middle bollinger band elif holdings > 0 and last_price < self.Bolband.MiddleBand.Current.Value: limitOrderTicket = self.LimitOrder(self.target_crypto, -holdings, bid_price) elif self.indicator_name == "momentum": mom = self.mom.Current.Value return def OnOrderEvent(self, orderEvent): order = self.Transactions.GetOrderById(orderEvent.OrderId) self.Debug("{0}: {1}: {2}".format(self.Time, order.Type, orderEvent))