feat: 优化游资详情股票列表
This commit is contained in:
@ -354,8 +354,7 @@ def fetch_trader_detail(trader_id: int) -> dict[str, Any]:
|
||||
)
|
||||
seats = [_normalize_row(row) for row in cursor.fetchall()]
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
stock_query = """
|
||||
SELECT
|
||||
d.stock_code,
|
||||
MAX(COALESCE(o.stock_name, d.stock_name)) AS stock_name,
|
||||
@ -365,22 +364,120 @@ def fetch_trader_detail(trader_id: int) -> dict[str, Any]:
|
||||
MAX(d.trade_date) AS last_trade_date,
|
||||
SUM(CASE WHEN CAST(COALESCE(NULLIF(d.buy_amount_wan, ''), '0') AS DECIMAL(18,2)) > 0 THEN 1 ELSE 0 END) AS buy_action_count,
|
||||
SUM(CASE WHEN CAST(COALESCE(NULLIF(d.sell_amount_wan, ''), '0') AS DECIMAL(18,2)) > 0 THEN 1 ELSE 0 END) AS sell_action_count,
|
||||
SUM(CAST(COALESCE(NULLIF(d.net_amount_wan, ''), '0') AS DECIMAL(18,2))) AS total_net_amount_wan,
|
||||
MAX(CASE WHEN w.warning_type = 'sell_alert' THEN 1 ELSE 0 END) AS has_sell_alert,
|
||||
MAX(CASE WHEN w.warning_type = 'slow_exit_watch' THEN 1 ELSE 0 END) AS has_slow_exit
|
||||
MAX(CASE WHEN w.warning_type = 'slow_exit_watch' THEN 1 ELSE 0 END) AS has_slow_exit,
|
||||
MAX(s.industry) AS industry,
|
||||
MAX(s.market) AS market,
|
||||
MAX(s.total_market_value) AS total_market_value,
|
||||
MAX(s.circulating_market_value) AS circulating_market_value
|
||||
FROM lhb_detail_seats d
|
||||
LEFT JOIN lhb_overview o
|
||||
ON o.stock_code = d.stock_code AND o.trade_date = d.trade_date
|
||||
LEFT JOIN warning_events w
|
||||
ON w.stock_code = d.stock_code AND w.trader_name = d.matched_trader_name
|
||||
LEFT JOIN stocks s
|
||||
ON s.stock_code = d.stock_code
|
||||
WHERE d.matched_trader_name = %s
|
||||
GROUP BY d.stock_code
|
||||
ORDER BY last_trade_date DESC, action_count DESC
|
||||
LIMIT 100
|
||||
""",
|
||||
(trader_name,),
|
||||
)
|
||||
"""
|
||||
|
||||
cursor.execute(stock_query, (trader_name,))
|
||||
stocks = [_normalize_row(row) for row in cursor.fetchall()]
|
||||
|
||||
stock_codes = [row["stock_code"] for row in stocks if row.get("stock_code")]
|
||||
increasing_by_stock: dict[str, bool] = {}
|
||||
if stock_codes:
|
||||
placeholders = ", ".join(["%s"] * len(stock_codes))
|
||||
cursor.execute(
|
||||
f"""
|
||||
SELECT
|
||||
stock_code,
|
||||
trade_date,
|
||||
SUM(CAST(COALESCE(NULLIF(net_amount_wan, ''), '0') AS DECIMAL(18,2))) AS daily_net_amount_wan
|
||||
FROM lhb_detail_seats
|
||||
WHERE matched_trader_name = %s
|
||||
AND stock_code IN ({placeholders})
|
||||
AND trade_date IS NOT NULL
|
||||
GROUP BY stock_code, trade_date
|
||||
ORDER BY stock_code, trade_date
|
||||
""",
|
||||
(trader_name, *stock_codes),
|
||||
)
|
||||
net_history_by_stock: dict[str, list[float]] = {}
|
||||
for row in cursor.fetchall():
|
||||
stock_code = row["stock_code"]
|
||||
net_history_by_stock.setdefault(stock_code, []).append(float(row["daily_net_amount_wan"] or 0))
|
||||
|
||||
for stock_code, net_history in net_history_by_stock.items():
|
||||
increasing_by_stock[stock_code] = len(net_history) >= 2 and all(
|
||||
current > previous for previous, current in zip(net_history, net_history[1:])
|
||||
)
|
||||
|
||||
for stock in stocks:
|
||||
stock["is_net_amount_increasing"] = increasing_by_stock.get(stock["stock_code"], False)
|
||||
|
||||
missing_codes = [
|
||||
row["stock_code"]
|
||||
for row in stocks[:30]
|
||||
if not row.get("industry") or not row.get("market") or row.get("total_market_value") is None
|
||||
]
|
||||
if missing_codes:
|
||||
eastmoney = EastMoneyClient()
|
||||
seen_codes: set[str] = set()
|
||||
for stock_code in missing_codes:
|
||||
if stock_code in seen_codes:
|
||||
continue
|
||||
seen_codes.add(stock_code)
|
||||
profile: dict[str, Any] = {}
|
||||
snapshot: dict[str, Any] = {}
|
||||
try:
|
||||
profile = eastmoney.fetch_company_profile(stock_code)
|
||||
except Exception:
|
||||
profile = {}
|
||||
try:
|
||||
snapshot = eastmoney.fetch_quote_snapshot(stock_code)
|
||||
except Exception:
|
||||
snapshot = {}
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO stocks (
|
||||
stock_code,
|
||||
stock_name,
|
||||
market,
|
||||
industry,
|
||||
concept_tags,
|
||||
total_market_value,
|
||||
circulating_market_value
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
stock_name = COALESCE(NULLIF(VALUES(stock_name), ''), stock_name),
|
||||
market = COALESCE(NULLIF(VALUES(market), ''), market),
|
||||
industry = COALESCE(NULLIF(VALUES(industry), ''), industry),
|
||||
concept_tags = COALESCE(VALUES(concept_tags), concept_tags),
|
||||
total_market_value = COALESCE(VALUES(total_market_value), total_market_value),
|
||||
circulating_market_value = COALESCE(VALUES(circulating_market_value), circulating_market_value)
|
||||
""",
|
||||
(
|
||||
stock_code,
|
||||
profile.get("stock_name") or (snapshot.get("stock_name") if snapshot else None) or stock_code,
|
||||
profile.get("market"),
|
||||
profile.get("industry") or snapshot.get("industry"),
|
||||
json.dumps(profile.get("concept_tags") or [], ensure_ascii=False) if profile.get("concept_tags") else None,
|
||||
snapshot.get("total_market_value"),
|
||||
snapshot.get("circulating_market_value"),
|
||||
),
|
||||
)
|
||||
|
||||
cursor.execute(stock_query, (trader_name,))
|
||||
stocks = [_normalize_row(row) for row in cursor.fetchall()]
|
||||
for stock in stocks:
|
||||
stock["is_net_amount_increasing"] = increasing_by_stock.get(stock["stock_code"], False)
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT trade_date, stock_code, stock_name, warning_type, warning_level, trigger_reason
|
||||
|
||||
Reference in New Issue
Block a user