Overall Statistics |
Total Orders 2048 Average Win 12.87% Average Loss -3.36% Compounding Annual Return 65657410.138% Drawdown 21.800% Expectancy 0.611 Start Equity 100000 End Equity 193588.6 Net Profit 93.589% Sharpe Ratio 29256.739 Sortino Ratio 132706.05 Probabilistic Sharpe Ratio 99.702% Loss Rate 67% Win Rate 33% Profit-Loss Ratio 3.83 Alpha 42982.288 Beta 23.695 Annual Standard Deviation 1.47 Annual Variance 2.16 Information Ratio 30355.69 Tracking Error 1.417 Treynor Ratio 1814.722 Total Fees $64.50 Estimated Strategy Capacity $0 Lowest Capacity Asset ES YJHOAMPYKQGX Portfolio Turnover 357.24% |
# region imports from AlgorithmImports import * # endregion class TerminalLinkFutureTickAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2024, 6, 1) self.set_cash(100000) # Set the default order properties to use Terminal Link order properties # which allow additional settings, such as VWAP strategy # See https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/brokerages/supported-models/terminal-link#03-Orders # It doesn't affect backtesting self.default_order_properties = TerminalLinkOrderProperties() self.default_order_properties.time_in_force = TimeInForce.GOOD_TIL_CANCELED self.default_order_properties.strategy = TerminalLinkOrderProperties.StrategyParameters( "VWAP", [ TerminalLinkOrderProperties.StrategyField("09:30:00"), TerminalLinkOrderProperties.StrategyField("10:30:00"), TerminalLinkOrderProperties.StrategyField(), TerminalLinkOrderProperties.StrategyField() ] ) # Add the futures continuous contract with TICK resolution self.future = self.add_future("ES", Resolution.TICK, extended_market_hours=True) # Create a rolling window of 100 ticks self.window = RollingWindow[Tick](100) def on_data(self, data: Slice): # Update the rolling window with the ticks in the Slice object # The Slice has a collection of Tick objects [self.window.add(tick) for tick in data.ticks.get(self.future.symbol, [])] if not self.window.is_ready: return # RollingWindow is an array of a fixed-size that holds trailing data. # Index 0 refers to the most recent item in the window # and the largest index refers to the last item in the window. first = self.window[self.window.count-1].last_price last = self.window[0].last_price holdings = self.portfolio[self.future.mapped] # We open a new position when the price moves $1 # Note we use `mapped` which represents the current contract that # the continuous contract refers to, we cannot use self.future.symbol if not holdings.is_long and last > first + 1: self.market_order(self.future.mapped, 1, tag=f'buy: {last} > {first}') if not holdings.is_short and last < first - 1: self.market_order(self.future.mapped, 1, tag=f'sell: {last} < {first}')