| Overall Statistics |
|
Total Orders 1213 Average Win 2.20% Average Loss -1.89% Compounding Annual Return 0.808% Drawdown 44.800% Expectancy 0.264 Start Equity 1000000 End Equity 1108295.14 Net Profit 10.830% Sharpe Ratio 0.086 Sortino Ratio 0.088 Probabilistic Sharpe Ratio 0.004% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.16 Alpha 0.01 Beta 0.184 Annual Standard Deviation 0.292 Annual Variance 0.085 Information Ratio -0.183 Tracking Error 0.313 Treynor Ratio 0.136 Total Fees $2544.33 Estimated Strategy Capacity $150000000000.00 Lowest Capacity Asset KM Z5O7UGDUMN69 Portfolio Turnover 1.52% Drawdown Recovery 1153 |
# region imports
from AlgorithmImports import *
# endregion
class Kospi200FuturesAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2013,11,1)
self.set_cash(1_000_000)
self._index = self.add_index("KM", market=Market.KRX)
self._forex = self.add_forex("USDKRW")
self._future = self.add_future(Futures.Indices.KOSPI_200,
extended_market_hours=True,
data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
contract_depth_offset=0
)
# Filter to contracts expiring within 6 months (approx 182 days)
self._future.set_filter(0, 182)
def on_end_of_day(self, symbol: Symbol):
if symbol.security_type in [SecurityType.INDEX, SecurityType.FOREX]:
self.plot(symbol.value, 'EOD', self.securities[symbol].price)
def on_data(self, data: Slice) -> None:
if self.is_warming_up or self.portfolio.invested:
return
# Get the futures chain for our KM contract
chain = data.future_chains.get(self._future.symbol)
if not chain:
return
# Sort contracts by expiry and pick the nearest one with data
contracts = sorted([c for c in chain if (c.expiry-self.time).days>1], key=lambda c: c.expiry)
if not contracts:
return
front = contracts[0]
# Place order on the front-month contract
self.market_order(front.symbol, 1, tag=f'{self._future.mapped.value=}')