Overall Statistics |
Total Orders 359 Average Win 0.65% Average Loss -0.32% Compounding Annual Return 16.270% Drawdown 13.900% Expectancy 0.472 Start Equity 100000000 End Equity 124605993.92 Net Profit 24.606% Sharpe Ratio 0.484 Sortino Ratio 0.569 Probabilistic Sharpe Ratio 40.216% Loss Rate 51% Win Rate 49% Profit-Loss Ratio 2.04 Alpha -0.078 Beta 1.126 Annual Standard Deviation 0.137 Annual Variance 0.019 Information Ratio -0.844 Tracking Error 0.073 Treynor Ratio 0.059 Total Fees $63330.03 Estimated Strategy Capacity $6600000.00 Lowest Capacity Asset VX YK79X28CKDEX Portfolio Turnover 6.14% |
from AlgorithmImports import * class InverseVolatilityRankAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2023, 3, 1) # Set Start Date self.set_cash(100000000) # For a large future universe, the fund needed would be large for contract in ["VX", "ES", "NQ", "YM", "B", "RB", "HO", "NG"]: future = self.add_future(contract) self.schedule.on(self.date_rules.every(DayOfWeek.MONDAY), self.time_rules.at(9, 31), self.rebalance) def rebalance(self): df = self.history(list(set(x.canonical for x in self.securities.keys())), 22, Resolution.DAILY).close.droplevel([0]).unstack(0).pct_change().dropna() inv_vol = 1. / df.std(axis=0, ddof=1) inv_vol /= np.sum(inv_vol) for contract, weight in inv_vol.items(): self.set_holdings(self.securities[contract].mapped, weight / 10) def on_symbol_changed_events(self, symbols_changed): for symbol, changed_event in symbols_changed.items(): quantity = self.portfolio[changed_event.old_symbol].quantity self.liquidate(changed_event.old_symbol) if changed_event.new_symbol in self.securities: self.market_order(changed_event.new_symbol, quantity // self.securities[symbol].symbol_properties.contract_multiplier)