Overall Statistics |
Total Trades 9 Average Win 10.38% Average Loss -1.77% Compounding Annual Return 14.205% Drawdown 13.700% Expectancy 2.427 Net Profit 49.063% Sharpe Ratio 1.038 Probabilistic Sharpe Ratio 48.491% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 5.85 Alpha 0.127 Beta -0.03 Annual Standard Deviation 0.119 Annual Variance 0.014 Information Ratio -0.077 Tracking Error 0.237 Treynor Ratio -4.15 Total Fees $18.26 |
#btc = self.Portfolio.CashBook["BTC"].Amount # Your New Python File
import numpy as np class SimpleBreakoutExample(QCAlgorithm): def Initialize(self): # Set the cash for backtest self.SetCash(100000) # self.AddCrypto("BTCUSD", Resolution.Hour, Market.GDAX) # Start and end dates for backtest self.SetStartDate(2017,9,1) self.SetEndDate(2020,9,1) # Add asset self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol # Lookback length for b/o (in days) self.lookback = 20 # Upper/lower limit for lookback length self.ceiling, self.floor = 30, 10 # Price offset for stop order self.initialStopRisk = 0.98 self.trailingStopRisk = 0.9 # Schedule function 20 minutes after every market open self.Schedule.On(self.DateRules.EveryDay(self.symbol), \ self.TimeRules.AfterMarketOpen(self.symbol, 20), \ Action(self.EveryMarketOpen)) def OnData(self, data): # Plot security's price self.Plot("Data Chart", self.symbol, self.Securities[self.symbol].Close) def EveryMarketOpen(self): # Dynamically determine lookback length based on 30 day volatility change rate close = self.History(self.symbol, 31, Resolution.Daily)["close"] todayvol = np.std(close[1:31]) yesterdayvol = np.std(close[0:30]) deltavol = (todayvol - yesterdayvol) / todayvol self.lookback = round(self.lookback * (1 + deltavol)) # Account for upper/lower limit of lockback length if self.lookback > self.ceiling: self.lookback = self.ceiling elif self.lookback < self.floor: self.lookback = self.floor # List of daily highs self.high = self.History(self.symbol, self.lookback, Resolution.Daily)["high"] # Buy in case of breakout if not self.Securities[self.symbol].Invested and \ self.Securities[self.symbol].Close >= max(self.high[:-1]): self.SetHoldings(self.symbol, 1) self.breakoutlvl = max(self.high[:-1]) self.highestPrice = self.breakoutlvl # Create trailing stop loss if invested if self.Securities[self.symbol].Invested: # If no order exists, send stop-loss if not self.Transactions.GetOpenOrders(self.symbol): self.stopMarketTicket = self.StopMarketOrder(self.symbol, \ -self.Portfolio[self.symbol].Quantity, \ self.initialStopRisk * self.breakoutlvl) # Check if the asset's price is higher than highestPrice & trailing stop price not below initial stop price if self.Securities[self.symbol].Close > self.highestPrice and \ self.initialStopRisk * self.breakoutlvl < self.Securities[self.symbol].Close * self.trailingStopRisk: # Save the new high to highestPrice self.highestPrice = self.Securities[self.symbol].Close # Update the stop price updateFields = UpdateOrderFields() updateFields.StopPrice = self.Securities[self.symbol].Close * self.trailingStopRisk self.stopMarketTicket.Update(updateFields) # Print the new stop price with Debug() self.Debug(updateFields.StopPrice) # Plot trailing stop's price self.Plot("Data Chart", "Stop Price", self.stopMarketTicket.Get(OrderField.StopPrice))