feat: add Quant OS A-share baseline

This commit is contained in:
2026-07-26 12:54:04 +08:00
commit 48c5f64bbd
98 changed files with 31874 additions and 0 deletions
+158
View File
@@ -0,0 +1,158 @@
"""Deterministic fake QMT ContextInfo and passorder recorder."""
import datetime
from types import SimpleNamespace
class FakeFrame(object):
def __init__(self, closes):
self._closes = list(closes)
def __getitem__(self, key):
if key != "close":
raise KeyError(key)
return list(self._closes)
class FakeQmtContext(object):
def __init__(
self,
histories,
asset=1_000_000.0,
positions=None,
bar_time=None,
trade_mode="backtest",
params=None,
st_periods=None,
):
self.histories = {
symbol: [float(value) for value in values]
for symbol, values in histories.items()
}
self.trade_mode = trade_mode
self.do_back_test = trade_mode == "backtest"
self._param = {"asset": float(asset), "trade_mode": trade_mode}
self._param.update(params or {})
self.barpos = 0
self._bar_time = bar_time or datetime.datetime(2026, 7, 20, 15, 0)
self._positions = list(positions or [])
self._asset = float(asset)
self.universe = []
self.last_market_request = None
self.last_sector_request = None
self.commission = None
self.slippage = None
self.st_periods = dict(st_periods or {})
def set_universe(self, symbols):
self.universe = list(symbols)
def set_commission(self, commission_type, commission_list):
self.commission = {
"type": int(commission_type),
"values": list(commission_list),
}
def set_slippage(self, slippage_type, slippage):
self.slippage = {
"type": int(slippage_type),
"value": float(slippage),
}
def get_bar_timetag(self, barpos):
del barpos
return int(self._bar_time.timestamp() * 1000)
def is_last_bar(self):
return True
def get_market_data_ex(
self,
fields,
stock_code,
period,
start_time,
end_time,
count,
dividend_type,
fill_data,
subscribe,
):
self.last_market_request = {
"fields": fields,
"stock_code": stock_code,
"period": period,
"start_time": start_time,
"end_time": end_time,
"count": count,
"dividend_type": dividend_type,
"fill_data": fill_data,
"subscribe": subscribe,
}
return {
symbol: FakeFrame(self.histories[symbol][-int(count) :])
for symbol in stock_code
}
def get_stock_list_in_sector(self, sector_name, timetag=None):
self.last_sector_request = {
"sector_name": sector_name,
"timetag": timetag,
}
return sorted(self.histories)
def get_his_st_data(self, symbol):
return dict(self.st_periods.get(symbol, {}))
def get_trade_detail_data(self, account_id, account_type, kind):
del account_id, account_type
if str(kind).lower() == "position":
return list(self._positions)
if str(kind).lower() == "account":
return [SimpleNamespace(total_asset=self._asset)]
return []
class FakeQmtHarness(object):
def __init__(self, context):
self.context = context
self.orders = []
def install(self, module):
module.passorder = self.passorder
return self
def passorder(
self,
operation,
order_type,
account_id,
order_code,
price_type,
price,
volume,
strategy_name,
quick_trade,
user_order_id,
context,
):
self.orders.append(
{
"operation": operation,
"order_type": order_type,
"account_id": account_id,
"order_code": order_code,
"price_type": price_type,
"price": price,
"volume": volume,
"strategy_name": strategy_name,
"quick_trade": quick_trade,
"user_order_id": user_order_id,
"context": context,
}
)
def run(self, module):
self.install(module)
module.init(self.context)
return module.handlebar(self.context)