Overall Statistics
Total Orders
32
Average Win
4.13%
Average Loss
-2.62%
Compounding Annual Return
44.000%
Drawdown
17.900%
Expectancy
0.449
Start Equity
1000000.00
End Equity
1199400
Net Profit
19.940%
Sharpe Ratio
1.278
Sortino Ratio
1.931
Probabilistic Sharpe Ratio
53.894%
Loss Rate
44%
Win Rate
56%
Profit-Loss Ratio
1.58
Alpha
0.404
Beta
-0.327
Annual Standard Deviation
0.257
Annual Variance
0.066
Information Ratio
0.328
Tracking Error
0.293
Treynor Ratio
-1.005
Total Fees
$1560.00
Estimated Strategy Capacity
$140000000.00
Lowest Capacity Asset
HSI XQJXBPPDMITL
Portfolio Turnover
25.58%
from AlgorithmImports import *

class InternationalFuturesDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2021, 1, 1)
        self.set_end_date(2021, 7, 1)
        # Set the time zone to HKT to make it more comparable with the exchange.
        self.set_time_zone(TimeZones.HONG_KONG)
        # Set the account currency as HKD to trade HSI Futures.
        self.set_account_currency("HKD", 1000000)
        # Seed the last price of the contracts for filling.
        self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices)))

        # Request HSI Futures to trade. 
        # Note that we will trade the contract with the highest open interest for liquidity.
        self.hsi_future = self.add_future(
            Futures.Indices.HANG_SENG,
            extended_market_hours=True,
            data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
            contract_depth_offset=0
        )
        # Request the corresponding underlying Index for feeding indicator for trade signal generation.
        hsi_index = self.add_index("HSI").symbol

        # Create a ZigZag indicator to trade Hang Seng Index price pivot points.
        self._zz = self.zz(hsi_index, 0.15, 5, Resolution.DAILY)
        # Warm up indicator for immediate readiness to trade.
        self.warm_up_indicator(hsi_index, self._zz, Resolution.DAILY)

    def on_data(self, slice: Slice) -> None:
        # Only place trade if the Future contracts is in market opening hours to avoid stale fills.
        if self.is_market_open(self.hsi_future.symbol) and self._zz.is_ready:
            pivot = self._zz.pivot_type
            # If the last pivot point is a low point, the current trend is increasing after this low point.
            if pivot == PivotPointType.LOW and not self.portfolio[self.hsi_future.symbol].is_long:
                self.set_holdings(self.hsi_future.mapped, 0.2)
            # If the last pivot point is a high point, the current trend is decreasing after this high point.
            elif pivot == PivotPointType.HIGH and not self.portfolio[self.hsi_future.symbol].is_short:
                self.set_holdings(self.hsi_future.mapped, -0.2)

        # Handle rollover in case the current mapped contract changes.
        for _, changed_event in slice.symbol_changed_events.items():
            old_symbol = changed_event.old_symbol
            new_symbol = self.add_future_contract(changed_event.new_symbol).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)
            if quantity != 0:
                self.market_order(new_symbol, quantity)