This commit is contained in:
2026-09-03 00:54:57 +08:00
parent 07e74d054e
commit e2800fc193
17 changed files with 262 additions and 208 deletions

View File

@@ -123,6 +123,24 @@ class StockGetHandler(BaseHandler):
"ref": result
}, separators=(',', ':'), ensure_ascii=False, default=str))
# Aggregate assets, positions, and orders in one request.
class PortfolioHandler(BaseHandler):
def get(self):
account_data = safe_call(get_trade_detail_data, self.acc(), 'stock', 'account')
positions = safe_call(get_trade_detail_data, self.acc(), 'stock', 'position') or []
orders = safe_call(get_trade_detail_data, self.acc(), 'stock', 'order') or []
result = {
"assets": format_assets(account_data),
"positions": format_holding(positions),
"orders": [fixed_fields(order) for order in orders],
}
self.write(json.dumps(result, separators=(',', ':'), ensure_ascii=False))
# 以下未处理
# ContextInfo.get_bar_timetag() - Get the bar timestamp
class BarTimetagHandler(BaseHandler):
def post(self):
@@ -1015,33 +1033,48 @@ class GetFactorRankHandler(BaseHandler):
# ============= 9. Legacy handlers (compatibility) =============
def format_holding(positions):
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
}
return holding
def format_assets(account_data):
info = account_data[0] if account_data else None
if not info:
raise HTTPError(500, "Failed to get account data")
return {
"total": round(info.m_dBalance, 2),
"available": round(info.m_dAvailable, 2),
}
# get_trade_detail_data('position') - Query positions in the wrapped format
class HoldingHandler(BaseHandler):
def post(self):
data = json.loads(self.request.body)
account = data.get('account', 'stock')
positions = safe_call(get_trade_detail_data, self.acc(), account, 'position') or []
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
}
holding = format_holding(positions)
self.write(json.dumps({"data": holding}, separators=(',', ':'), ensure_ascii=False))
# get_trade_detail_data('account') - Query account assets
@@ -1050,10 +1083,9 @@ class AssetsHandler(BaseHandler):
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": round(info.m_dBalance, 2),"available": round(info.m_dAvailable, 2)}, separators=(',', ':'), ensure_ascii=False))
self.write(json.dumps(format_assets(_data), separators=(',', ':'), ensure_ascii=False))
# passorder(23) - Simplified buy order wrapper
@@ -1210,6 +1242,7 @@ class DealHandler(BaseHandler):
def make_app():
return Application([
# V2
(r"/api/v2/portfolio", PortfolioHandler),
(r"/api/v2/positions", HoldingHandler),
(r"/api/v2/assets", AssetsHandler),
# ContextInfo properties