|
|
|
|
@ -3,12 +3,21 @@
|
|
|
|
|
将 AmazingData SDK 的调用封装为内部接口
|
|
|
|
|
对外接口不直接调用 SDK,而是通过内部接口调用
|
|
|
|
|
"""
|
|
|
|
|
import time
|
|
|
|
|
import functools
|
|
|
|
|
import pandas as pd
|
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
|
from typing import List, Optional, Dict, Any
|
|
|
|
|
|
|
|
|
|
from app.core.logger import info, error
|
|
|
|
|
|
|
|
|
|
# 导入指标统计
|
|
|
|
|
try:
|
|
|
|
|
from app.core.metrics import record_internal_call
|
|
|
|
|
METRICS_AVAILABLE = True
|
|
|
|
|
except ImportError:
|
|
|
|
|
METRICS_AVAILABLE = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 数据库相关导入(可选,如果数据库未配置则回退到SDK)
|
|
|
|
|
try:
|
|
|
|
|
@ -20,12 +29,43 @@ except ImportError:
|
|
|
|
|
DB_AVAILABLE = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def track_internal_call(category: str):
|
|
|
|
|
"""对内接口调用统计装饰器
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
category: 接口类别 (market/base/info)
|
|
|
|
|
"""
|
|
|
|
|
def decorator(func):
|
|
|
|
|
@functools.wraps(func)
|
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
|
if not METRICS_AVAILABLE:
|
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
method_name = func.__name__
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
status = "success"
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
result = func(*args, **kwargs)
|
|
|
|
|
return result
|
|
|
|
|
except Exception as e:
|
|
|
|
|
status = "error"
|
|
|
|
|
raise e
|
|
|
|
|
finally:
|
|
|
|
|
duration = time.time() - start_time
|
|
|
|
|
record_internal_call(category, method_name, status, duration)
|
|
|
|
|
|
|
|
|
|
return wrapper
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _MarketDataInternal:
|
|
|
|
|
"""市场数据内部接口 - 封装 _market_data"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, market_data):
|
|
|
|
|
self._market_data = market_data
|
|
|
|
|
|
|
|
|
|
@track_internal_call("market")
|
|
|
|
|
def login(self, username: str, password: str, ip: str, port: str) -> bool:
|
|
|
|
|
"""登录"""
|
|
|
|
|
try:
|
|
|
|
|
@ -39,6 +79,7 @@ class _MarketDataInternal:
|
|
|
|
|
error(f"[_MarketDataInternal] Login failed: {e}")
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
@track_internal_call("market")
|
|
|
|
|
def is_login(self) -> bool:
|
|
|
|
|
"""检查登录状态"""
|
|
|
|
|
try:
|
|
|
|
|
@ -46,6 +87,7 @@ class _MarketDataInternal:
|
|
|
|
|
except Exception:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
@track_internal_call("market")
|
|
|
|
|
def query_kline(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -65,6 +107,7 @@ class _MarketDataInternal:
|
|
|
|
|
error(f"[_MarketDataInternal] Query kline failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("market")
|
|
|
|
|
def query_snapshot(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -89,6 +132,7 @@ class _BaseDataInternal:
|
|
|
|
|
def __init__(self, base_data):
|
|
|
|
|
self._base_data = base_data
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_code_list(self, security_type: str) -> List[str]:
|
|
|
|
|
"""获取代码列表 - 优先从数据库获取,无数据则从SDK获取并缓存"""
|
|
|
|
|
# 1. 先尝试从数据库获取
|
|
|
|
|
@ -171,6 +215,7 @@ class _BaseDataInternal:
|
|
|
|
|
finally:
|
|
|
|
|
db.close()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_future_code_list(self, security_type: str) -> List[str]:
|
|
|
|
|
"""获取期货代码列表"""
|
|
|
|
|
try:
|
|
|
|
|
@ -179,6 +224,7 @@ class _BaseDataInternal:
|
|
|
|
|
error(f"[_BaseDataInternal] Get future code list failed: {e}")
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_code_info(self, security_type: str) -> pd.DataFrame:
|
|
|
|
|
"""获取代码信息"""
|
|
|
|
|
try:
|
|
|
|
|
@ -187,6 +233,7 @@ class _BaseDataInternal:
|
|
|
|
|
error(f"[_BaseDataInternal] Get code info failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_calendar(self, market: str) -> List[int]:
|
|
|
|
|
"""获取交易日历 - 优先从数据库获取,无数据则从SDK获取并缓存"""
|
|
|
|
|
# 1. 先尝试从数据库获取
|
|
|
|
|
@ -270,6 +317,7 @@ class _BaseDataInternal:
|
|
|
|
|
finally:
|
|
|
|
|
db.close()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_adj_factor(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -287,6 +335,7 @@ class _BaseDataInternal:
|
|
|
|
|
error(f"[_BaseDataInternal] Get adj factor failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_backward_factor(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -304,6 +353,7 @@ class _BaseDataInternal:
|
|
|
|
|
error(f"[_BaseDataInternal] Get backward factor failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_etf_pcf(self, code_list: List[str]) -> tuple:
|
|
|
|
|
"""获取ETF申赎数据"""
|
|
|
|
|
try:
|
|
|
|
|
@ -312,6 +362,7 @@ class _BaseDataInternal:
|
|
|
|
|
error(f"[_BaseDataInternal] Get ETF PCF failed: {e}")
|
|
|
|
|
return ({}, {})
|
|
|
|
|
|
|
|
|
|
@track_internal_call("base")
|
|
|
|
|
def get_hist_code_list(self, security_type: str) -> pd.DataFrame:
|
|
|
|
|
"""获取历史代码列表"""
|
|
|
|
|
try:
|
|
|
|
|
@ -327,6 +378,7 @@ class _InfoDataInternal:
|
|
|
|
|
def __init__(self, info_data):
|
|
|
|
|
self._info_data = info_data
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_equity_structure(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -344,6 +396,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get equity structure failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_share_holder(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -368,6 +421,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get share holder failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_holder_num(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -389,6 +443,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get holder num failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_income(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -410,6 +465,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get income failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_balance_sheet(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -431,6 +487,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get balance sheet failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_cash_flow(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -452,6 +509,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get cash flow failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_profit_express(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -473,6 +531,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get profit express failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_profit_notice(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -494,6 +553,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get profit notice failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_margin_summary(
|
|
|
|
|
self,
|
|
|
|
|
local_path: str,
|
|
|
|
|
@ -513,6 +573,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get margin summary failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_margin_detail(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -534,6 +595,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get margin detail failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_long_hu_bang(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -555,6 +617,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get long hu bang failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_block_trading(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -576,6 +639,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get block trading failed: {e}")
|
|
|
|
|
return pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_index_constituent(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -593,6 +657,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get index constituent failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_index_weight(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -614,6 +679,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get index weight failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_fund_share(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -635,6 +701,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get fund share failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_kzz_issuance(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
@ -652,6 +719,7 @@ class _InfoDataInternal:
|
|
|
|
|
error(f"[_InfoDataInternal] Get kzz issuance failed: {e}")
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
@track_internal_call("info")
|
|
|
|
|
def get_history_stock_status(
|
|
|
|
|
self,
|
|
|
|
|
code_list: List[str],
|
|
|
|
|
|