Overall Statistics |
Total Trades 384 Average Win 6.45% Average Loss -5.59% Compounding Annual Return -38.130% Drawdown 82.200% Expectancy 0.016 Net Profit -36.289% Sharpe Ratio 0.652 Probabilistic Sharpe Ratio 26.744% Loss Rate 53% Win Rate 47% Profit-Loss Ratio 1.16 Alpha 1.189 Beta 2.773 Annual Standard Deviation 1.381 Annual Variance 1.907 Information Ratio 0.767 Tracking Error 1.311 Treynor Ratio 0.325 Total Fees $2830.64 Estimated Strategy Capacity $8300000.00 Lowest Capacity Asset ZO Y6RTF5MGZVOL |
# region imports from AlgorithmImports import * from datetime import datetime import math # endregionfs class InverseVolatility(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 1, 1) self.SetEndDate(2022, 12, 31) self.SetSecurityInitializer(BrokerageModelSecurityInitializer(self.BrokerageModel, FuncSecuritySeeder(self.GetLastKnownPrices))) self.volatility = {} tickers = [ Futures.Indices.VIX, Futures.Indices.SP500EMini, Futures.Indices.NASDAQ100EMini, Futures.Indices.Dow30EMini, Futures.Energies.BrentCrude, Futures.Energies.Gasoline, Futures.Energies.HeatingOil, Futures.Energies.NaturalGas, Futures.Grains.Corn, Futures.Grains.Oats, Futures.Grains.Soybeans, Futures.Grains.Wheat ] for ticker in tickers: future = self.AddFuture(ticker, extendedMarketHours=True) # 30-day standard deviation of 1-day returns roc = self.ROC(future.Symbol, 1, Resolution.Daily) self.volatility[future] = IndicatorExtensions.Of(StandardDeviation(30), roc) self.SetWarmup(31, Resolution.Daily) self.Schedule.On( self.DateRules.WeekStart(), self.TimeRules.At(10,0,0), self.Rebalance) def Rebalance(self): if self.IsWarmingUp: return sorted_by_value = sorted([kvp for kvp in self.volatility.items() if kvp[1].IsReady], key=lambda item: item[1].Current.Value) top5 = {k: v for k, v in sorted_by_value[:5]} # Sum the inverse STD of ROC inverse_sum = sum([1/std.Current.Value for std in top5.values()]) if inverse_sum == 0: return # Create Portfoliotarget for the inverse weighted STD targets = [PortfolioTarget(future.Mapped, 1/std.Current.Value/inverse_sum) for future,std in top5.items() if future.Mapped] # Liquidate if invested and no new negative news for symbol, holdings in self.Portfolio.items(): if holdings.Invested and symbol not in top5: targets.append(PortfolioTarget(symbol, 0)) #for target in targets: # self.Plot("Targets", target.Symbol.Value, target.Quantity) self.SetHoldings(targets)