| Overall Statistics |
|
Total Orders 75651 Average Win 0.02% Average Loss -0.02% Compounding Annual Return 17.894% Drawdown 6.600% Expectancy 0.292 Start Equity 1000000 End Equity 6273642.12 Net Profit 527.364% Sharpe Ratio 1.224 Sortino Ratio 1.869 Probabilistic Sharpe Ratio 98.547% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 1.09 Alpha 0.08 Beta 0.246 Annual Standard Deviation 0.08 Annual Variance 0.006 Information Ratio 0.169 Tracking Error 0.132 Treynor Ratio 0.401 Total Fees $107860.60 Estimated Strategy Capacity $920000.00 Lowest Capacity Asset UVXY V0H08FY38ZFP Portfolio Turnover 25.03% Drawdown Recovery 350 |
from AlgorithmImports import *
from datetime import timedelta
from collections import deque
class Algo(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetCash(1000000)
self.uvxy = self.AddEquity("UVXY", Resolution.Minute).Symbol
self.qqq = self.AddEquity("QQQ", Resolution.Minute).Symbol
self.SetBenchmark("SPY")
self.benchmark_symbol = self.qqq
self.uvxy_daily_window = deque(maxlen=2)
self.Consolidate(self.uvxy, Resolution.Daily, self.UvxyDailyHandler)
self.qqq_sma_fast = self.SMA(self.qqq, 11, Resolution.Daily)
self.qqq_sma_slow = self.SMA(self.qqq, 160, Resolution.Daily)
self.mod_bull = 1.10
self.mod_bear = 0.80
self.SetPortfolioConstruction(InsightWeightingPortfolioConstructionModel())
self.SetExecution(StandardDeviationExecutionModel(4.0, 1.5, Resolution.Minute))
self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.0332))
self.Schedule.On(
self.DateRules.EveryDay(self.uvxy),
self.TimeRules.AfterMarketOpen(self.uvxy, 10),
self.ExitPositions
)
self.SetWarmUp(160, Resolution.Daily)
self.started = False
def OnData(self, data: Slice):
if len(self.uvxy_daily_window) < 2:
return
if self.Time.hour != 9 or self.Time.minute != 31:
return
if not data.ContainsKey(self.uvxy):
return
if not (self.qqq_sma_fast.IsReady and self.qqq_sma_slow.IsReady):
return
uvxy_bar = data[self.uvxy]
prev_daily_close = float(self.uvxy_daily_window[-1].Close)
modifier = self.mod_bull if self.qqq_sma_fast.Current.Value > self.qqq_sma_slow.Current.Value else self.mod_bear
short_w = -0.75 * modifier
long_w = 0.30 * modifier
short_w = max(-0.99, min(-0.01, short_w))
long_w = max( 0.01, min( 0.99, long_w))
if uvxy_bar.Open >= 1.093 * prev_daily_close:
self.SetHoldings(self.uvxy, short_w)
elif uvxy_bar.Open <= 0.982 * prev_daily_close:
self.SetHoldings(self.uvxy, long_w)
if not self.Portfolio.Invested:
self.EmitInsights(
Insight.Price(self.benchmark_symbol, timedelta(days=3),
InsightDirection.Up, weight=0.5, tag="rebalance")
)
if (not self.started) and (not self.IsWarmingUp) and (len(data.Bars) > 0):
self.started = True
def UvxyDailyHandler(self, bar: TradeBar):
self.uvxy_daily_window.append(bar)
def ExitPositions(self):
self.Liquidate(self.uvxy, tag="Morning exit")