Overall Statistics
Total Orders
388
Average Win
0.47%
Average Loss
-0.35%
Compounding Annual Return
42.502%
Drawdown
25.600%
Expectancy
0.832
Start Equity
100000
End Equity
208855.08
Net Profit
108.855%
Sharpe Ratio
1.171
Sortino Ratio
1.55
Probabilistic Sharpe Ratio
61.250%
Loss Rate
21%
Win Rate
79%
Profit-Loss Ratio
1.33
Alpha
0.223
Beta
0.891
Annual Standard Deviation
0.238
Annual Variance
0.057
Information Ratio
1.133
Tracking Error
0.191
Treynor Ratio
0.313
Total Fees
$468.21
Estimated Strategy Capacity
$1000000.00
Lowest Capacity Asset
OEF RZ8CR0XXNOF9
Portfolio Turnover
3.84%
#https://chat.openai.com/share/923ff83d-011b-4416-b37f-3f586510e37d


from QuantConnect.Algorithm import QCAlgorithm
from QuantConnect import Resolution

class VXXMOMENTUMPredictsStockIndexReturns(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2022, 3, 1)
        self.SetEndDate(2024, 3, 31)
        self.SetCash(100000)
        
        self.oef = "OEF"
        self.vxx = "VXX"
        self.AddEquity(self.oef, Resolution.Daily)
        self.AddEquity(self.vxx, Resolution.Daily)
        
        # Set OEF as the benchmark
        self.SetBenchmark(self.oef)

        # Parameters
        params = ['ema-slow', 'ema-fast', 'leverage_up', 'leverage_down']
        self.params = {p: int(self.GetParameter(p)) for p in params}

        # Indicators
        self.emaFast = self.EMA(self.vxx, self.params['ema-fast'])
        self.emaSlow = self.EMA(self.vxx, self.params['ema-slow'])

        # To simulate a full investment in OEF from the start
        self.initialOEFPrice = None  # This will be set on the first available price
        self.hypotheticalOEFInvestment = self.Portfolio.Cash

    def OnData(self, data):
        if not data.ContainsKey(self.vxx) or data[self.vxx] is None or data[self.vxx].Close is None:
            self.Log("VXX data is missing or incomplete.")
            return

        if not data.ContainsKey(self.oef) or data[self.oef] is None or data[self.oef].Close is None:
            self.Log("OEF data is missing or incomplete.")
            return

        vxx_close = data[self.vxx].Close
        oef_close = data[self.oef].Close
        self.PlotIndicators(vxx_close, oef_close)
        self.EvaluatePositions()

    def PlotIndicators(self, vxx_close, oef_close):
        self.Plot("My Indicators", "slow Signal", self.emaSlow.Current.Value)
        self.Plot("My Indicators", "Fast Signal", self.emaFast.Current.Value)
        self.Plot("My Indicators", "VXX", vxx_close)
        
        # Initial OEF price setting
        if self.initialOEFPrice is None:
            self.initialOEFPrice = oef_close
        
        # Hypothetical investment value
        hypotheticalValue = self.hypotheticalOEFInvestment / self.initialOEFPrice * oef_close
        
        # Plot Strategy Equity and Benchmark with two scales
        self.Plot("Strategy Equity", "Portfolio Value", self.Portfolio.TotalPortfolioValue)
        self.Plot("Strategy Equity", "Hypothetical OEF Investment", hypotheticalValue)

    def EvaluatePositions(self):
        if self.emaFast.Current.Value > self.emaSlow.Current.Value:
            self.SetHoldings(self.oef, -1.5 * self.params['leverage_up'])
        elif self.emaFast.Current.Value < self.emaSlow.Current.Value:
            self.SetHoldings(self.oef, 1.5 * self.params['leverage_down'])
        else:
            self.SetHoldings(self.oef, 1.0)