| 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)