Overall Statistics |
Total Trades 260 Average Win 1.34% Average Loss -0.94% Compounding Annual Return 5.213% Drawdown 13.900% Expectancy 0.226 Net Profit 29.450% Sharpe Ratio 0.59 Probabilistic Sharpe Ratio 15.491% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 1.42 Alpha 0.047 Beta -0.007 Annual Standard Deviation 0.078 Annual Variance 0.006 Information Ratio -0.399 Tracking Error 0.145 Treynor Ratio -6.192 Total Fees $260.00 |
import numpy as np import pandas as pd import math class NadionHorizontalCircuit(QCAlgorithm): ## order ticket for stop order stopMarketTicket = None stopMarketFillTime = datetime.min highestPrice = 0 prevClose = 0 def Initialize(self): self.SetStartDate(2015, 1, 2) # Set Start Date self.SetEndDate(2020, 1, 28) self.SetCash(10000) # Set Strategy Cash self.ziv = self.AddEquity("ZIV", Resolution.Daily) self.ziv.SetDataNormalizationMode(DataNormalizationMode.Raw) self.roc = self.ROC("ZIV", 5, Resolution.Daily) #self.SetWarmUp(5) self.lastOrderEvent = None ## this is for listening to order status # get ATR to use for stop loss. self.atr = self.ATR("ZIV", 20, Resolution.Daily) # get volatility self.lookback = 30 self.SetWarmUp(self.lookback) self.roc1 = self.ROC("ZIV", 1, Resolution.Daily) self.std = IndicatorExtensions.Of(StandardDeviation(self.lookback), self.roc1) # define portfolio volatility self.target_portfolio_sigma = 0.12 def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' if self.IsWarmingUp: return # check that 1 day have passed since we hit the stop loss. if(self.Time - self.stopMarketFillTime).days < 2: return ## this means wait if not self.Portfolio.Invested: if self.roc.Current.Value > 0: volatility = self.std.Current.Value * np.sqrt(252) # calculate quantity to trade based on the targeted vol weight = self.target_portfolio_sigma / volatility quantity = (self.Portfolio.TotalPortfolioValue * weight)/self.Securities["ZIV"].Close self.MarketOrder("ZIV", quantity) # create stop loss and track the ticket self.stopMarketTicket = self.StopMarketOrder("ZIV", -quantity, self.Securities["ZIV"].Close - 2 * self.atr.Current.Value) else: if self.roc.Current.Value > 0: # check if the current price is higher than the highest closing price since we entered position if self.Securities["ZIV"].Close > self.highestPrice: # save the new highestPrice self.highestPrice = self.Securities["ZIV"].Close updateFields = UpdateOrderFields() updateFields.StopPrice = self.highestPrice - 2 * self.atr.Current.Value ## updating stop price self.stopMarketTicket.Update(updateFields) self.Debug("ZIV: " + str(self.highestPrice) + " Stop: " + str(updateFields.StopPrice)) else: self.Liquidate("ZIV") self.highestPrice = 0 def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return ## if no orders were filled then wait and dont worry. # this checks that the stop order ticket was submitted if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: self.stopMarketFillTime = self.Time self.Debug(self.stopMarketFillTime)