feat QMT_API.py

This commit is contained in:
2026-09-02 21:03:45 +08:00
parent 66ccd42d4e
commit 9d8b913465
13 changed files with 91 additions and 163 deletions

View File

@@ -67,55 +67,23 @@ class BaseHandler(RequestHandler):
# ============= 1. ContextInfo properties =============
# ContextInfo.period - Get the current period
class ContextPeriodHandler(BaseHandler):
class ContextInfoHandler(BaseHandler):
def get(self):
self.write(json.dumps({"period": self.ctx().period}, separators=(',', ':'), ensure_ascii=False))
ctx = self.ctx()
data = {
"period": ctx.period,
"barpos": ctx.barpos,
"time_tick_size": ctx.time_tick_size,
"stockcode": ctx.stockcode,
"dividend_type": ctx.dividend_type,
"market": ctx.market,
"do_back_test": ctx.do_back_test,
"benchmark": ctx.benchmark,
"capital": ctx.capital,
"universe": ctx.get_universe(),
}
self.write(data, separators=(',', ':'), ensure_ascii=False)
# ContextInfo.barpos - Get the current bar index
class ContextBarposHandler(BaseHandler):
def get(self):
self.write(json.dumps({"barpos": self.ctx().barpos}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.time_tick_size - Get the current bar count
class ContextTimeTickSizeHandler(BaseHandler):
def get(self):
self.write(json.dumps({"time_tick_size": self.ctx().time_tick_size}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.stockcode - Get the current chart symbol
class ContextStockCodeHandler(BaseHandler):
def get(self):
self.write(json.dumps({"stockcode": self.ctx().stockcode}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.dividend_type - Get the current adjustment mode
class ContextDividendTypeHandler(BaseHandler):
def get(self):
self.write(json.dumps({"dividend_type": self.ctx().dividend_type}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.market - Get the current chart market
class ContextMarketHandler(BaseHandler):
def get(self):
self.write(json.dumps({"market": self.ctx().market}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.do_back_test - Check whether backtesting is enabled
class ContextDoBackTestHandler(BaseHandler):
def get(self):
self.write(json.dumps({"do_back_test": self.ctx().do_back_test}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.benchmark - Get the backtest benchmark
class ContextBenchmarkHandler(BaseHandler):
def get(self):
self.write(json.dumps({"benchmark": self.ctx().benchmark}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.capital - Get the initial backtest capital
class ContextCapitalHandler(BaseHandler):
def get(self):
self.write(json.dumps({"capital": self.ctx().capital}, separators=(',', ':'), ensure_ascii=False))
# ContextInfo.get_universe() - Get symbols in the universe
class ContextUniverseHandler(BaseHandler):
def get(self):
self.write(json.dumps({"universe": self.ctx().get_universe()}, separators=(',', ':'), ensure_ascii=False))
# ============= 2. Data queries (ContextInfo get_*) =============
@@ -966,7 +934,8 @@ class TradeDetailDataHandler(BaseHandler):
ret = safe_call(get_trade_detail_data, self.acc(), account, datatype)
if ret is None:
ret = []
self.write(json.dumps({"data": ret}, separators=(',', ':'), ensure_ascii=False))
result = [fixed_fields(obj) for obj in ret]
self.write(json.dumps({"data": result}, separators=(',', ':'), ensure_ascii=False))
# get_value_by_order_id() - Get order or trade details by order ID
class ValueByOrderIdHandler(BaseHandler):
@@ -1112,7 +1081,28 @@ class HoldingHandler(BaseHandler):
data = json.loads(self.request.body)
account = data.get('account', 'stock')
positions = safe_call(get_trade_detail_data, self.acc(), account, 'position') or []
self.write(json.dumps({"data": positions}, separators=(',', ':'), ensure_ascii=False))
holding = {}
for position in positions:
stock = position.m_strInstrumentID + '.' + position.m_strExchangeID
holding[stock] = {
'StockCode': stock,
'StockName': position.m_strInstrumentName,
'Direction': position.m_nDirection,
'Volume': position.m_nVolume,
'OpenPrice': position.m_dOpenPrice,
'FloatProfit': position.m_dFloatProfit,
'MarketValue': position.m_dMarketValue,
'StockHolder': position.m_strStockHolder,
'FrozenVolume': position.m_nFrozenVolume,
'CanUseVolume': position.m_nCanUseVolume,
'OnRoadVolume': position.m_nOnRoadVolume,
'YesterdayVolume': position.m_nYesterdayVolume,
'LastPrice': position.m_dLastPrice,
'ProfitRate': position.m_dProfitRate,
'FutureTradeType': position.m_eFutureTradeType,
'ExpireDate': position.m_strExpireDate
}
self.write(json.dumps({"data": holding}, separators=(',', ':'), ensure_ascii=False))
# get_trade_detail_data('account') - Query account assets
class AssetsHandler(BaseHandler):
@@ -1126,28 +1116,6 @@ class AssetsHandler(BaseHandler):
self.write(json.dumps({"total": round(info.m_dBalance, 2),"available": round(info.m_dAvailable, 2)}, separators=(',', ':'), ensure_ascii=False))
# get_trade_detail_data('account') - Query total assets
class TotalMoneyHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
account = data.get('account', 'stock')
_data = safe_call(get_trade_detail_data, self.acc(), account, 'account')
info = _data[0] if _data else None
if not info:
raise HTTPError(500, "Failed to get account data")
self.write(json.dumps({"total_money": round(info.m_dBalance, 2)}, separators=(',', ':'), ensure_ascii=False))
# get_trade_detail_data('account') - Query available cash
class AvailableMoneyHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
account = data.get('account', 'stock')
_data = safe_call(get_trade_detail_data, self.acc(), account, 'account')
info = _data[0] if _data else None
if not info:
raise HTTPError(500, "Failed to get account data")
self.write(json.dumps({"available_money": round(info.m_dAvailable, 2)}, separators=(',', ':'), ensure_ascii=False))
# passorder(23) - Simplified buy order wrapper
class BuyHandler(BaseHandler):
def post(self):
@@ -1307,8 +1275,6 @@ def make_app():
# Legacy compatibility routes
(r"/api/holding", HoldingHandler),
(r"/api/money/total", TotalMoneyHandler),
(r"/api/money/available", AvailableMoneyHandler),
(r"/api/order/buy", BuyHandler),
(r"/api/order/sell", SellHandler),
(r"/api/order/status", OrderStatusHandler),
@@ -1318,16 +1284,7 @@ def make_app():
(r"/api/order/deal", DealHandler),
# ContextInfo properties
(r"/api/context/period", ContextPeriodHandler),
(r"/api/context/barpos", ContextBarposHandler),
(r"/api/context/time_tick_size", ContextTimeTickSizeHandler),
(r"/api/context/stockcode", ContextStockCodeHandler),
(r"/api/context/dividend_type", ContextDividendTypeHandler),
(r"/api/context/market", ContextMarketHandler),
(r"/api/context/do_back_test", ContextDoBackTestHandler),
(r"/api/context/benchmark", ContextBenchmarkHandler),
(r"/api/context/capital", ContextCapitalHandler),
(r"/api/context/universe", ContextUniverseHandler),
(r"/api/context/info", ContextInfoHandler),
# Data queries
(r"/api/data/stock_name", StockNameHandler),