Overall Statistics |
Total Orders 557 Average Win 2.55% Average Loss -1.37% Compounding Annual Return 49.678% Drawdown 56.900% Expectancy 0.219 Start Equity 100000000 End Equity 181742434.9 Net Profit 81.742% Sharpe Ratio 0.915 Sortino Ratio 1.057 Probabilistic Sharpe Ratio 35.907% Loss Rate 57% Win Rate 43% Profit-Loss Ratio 1.86 Alpha -0.18 Beta 5.834 Annual Standard Deviation 0.71 Annual Variance 0.504 Information Ratio 0.814 Tracking Error 0.623 Treynor Ratio 0.111 Total Fees $500387.55 Estimated Strategy Capacity $3400000.00 Lowest Capacity Asset NG YLCMOZLFS05D Portfolio Turnover 36.50% |
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 / 2) 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)