Overall Statistics
Total Trades
352
Average Win
1.27%
Average Loss
-0.32%
Compounding Annual Return
64.963%
Drawdown
3.600%
Expectancy
2.325
Net Profit
135.297%
Sharpe Ratio
5.56
Probabilistic Sharpe Ratio
100%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
3.99
Alpha
0
Beta
0
Annual Standard Deviation
0.075
Annual Variance
0.006
Information Ratio
5.56
Tracking Error
0.075
Treynor Ratio
0
Total Fees
$352.00
Estimated Strategy Capacity
$2500000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
from AlgorithmImports import *

class VIXPredictsStockIndexReturns(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)   
        
        self.SetCash(1000)     
        self.ticker="SPY"     
        self.current_state=0
        self.trailing_stop=0.12
        self.symbol = self.AddEquity(self.ticker, Resolution.Daily).Symbol
        self.vix = self.AddEquity("SSG", Resolution.Hour).Symbol
        x=9
        self.SetWarmUp(x)
        self.period =x
        self.data = RollingWindow[float](self.period)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        hist = self.History([self.vix], self.period, Resolution.Hour)
        for close in hist.loc[self.vix]['close']:
            self.data.Add(close)
        self.Schedule.On(self.DateRules.EveryDay(self.ticker), self.TimeRules.AfterMarketOpen(self.ticker,30), self.EveryDayAfterMarketOpen)

    def EveryDayAfterMarketOpen(self):
        self.turn_trading_on = True
    def OnData(self, data):
        if self.IsWarmingUp != False:
            return
        holdings = self.Portfolio[self.ticker].Quantity
        price = self.Securities[self.ticker].Close
        quantity=2
        symbol_obj = self.Symbol(self.vix)
        if symbol_obj in data.Keys:
            if data[symbol_obj]:
                price = data[symbol_obj].Value
                if price != 0:
                    self.data.Add(price)
        
        if self.data.IsReady:
            closes = [x for x in self.data]
            price = closes[0]
            vix_closes = [x for x in self.data][1:]
            if holdings<=0:
                if price < np.percentile(vix_closes, 10):
                    self.MarketOrder(self.ticker, quantity)
                    stopPrice = round((1-self.trailing_stop)*self.Securities[self.ticker].Price,2)
                    self.stopTicket = self.StopMarketOrder(self.symbol, quantity, stopPrice,'Exited using Sell Stop')
                    self.stopTargetPrice = self.Securities[self.ticker].Price
            else:
                if self.Securities[self.ticker].Price < self.stopTargetPrice and self.stopTargetPrice!=0:
                    updateFields = UpdateOrderFields()
                    updateFields.StopPrice = round(self.Securities[self.ticker].Price*(1+self.trailing_stop),2)
                    self.stopTicket.Update(updateFields)
                    self.stopTargetPrice = self.Securities[self.ticker].Price           
            if holdings>0:
                if price > np.percentile(vix_closes, 90):
                    self.Liquidate()

    def update_stop(self, buy_sym, sell_sym):
        if self.Securities[buy_sym].Price > self.stopTargets[buy_sym] and self.stopTargets[buy_sym]!=0:
            updateFields = UpdateOrderFields()
            updateFields.StopPrice = round(self.Securities[buy_sym].Price*(1-self.trailing_stop),2)
            self.stopTickets[buy_sym].Update(updateFields)
            self.stopTargets[buy_sym] = self.Securities[buy_sym].Price