Overall Statistics |
Total Trades 390 Average Win 10.33% Average Loss -2.18% Compounding Annual Return 57.357% Drawdown 29.600% Expectancy 1.188 Net Profit 7731.772% Sharpe Ratio 1.605 Probabilistic Sharpe Ratio 82.644% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 4.73 Alpha 0.425 Beta 0.349 Annual Standard Deviation 0.334 Annual Variance 0.112 Information Ratio 0.473 Tracking Error 0.455 Treynor Ratio 1.538 Total Fees $71872.94 Estimated Strategy Capacity $480000.00 Lowest Capacity Asset SVXY V0H08FY38ZFP |
import numpy as np from collections import deque from datetime import datetime class Quad: def __init__(self, period): self.Name = "quad" self.Time = datetime.min self.a = 0 self.b=0 self.c=0 self.IsReady = False self.time_scale=[-i-1 for i in range(period)] self.queue = deque(maxlen=period) self.period=period self.Value=0 # Update method is mandatory def Update(self, input): self.queue.appendleft(input.Close) self.IsReady=(self.period==len(self.queue)) self.Time = input.EndTime if self.IsReady: self.a,self.b,self.c=np.polyfit(self.time_scale,self.queue,2) self.Value=self.a return self.IsReady class SleepyVioletCat(QCAlgorithm): def Initialize(self): self.SetStartDate(2012, 1, 1) #self.SetEndDate(2020,5,1) self.SetCash(100000) self.AddEquity('SVXY',Resolution.Minute) res=Resolution.Daily self.uvxy=self.AddEquity('UVXY',Resolution.Daily).Symbol self.bb=self.BB(self.uvxy,int(self.GetParameter('bb')),2,res) self.sma=self.SMA(self.uvxy,4,res) self.rc=self.RC(self.uvxy,int(self.GetParameter('rc')),float(self.GetParameter('std')),res) self.trigger=False self.buy=False self.hold=False self.sell=False self.days=0 self.quad=Quad(8) self.RegisterIndicator("UVXY", self.quad, res) self.SetWarmUp(timedelta(15)) self.SetBenchmark('SVXY') #self.AddFuture(Futures.Indices.VIX, Resolution.Minute).SetFilter(TimeSpan.Zero, TimeSpan.FromDays(120)) #self.future=False def OnData(self, data): #self.Log(self.Portfolio['SVXY'].UnrealizedProfitPercent) ''' for chain in data.FutureChains.Values: pool=sorted(chain.Contracts.Values,key=lambda x: x.Expiry) if len(pool)>2: vx0,vx1,vx2 = pool[:3] if vx0.LastPrice>vx1.LastPrice and vx2.LastPrice<vx1.LastPrice: self.future=True ''' if self.bb.IsReady and data.ContainsKey(self.uvxy) and self.sma.IsReady and self.quad.IsReady and data[self.uvxy]!=None: self.days=self.days+1 vix=data[self.uvxy].Close k=self.rc.Slope.Current.Value/vix if self.rc.UpperChannel.Current.Value<vix: self.trigger=True #self.future=False if self.trigger and self.sma.Current.Value>vix and self.quad.a/vix<float(self.GetParameter('quad')) and float(self.GetParameter('pos'))<abs(self.quad.b/self.quad.a): self.buy=True if self.hold and (vix<(self.bb.MiddleBand.Current.Value-self.bb.StandardDeviation.Current.Value)): self.sell=True if self.buy and data.ContainsKey('SVXY'): if not self.hold: self.Log('uvxy:'+str(self.uvxy)) self.Log('channel:'+str(0.5*(self.rc.UpperChannel.Current.Value-self.rc.LowerChannel.Current.Value)/vix)) self.Log('normalized a:'+str(self.quad.a/vix)) self.Log('normalized b:'+str(self.quad.b/vix)) self.SetHoldings('SVXY',1) self.trigger=False self.buy=False self.hold=True if data.ContainsKey('SVXY') and (self.sell or self.Portfolio['SVXY'].UnrealizedProfitPercent<-float(self.GetParameter('loss'))) and self.days>385*1 and not self.buy: self.Log('profit' if self.Portfolio['SVXY'].UnrealizedProfitPercent>0 else 'loss') self.SetHoldings('SVXY',0) self.hold=False self.sell=False self.days=0