Overall Statistics |
Total Orders 3 Average Win 0% Average Loss 0% Compounding Annual Return 43.401% Drawdown 3.700% Expectancy 0 Start Equity 100000.00 End Equity 103210.78 Net Profit 3.211% Sharpe Ratio 1.989 Sortino Ratio 3.497 Probabilistic Sharpe Ratio 65.530% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.091 Beta 0.709 Annual Standard Deviation 0.122 Annual Variance 0.015 Information Ratio 0.269 Tracking Error 0.104 Treynor Ratio 0.343 Total Fees $2.24 Estimated Strategy Capacity $83000000.00 Lowest Capacity Asset FESX YGT6HGVF2U1X Portfolio Turnover 3.13% |
# region imports from AlgorithmImports import * # endregion class EurexEuroStoxx50Test(QCAlgorithm): def __init__(self): self._traded = False self._future: Future = None self._limit_order_ticket_to_cancel: OrderTicket = None self._limit_order_ticket_to_update: OrderTicket = None def initialize(self): self.set_start_date(2024, 1, 1) self.set_end_date(2024, 2, 1) resolution = Resolution.MINUTE if self.live_mode else Resolution.HOUR self._future = self.add_future(Futures.Indices.EURO_STOXX_50, resolution, data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, data_mapping_mode=DataMappingMode.FIRST_DAY_MONTH, contract_depth_offset=0) self._future.set_filter(0, 180) # self.set_warm_up(30, Resolution.DAILY) def is_symbol_of_interest(self, symbol: Symbol) -> bool: return (symbol == self._future.symbol or (symbol.has_canonical() and symbol.canonical == self._future.symbol)) def on_warmup_finished(self): # self.log(f"[{self.time}] :: Mapped contract: {self._future.mapped.value}") # securities = [security for security in self.securities.values() if self.is_symbol_of_interest(security.symbol)] # prices_str = ", ".join([f"{security.Symbol.Value}: {security.Price}" for security in securities]) # self.log(f"[{self.time}] :: Security Prices: {prices_str}") pass def place_trades(self): # Market order self.market_order(self._future.mapped, 1) # Limit orders that won't fill self._limit_order_ticket_to_cancel = self.limit_order(self._future.mapped, 1, 3000, tag="To cancel") self._limit_order_ticket_to_update = self.limit_order(self._future.mapped, 1, 3000, tag="To update") def on_order_event(self, order_event: OrderEvent): # Cancel limit order if order_event.ticket.order_type == OrderType.LIMIT and order_event.ticket.tag == "To cancel": order_event.ticket.cancel() # Update limit price so that the order is filled if order_event.ticket.order_type == OrderType.LIMIT and order_event.ticket.tag == "To update": order_event.ticket.update_limit_price( self._future.price, f"{order_event.ticket.tag}: Updated limit price from {order_event.limit_price} to {self._future.price}") def on_data(self, slice: Slice): if self.is_warming_up: return data_str = "\n".join([f"[{SecurityType(data.symbol.security_type)}] [{data.symbol.value}] {data}" for data in slice.all_data]) self.log(f"[{self.time}] :: Data:\n{data_str}") if not self._traded and self._future.mapped is not None: self.place_trades() self._traded = True