Overall Statistics |
Total Orders 239 Average Win 0.32% Average Loss -0.13% Compounding Annual Return 1.022% Drawdown 2.700% Expectancy 0.141 Start Equity 1000000 End Equity 1024007.2 Net Profit 2.401% Sharpe Ratio -0.404 Sortino Ratio -0.548 Probabilistic Sharpe Ratio 12.947% Loss Rate 67% Win Rate 33% Profit-Loss Ratio 2.48 Alpha -0.004 Beta -0.021 Annual Standard Deviation 0.017 Annual Variance 0 Information Ratio -0.833 Tracking Error 0.203 Treynor Ratio 0.338 Total Fees $590.33 Estimated Strategy Capacity $2800000000.00 Lowest Capacity Asset CL XON0163K9O75 Portfolio Turnover 1.41% |
from AlgorithmImports import * from QuantConnect.DataSource import * class USFuturesSecurityMasterDataClassicAlgorithm (QCAlgorithm): threshold = 0.01 # 1% def initialize(self) -> None: self.set_cash(1000000) self.set_start_date(2019, 2, 1) self.set_end_date(2021, 6, 1) # Requesting data self.continuous_contract = self.add_future(Futures.Energies.CRUDE_OIL_WTI, data_normalization_mode = DataNormalizationMode.BACKWARDS_RATIO, data_mapping_mode = DataMappingMode.OPEN_INTEREST, contract_depth_offset = 0) self.continuous_contract_symbol = self.continuous_contract.symbol # Historical data history = self.history(self.continuous_contract_symbol, 500, Resolution.MINUTE) self.debug(f"We got {len(history)} items from our history request") self.sma = self.SMA(self.continuous_contract_symbol, 10, Resolution.DAILY) if not history.empty: for time, row in history.droplevel(0).loc[self.continuous_contract_symbol].iterrows(): self.sma.update(IndicatorDataPoint(time, row.close)) def on_data(self, slice: Slice) -> None: # Accessing data for symbol, changed_event in slice.symbol_changed_events.items(): old_symbol = changed_event.old_symbol new_symbol = changed_event.new_symbol tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}" quantity = self.portfolio[old_symbol].quantity # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract self.liquidate(old_symbol, tag = tag) if quantity != 0: self.market_order(new_symbol, quantity, tag = tag) self.log(tag) mapped_symbol = self.continuous_contract.mapped if not (slice.bars.contains_key(self.continuous_contract_symbol) and self.sma.is_ready and mapped_symbol): return if slice.bars[self.continuous_contract_symbol].price > self.sma.current.value * (1+self.threshold) and not self.portfolio[mapped_symbol].is_long: self.market_order(mapped_symbol, 1) elif slice.bars[self.continuous_contract_symbol].price < self.sma.current.value * (1-self.threshold) and not self.portfolio[mapped_symbol].is_short: self.market_order(mapped_symbol, -1)