Overall Statistics |
Total Trades 593 Average Win 1.86% Average Loss -2.46% Compounding Annual Return -6.509% Drawdown 52.300% Expectancy -0.033 Net Profit -30.081% Sharpe Ratio -0.14 Probabilistic Sharpe Ratio 0.402% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.76 Alpha -0.11 Beta 0.759 Annual Standard Deviation 0.25 Annual Variance 0.062 Information Ratio -0.634 Tracking Error 0.211 Treynor Ratio -0.046 Total Fees $615.39 |
import numpy as np import pandas as pd from datetime import datetime, timedelta class UncoupledTransdimensionalAntennaArray(QCAlgorithm): def Initialize(self): stopMarketTicket = None stopMarketFillTime = datetime.min highestPrice = 0 self.SetStartDate(2015, 1, 1) # Set Start Date self.SetCash(10000) # Set Strategy Cash self.asset = self.AddEquity("ZIV", Resolution.Minute) self.asset.SetDataNormalizationMode(DataNormalizationMode.Raw) # define the n period indicators with indicator constructors. self.rocfiveDay = RateOfChange(5) self.rocfiveDay.Updated += self.ROCFiveDayUpdated self.rocfiveDayWindow = RollingWindow[IndicatorDataPoint](6) # for volatility. self.roc1 = RateOfChange(1) self.std = IndicatorExtensions.Of(StandardDeviation(30), self.roc1) # for stop loss self.atr = self.ATR("ZIV", 20, Resolution.Daily) history = self.History("ZIV", 20, Resolution.Daily) for bar in history: self.atr.Update(bar) self.rocfiveDay.Update(bar.EndTime, bar.Close) # voltaility calculator. one day return. self.roc1.Update(bar.EndTime, bar.Close) # this is for listening to order status self.lastOrderEvent = None self.ticket = None # Flag for position status # define portfolio volatility self.target_portfolio_sigma = 0.25 self.Schedule.On(self.DateRules.EveryDay("ZIV"), self.TimeRules.BeforeMarketClose("ZIV", 5), self.Rebalance) def Rebalance(self): # this is to warm up indicators. if not self.rocfiveDay.IsReady or not self.roc1.IsReady or not self.atr.IsReady: return self.rocfiveDay.Update(self.Time, self.Securities["ZIV"].Close) self.roc1.Update(self.Time, self.Securities["ZIV"].Close) # wait is indicators are not ready. if not self.rocfiveDayWindow.IsReady: return ''' # ATR for Stop Loss. if not self.atr.IsReady: history = self.History("ZIV", 20, Resolution.Daily) for bar in history: self.atr.Update(bar.EndTime, bar.Close) self.atr.Update(self.Time, self.Securities["ZIV"].Close) ''' long_signal_1 = self.rocfiveDayWindow[0] > self.rocfiveDayWindow[1] if not self.Portfolio.Invested: if long_signal_1 == True: volatility = self.std.Current.Value * np.sqrt(252) # get vol. self.Debug("Volatility " + str(volatility)) weight = self.target_portfolio_sigma / volatility # get weight. #quantity = (self.Portfolio.TotalPortfolioValue * weight)/self.Securities["ZIV"].Close # get quantity. quantity = self.Portfolio.TotalPortfolioValue / self.Securities["ZIV"].Close self.ticket = self.MarketOrder("ZIV", quantity) #self.MarketOrder("ZIV", quantity) self.stopMarketTicket = self.StopMarketOrder("ZIV", -quantity, 0.9 * self.Securities["ZIV"].Close) ## TODO update to 2 times ATR self.Debug("Volatility " + str(volatility)) self.Debug("Portfolio Size " + str(self.Portfolio.TotalPortfolioValue )) self.Debug("Quantity " + str(quantity)) # self.Log() # add log messaging elif self.ticket is not None and (self.UtcTime - self.ticket.Time).days < 3: ## to update stop loss. if self.Securities["ZIV"].Close > self.highestPrice: self.highestPrice = self.Securities["ZIV"].Close # save the new highestPrice updateFields = UpdateOrderFields() updateFields.StopPrice = self.highestPrice * 0.9 # TODO self.highestPrice - 2 * self.atr.Current.Value ## updating stop price self.stopMarketTicket.Update(updateFields) self.Debug("ZIV: " + str(self.highestPrice) + " Stop: " + str(updateFields.StopPrice)) elif self.ticket is not None and self.UtcTime >= self.ticket.Time + timedelta(days = 3): self.Liquidate("ZIV") self.highestPrice = 0 self.ticket = None def ROCFiveDayUpdated(self, sender, updated): self.rocfiveDayWindow.Add(updated)