Overall Statistics |
Total Trades 47 Average Win 7.11% Average Loss -14.04% Compounding Annual Return -51.169% Drawdown 70.800% Expectancy -0.149 Net Profit -51.265% Sharpe Ratio -0.545 Probabilistic Sharpe Ratio 3.066% Loss Rate 43% Win Rate 57% Profit-Loss Ratio 0.51 Alpha -0.285 Beta -0.214 Annual Standard Deviation 0.598 Annual Variance 0.358 Information Ratio -0.745 Tracking Error 0.697 Treynor Ratio 1.522 Total Fees $0.00 |
class AdvancedBB(QCAlgorithm): # Order ticket for our stop order, Datetime when stop order was last hit stopMarketTicket = None stopMarketOrderFillTime = datetime.min fill_price = 0 highestPrice = 0 lowestPrice = 0 stoplosspctlong = 0.97 stoplosspctshort = 1.01 def Initialize(self): self.SetStartDate(2020, 1, 1) #Set Start Date self.SetEndDate(2020, 12, 31) #Set End Date self.SetCash(2000) #Set Strategy Cash self.SetBrokerageModel(BrokerageName.OandaBrokerage) # define Cfd we want to trade on # for example NATGAS self.symbol = "NATGASUSD" self.AddCfd(self.symbol, Resolution.Minute, Market.Oanda) # Set window self.window = RollingWindow[QuoteBar](3) # create a bollinger band self.Bolband = self.BB(self.symbol, 20,2, MovingAverageType.Simple, Resolution.Minute) self.Bolband.Updated += self.BolbandUpdated self.BolbandWin = RollingWindow[IndicatorDataPoint](5) # set warmup period self.SetWarmUp(20) def BolbandUpdated(self, sender, updated): '''Adds updated values to rolling window''' self.BolbandWin.Add(updated) def OnData(self, data): if (self.Time - self.stopMarketOrderFillTime).days < 15: return self.window.Add(data[self.symbol]) if not (self.window.IsReady and self.BolbandWin.IsReady): return currentprice = self.window[0].Close previousprice = self.window[1].Close currentlowerband = self.Bolband.LowerBand.Current.Value currentmiddleband = self.Bolband.MiddleBand.Current.Value currentupperband = self.Bolband.UpperBand.Current.Value available = (self.Portfolio.Cash/currentprice)*1 # # LONG TRANSACTIONS # ############################################## # # open LONG position # if not self.Portfolio.Invested: # if self.IsMarketOpen(self.symbol): # if currentprice < currentlowerband: # self.stopMarketTicket = self.StopMarketOrder(self.symbol, available, self.stoplosspctlong * currentprice) # else: # Check if the price is higher that highestPrice. # if currentprice > self.highestPrice: # Save the new high to highestPrice; then update the stop price to % of highestPrice # self.highestPrice = currentprice # updateFields = UpdateOrderFields() # updateFields.StopPrice = self.highestPrice * self.stoplosspctlong # self.stopMarketTicket.Update(updateFields) # Print the new stop price with Debug() # self.Debug(str(self.symbol) + str(self.highestPrice) + " Stop (long): " + str(updateFields.StopPrice)) # close LONG position # if self.Portfolio[self.symbol].Invested and self.IsMarketOpen(self.symbol): # if currentprice < self.Bolband.UpperBand.Current.Value and self.fill_price > currentprice: # self.Liquidate() # SHORT TRANSACTIONS ############################################## # open SHORT position if not self.Portfolio[self.symbol].Invested: if self.IsMarketOpen(self.symbol): if currentprice < currentupperband and previousprice >= currentupperband: self.stopMarketTicket = self.StopMarketOrder(self.symbol, round(-available), self.stoplosspctshort * currentprice) else: #1. Check if the price is lower that lowestPrice. if currentprice < self.lowestPrice: # Save the new low to lowestPrice; then update the stop price to % of lowestPrice self.lowestPrice = currentprice updateFields = UpdateOrderFields() updateFields.StopPrice = self.lowestPrice * self.stoplosspctshort self.stopMarketTicket.Update(updateFields) # Print the new stop price with Debug() self.Debug(str(self.symbol) + str(self.lowestPrice) + " Stop (short): " + str(updateFields.StopPrice)) # close SHORT position if self.Portfolio[self.symbol].Invested and self.IsMarketOpen(self.symbol): if currentprice <= currentlowerband and currentprice >= previousprice: self.Liquidate() def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: self.stopMarketOrderFillTime = self.Time self.fill_price = orderEvent.FillPrice
from QuantConnect.Indicators import * import numpy as np from decimal 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): self.SetStartDate(2020, 1, 1) #Set Start Date self.SetEndDate(2021, 1, 11) #Set End Date self.SetCash(1000) #Set Strategy Cash self.SetBrokerageModel(BrokerageName.OandaBrokerage) # define Cfd we want to trade on # for example NATGAS self.target_cfd = "NATGASUSD" self.AddCfd(self.target_cfd, Resolution.Hour, Market.Oanda) # Set window self.window = RollingWindow[QuoteBar](3) # create a bollinger band self.Bolband = self.BB(self.target_cfd, 20, 2, MovingAverageType.Simple, Resolution.Hour) self.Bolband.Updated += self.BolbandUpdated self.BolbandWin = RollingWindow[IndicatorDataPoint](5) # set warmup period self.SetWarmUp(20) def BolbandUpdated(self, sender, updated): '''Adds updated values to rolling window''' self.BolbandWin.Add(updated) def OnData(self, data): self.window.Add(data[self.target_cfd]) if not (self.window.IsReady and self.BolbandWin.IsReady): return holdings = self.Portfolio[self.target_cfd].Quantity currentprice = self.window[0].Close previousprice = self.window[1].Close previouspreviousprice = self.window[2].Close currentlowerband = self.Bolband.LowerBand.Current.Value currentmiddleband = self.Bolband.MiddleBand.Current.Value lowerpctline = self.Bolband.MiddleBand.Current.Value - ((self.Bolband.MiddleBand.Current.Value - self.Bolband.LowerBand.Current.Value)* 0.30) selltrigger1 = self.Bolband.UpperBand.Current.Value - ((self.Bolband.UpperBand.Current.Value - self.Bolband.MiddleBand.Current.Value) * (0.30)) buy_below_lowerband = (previousprice <= self.Bolband.LowerBand.Current.Value) and (currentprice > self.Bolband.LowerBand.Current.Value) if holdings <= 1: # if the previous price is lower or the same as the current lower band and the price before the previousprice is smaller and the current price is more than the current lower band then buy if previousprice <= currentlowerband and currentprice > currentlowerband and currentprice < currentmiddleband: self.SetHoldings(self.target_cfd, 1) elif previousprice <= lowerpctline and currentprice > lowerpctline and currentprice < currentmiddleband: self.SetHoldings(self.target_cfd, 1) if holdings > 0: # sell when the previous price is above the upper band and the current price is below the upperband - triggered after steep rise in price if previousprice >= self.Bolband.UpperBand.Current.Value and currentprice < self.Bolband.UpperBand.Current.Value: self.Liquidate() #sell when the previous price is a 25 % below the upper band and the current price is below that point - triggered after small increase in price elif previouspreviousprice >= previousprice and previousprice > selltrigger1 and currentprice <= selltrigger1: self.Liquidate() elif buy_below_lowerband: if currentprice == self.Bolband.MiddleBand.Current.Value: self.Liquidate()