| Overall Statistics |
|
Total Orders 1033 Average Win 0.32% Average Loss -0.35% Compounding Annual Return 15.971% Drawdown 9.600% Expectancy 0.347 Start Equity 100000 End Equity 199040.41 Net Profit 99.040% Sharpe Ratio 0.999 Sortino Ratio 1.184 Probabilistic Sharpe Ratio 71.297% Loss Rate 30% Win Rate 70% Profit-Loss Ratio 0.92 Alpha 0.085 Beta 0.023 Annual Standard Deviation 0.087 Annual Variance 0.008 Information Ratio -0.015 Tracking Error 0.195 Treynor Ratio 3.751 Total Fees $1108.15 Estimated Strategy Capacity $5600000.00 Lowest Capacity Asset VXZB WRBPJAJZ2Q91 Portfolio Turnover 0.80% |
from AlgorithmImports import *
from scipy.optimize import minimize
class LeverageEtfRiskParity(QCAlgorithm):
def initialize(self):
self.set_start_date(2020, 1, 1)
self.set_cash(100000)
self.symbols = [self.add_equity(ticker, data_normalization_mode=DataNormalizationMode.RAW).symbol for ticker in ["TQQQ", "SVXY", "VXZ", "TMF", "EDZ", "UGL"]]
self.schedule.on(self.date_rules.week_start(), self.time_rules.at(8, 0), self.rebalance)
def rebalance(self):
ret = self.history(self.symbols, 253, Resolution.DAILY).close.unstack(0).pct_change().dropna()
x0 = [1/ret.shape[1]] * ret.shape[1]
constraints = {"type": "eq", "fun": lambda w: np.sum(w) - 1}
bounds = [(0, 1)] * ret.shape[1]
opt = minimize(lambda w: 0.5 * (w.T @ ret.cov() @ w) - np.array(x0) @ w, x0=x0, constraints=constraints, bounds=bounds, tol=1e-8, method="SLSQP")
self.set_holdings([PortfolioTarget(symbol, weight) for symbol, weight in zip(ret.columns, opt.x)])