| Overall Statistics |
|
Total Trades 258 Average Win 1.36% Average Loss -0.96% Compounding Annual Return 5.127% Drawdown 12.200% Expectancy 0.222 Net Profit 28.912% Sharpe Ratio 0.584 Probabilistic Sharpe Ratio 15.208% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.42 Alpha 0.046 Beta -0.009 Annual Standard Deviation 0.077 Annual Variance 0.006 Information Ratio -0.405 Tracking Error 0.144 Treynor Ratio -5.083 Total Fees $258.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
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)
# 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:
# get historical return data and calculate volatility
history_data = self.History(self.Symbol("ZIV"),self.lookback, Resolution.Daily).close.unstack(level=0)
history_data = history_data['ZIV']
change = history_data.pct_change().dropna()
volatility = change.std(ddof=1)
volatility = volatility * 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")
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)class Volatility(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 1, 2) # Set Start Date
self.SetCash(10000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
self.ziv = self.AddEquity("ZIV", Resolution.Daily)
self.ziv.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.roc = self.ROC("ZIV", 5, Resolution.Daily)
self.SetWarmUp(5)
self.Schedule.On(self.DateRules.EveryDay("ZIV"), self.TimeRules.BeforeMarketClose("ZIV", 5), self.trade_signal)
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
'''
if self.roc.Current.Value > 0:
self.SetHoldings("ZIV",1)
else:
self.Liquidate("ZIV")
'''
def trade_signal(self):
if self.roc.Current.Value > 0 and not self.portfolio.Invested:
self.SetHoldings("ZIV",1)
else:
self.Liquidate("ZIV")