Overall Statistics
Total Trades
132
Average Win
1.47%
Average Loss
-0.77%
Compounding Annual Return
18.576%
Drawdown
4.300%
Expectancy
0.983
Net Profit
37.808%
Sharpe Ratio
1.881
Probabilistic Sharpe Ratio
89.574%
Loss Rate
32%
Win Rate
68%
Profit-Loss Ratio
1.91
Alpha
0
Beta
0
Annual Standard Deviation
0.068
Annual Variance
0.005
Information Ratio
1.881
Tracking Error
0.068
Treynor Ratio
0
Total Fees
$132.00
Estimated Strategy Capacity
$850000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
from AlgorithmImports import *

class VIXPredictsStockIndexReturns(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)   
        
        self.SetCash(5000)     
        self.ticker="SPY"     
        self.current_state=0
        self.trailing_stop=0.05
        self.symbol = self.AddEquity(self.ticker, Resolution.Daily).Symbol
        self.vix = self.AddEquity("SSG", Resolution.Hour).Symbol
        x=35
        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,10), 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=5
        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