币种标记标准化 + data-pipeline诊断文档
stale_detector: HK股价格输出加(HKD)标记,防止LLM混读CNY/HKD per_stock_reassess: 写回decisions.json的HK股加上currency: HKD docs/data-pipeline-diagnosis.md: 完整数据管道重构需求文档 避免建滔积层板CNY/HKD错配类问题复发
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"last_updated": "2026-06-30 09:02",
|
"last_updated": "2026-06-30 11:11",
|
||||||
"total_candidates": 0,
|
"total_candidates": 3,
|
||||||
"sectors_analyzed_today": [
|
"sectors_analyzed_today": [
|
||||||
"半导体",
|
"半导体",
|
||||||
"金属新材料",
|
"金属新材料",
|
||||||
@@ -343,6 +343,102 @@
|
|||||||
"drop_reason": "超7天未更新",
|
"drop_reason": "超7天未更新",
|
||||||
"trend_warning": false,
|
"trend_warning": false,
|
||||||
"trend_note": ""
|
"trend_note": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "688981",
|
||||||
|
"name": "中芯国际",
|
||||||
|
"sector": "半导体",
|
||||||
|
"xiaoguo_score": 8,
|
||||||
|
"xiaoguo_reason": "晶圆代工龙头,产能利用率回升,先进制程突破预期强,机构持仓集中,趋势走稳。",
|
||||||
|
"xiaoguo_strategy": {
|
||||||
|
"entry_range": "58.00-60.50",
|
||||||
|
"stop_loss": "55.00",
|
||||||
|
"target": "68.00"
|
||||||
|
},
|
||||||
|
"verified_price": 159.52,
|
||||||
|
"verified_change": 5.64,
|
||||||
|
"added_at": "2026-06-30 11:09",
|
||||||
|
"last_updated": "2026-06-30 11:09",
|
||||||
|
"num_observations": 1,
|
||||||
|
"score_history": [
|
||||||
|
{
|
||||||
|
"date": "2026-06-30 11:09",
|
||||||
|
"score": 8
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zhiwei_star": null,
|
||||||
|
"zhiwei_reviewed": false,
|
||||||
|
"zhiwei_reviewed_at": null,
|
||||||
|
"promoted": false,
|
||||||
|
"promoted_at": null,
|
||||||
|
"dropped": false,
|
||||||
|
"drop_reason": null,
|
||||||
|
"trend_warning": false,
|
||||||
|
"trend_note": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "002371",
|
||||||
|
"name": "北方华创",
|
||||||
|
"sector": "半导体",
|
||||||
|
"xiaoguo_score": 9,
|
||||||
|
"xiaoguo_reason": "半导体设备核心标的,订单饱满,国产替代加速,业绩高增确定性高,资金持续加仓。",
|
||||||
|
"xiaoguo_strategy": {
|
||||||
|
"entry_range": "285.00-295.00",
|
||||||
|
"stop_loss": "270.00",
|
||||||
|
"target": "330.00"
|
||||||
|
},
|
||||||
|
"verified_price": 882.01,
|
||||||
|
"verified_change": 2.54,
|
||||||
|
"added_at": "2026-06-30 11:09",
|
||||||
|
"last_updated": "2026-06-30 11:09",
|
||||||
|
"num_observations": 1,
|
||||||
|
"score_history": [
|
||||||
|
{
|
||||||
|
"date": "2026-06-30 11:09",
|
||||||
|
"score": 9
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zhiwei_star": null,
|
||||||
|
"zhiwei_reviewed": false,
|
||||||
|
"zhiwei_reviewed_at": null,
|
||||||
|
"promoted": false,
|
||||||
|
"promoted_at": null,
|
||||||
|
"dropped": false,
|
||||||
|
"drop_reason": null,
|
||||||
|
"trend_warning": false,
|
||||||
|
"trend_note": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "603501",
|
||||||
|
"name": "韦尔股份",
|
||||||
|
"sector": "半导体",
|
||||||
|
"xiaoguo_score": 7.5,
|
||||||
|
"xiaoguo_reason": "CIS龙头,消费电子复苏+汽车电子放量,估值处于历史中低位,弹性较大。",
|
||||||
|
"xiaoguo_strategy": {
|
||||||
|
"entry_range": "88.00-92.00",
|
||||||
|
"stop_loss": "83.00",
|
||||||
|
"target": "105.00"
|
||||||
|
},
|
||||||
|
"verified_price": 92.38,
|
||||||
|
"verified_change": 4.62,
|
||||||
|
"added_at": "2026-06-30 11:09",
|
||||||
|
"last_updated": "2026-06-30 11:09",
|
||||||
|
"num_observations": 1,
|
||||||
|
"score_history": [
|
||||||
|
{
|
||||||
|
"date": "2026-06-30 11:09",
|
||||||
|
"score": 7.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zhiwei_star": null,
|
||||||
|
"zhiwei_reviewed": false,
|
||||||
|
"zhiwei_reviewed_at": null,
|
||||||
|
"promoted": false,
|
||||||
|
"promoted_at": null,
|
||||||
|
"dropped": false,
|
||||||
|
"drop_reason": null,
|
||||||
|
"trend_warning": false,
|
||||||
|
"trend_note": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+38
-38
@@ -32,8 +32,8 @@
|
|||||||
"entry_zone": "1220.0~1256.27",
|
"entry_zone": "1220.0~1256.27",
|
||||||
"take_profit_zone": "0~1328.37"
|
"take_profit_zone": "0~1328.37"
|
||||||
},
|
},
|
||||||
"price": 1272.71,
|
"price": 1273.99,
|
||||||
"change_pct": 4.32
|
"change_pct": 4.43
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "06869",
|
"code": "06869",
|
||||||
@@ -67,8 +67,8 @@
|
|||||||
"entry_zone": "239.4~251.37",
|
"entry_zone": "239.4~251.37",
|
||||||
"take_profit_zone": "0~309.76"
|
"take_profit_zone": "0~309.76"
|
||||||
},
|
},
|
||||||
"price": 219.78,
|
"price": 219.43,
|
||||||
"change_pct": 5.76
|
"change_pct": 5.6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "01478",
|
"code": "01478",
|
||||||
@@ -102,8 +102,8 @@
|
|||||||
"entry_zone": "6.2~7.23",
|
"entry_zone": "6.2~7.23",
|
||||||
"take_profit_zone": "0~7.44"
|
"take_profit_zone": "0~7.44"
|
||||||
},
|
},
|
||||||
"price": 6.01,
|
"price": 6.0,
|
||||||
"change_pct": 0.29
|
"change_pct": 0.14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "601899",
|
"code": "601899",
|
||||||
@@ -137,8 +137,8 @@
|
|||||||
"entry_zone": "22.48~26.23",
|
"entry_zone": "22.48~26.23",
|
||||||
"take_profit_zone": "0~24.6"
|
"take_profit_zone": "0~24.6"
|
||||||
},
|
},
|
||||||
"price": 24.98,
|
"price": 24.97,
|
||||||
"change_pct": -3.14
|
"change_pct": -3.18
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "688411",
|
"code": "688411",
|
||||||
@@ -172,8 +172,8 @@
|
|||||||
"entry_zone": "278.2~292.11",
|
"entry_zone": "278.2~292.11",
|
||||||
"take_profit_zone": "0~303.96"
|
"take_profit_zone": "0~303.96"
|
||||||
},
|
},
|
||||||
"price": 283.32,
|
"price": 283.06,
|
||||||
"change_pct": -0.94
|
"change_pct": -1.03
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "688981",
|
"code": "688981",
|
||||||
@@ -207,8 +207,8 @@
|
|||||||
"entry_zone": "151.0~158.55",
|
"entry_zone": "151.0~158.55",
|
||||||
"take_profit_zone": "0~173.58"
|
"take_profit_zone": "0~173.58"
|
||||||
},
|
},
|
||||||
"price": 159.99,
|
"price": 160.04,
|
||||||
"change_pct": 5.95
|
"change_pct": 5.99
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "01888",
|
"code": "01888",
|
||||||
@@ -242,8 +242,8 @@
|
|||||||
"entry_zone": "96.3~101.11",
|
"entry_zone": "96.3~101.11",
|
||||||
"take_profit_zone": "0~111.71"
|
"take_profit_zone": "0~111.71"
|
||||||
},
|
},
|
||||||
"price": 86.45,
|
"price": 86.97,
|
||||||
"change_pct": 3.43
|
"change_pct": 4.05
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "688639",
|
"code": "688639",
|
||||||
@@ -277,8 +277,8 @@
|
|||||||
"entry_zone": "14.37~16.77",
|
"entry_zone": "14.37~16.77",
|
||||||
"take_profit_zone": "0~18.35"
|
"take_profit_zone": "0~18.35"
|
||||||
},
|
},
|
||||||
"price": 15.91,
|
"price": 15.94,
|
||||||
"change_pct": -4.33
|
"change_pct": -4.15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "300750",
|
"code": "300750",
|
||||||
@@ -312,8 +312,8 @@
|
|||||||
"entry_zone": "386.75~394.56",
|
"entry_zone": "386.75~394.56",
|
||||||
"take_profit_zone": "0~409.12"
|
"take_profit_zone": "0~409.12"
|
||||||
},
|
},
|
||||||
"price": 392.86,
|
"price": 392.8,
|
||||||
"change_pct": 0.13
|
"change_pct": 0.11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "01211",
|
"code": "01211",
|
||||||
@@ -347,8 +347,8 @@
|
|||||||
"entry_zone": "64.89~75.7",
|
"entry_zone": "64.89~75.7",
|
||||||
"take_profit_zone": "0~71.43"
|
"take_profit_zone": "0~71.43"
|
||||||
},
|
},
|
||||||
"price": 62.58,
|
"price": 62.63,
|
||||||
"change_pct": -1.1
|
"change_pct": -1.03
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "02202",
|
"code": "02202",
|
||||||
@@ -417,8 +417,8 @@
|
|||||||
"entry_zone": "416.13~423.07",
|
"entry_zone": "416.13~423.07",
|
||||||
"take_profit_zone": "0~439.59"
|
"take_profit_zone": "0~439.59"
|
||||||
},
|
},
|
||||||
"price": 365.6,
|
"price": 365.25,
|
||||||
"change_pct": 0.24
|
"change_pct": 0.14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "00981",
|
"code": "00981",
|
||||||
@@ -452,8 +452,8 @@
|
|||||||
"entry_zone": "84.8~89.04",
|
"entry_zone": "84.8~89.04",
|
||||||
"take_profit_zone": "0~97.27"
|
"take_profit_zone": "0~97.27"
|
||||||
},
|
},
|
||||||
"price": 78.55,
|
"price": 78.99,
|
||||||
"change_pct": 6.72
|
"change_pct": 7.31
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "300548",
|
"code": "300548",
|
||||||
@@ -487,8 +487,8 @@
|
|||||||
"entry_zone": "253.19~265.85",
|
"entry_zone": "253.19~265.85",
|
||||||
"take_profit_zone": "0~300.43"
|
"take_profit_zone": "0~300.43"
|
||||||
},
|
},
|
||||||
"price": 273.16,
|
"price": 275.91,
|
||||||
"change_pct": 7.89
|
"change_pct": 8.97
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "518880",
|
"code": "518880",
|
||||||
@@ -557,8 +557,8 @@
|
|||||||
"entry_zone": "12.94~15.1",
|
"entry_zone": "12.94~15.1",
|
||||||
"take_profit_zone": "0~15.05"
|
"take_profit_zone": "0~15.05"
|
||||||
},
|
},
|
||||||
"price": 14.23,
|
"price": 14.24,
|
||||||
"change_pct": 0.28
|
"change_pct": 0.35
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "000700",
|
"code": "000700",
|
||||||
@@ -592,8 +592,8 @@
|
|||||||
"entry_zone": "13.32~14.09",
|
"entry_zone": "13.32~14.09",
|
||||||
"take_profit_zone": "0~15.54"
|
"take_profit_zone": "0~15.54"
|
||||||
},
|
},
|
||||||
"price": 14.7,
|
"price": 14.67,
|
||||||
"change_pct": 6.06
|
"change_pct": 5.84
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "600563",
|
"code": "600563",
|
||||||
@@ -627,8 +627,8 @@
|
|||||||
"entry_zone": "183.44~192.61",
|
"entry_zone": "183.44~192.61",
|
||||||
"take_profit_zone": "0~206.01"
|
"take_profit_zone": "0~206.01"
|
||||||
},
|
},
|
||||||
"price": 190.02,
|
"price": 189.6,
|
||||||
"change_pct": 0.33
|
"change_pct": 0.11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "01088",
|
"code": "01088",
|
||||||
@@ -662,16 +662,16 @@
|
|||||||
"entry_zone": "40.09~40.79",
|
"entry_zone": "40.09~40.79",
|
||||||
"take_profit_zone": "0~40.33"
|
"take_profit_zone": "0~40.33"
|
||||||
},
|
},
|
||||||
"price": 34.98,
|
"price": 35.03,
|
||||||
"change_pct": -1.95
|
"change_pct": -1.8
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"cash": 92678.85,
|
"cash": 92678.85,
|
||||||
"total_market_value": 835552.6,
|
"total_market_value": 835552.6,
|
||||||
"total_assets": 1000647.25,
|
"total_assets": 1001212.25,
|
||||||
"total_pl": 0,
|
"total_pl": 0,
|
||||||
"position_pct": 86.79,
|
"position_pct": 86.8,
|
||||||
"updated_at": "2026-06-30 11:10",
|
"updated_at": "2026-06-30 11:12",
|
||||||
"source": "/home/hmo/stocks/holding.xls",
|
"source": "/home/hmo/stocks/holding.xls",
|
||||||
"frozen_cash": 39481.4,
|
"frozen_cash": 39481.4,
|
||||||
"available_cash": 92678.85,
|
"available_cash": 92678.85,
|
||||||
@@ -689,7 +689,7 @@
|
|||||||
"timestamp": "2026-06-29 10:43"
|
"timestamp": "2026-06-29 10:43"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total_mv": 868487.0,
|
"total_mv": 869052.0,
|
||||||
"note": "cash fixed from screenshot 6/29, prices=CNY",
|
"note": "cash fixed from screenshot 6/29, prices=CNY",
|
||||||
"currency": "CNY",
|
"currency": "CNY",
|
||||||
"last_verified_at": "2026-06-29 22:28",
|
"last_verified_at": "2026-06-29 22:28",
|
||||||
|
|||||||
@@ -43,29 +43,23 @@ def main():
|
|||||||
try:
|
try:
|
||||||
import urllib.request
|
import urllib.request
|
||||||
code_raw = entry.get("code", "")
|
code_raw = entry.get("code", "")
|
||||||
sym_map = {"6":"sh","5":"sh","0":"sz","3":"sz"}
|
# 港股5位代码(含0开头)→ 前缀hk
|
||||||
prefix = ""
|
if len(code_raw) == 5 and code_raw[0] in '01':
|
||||||
for k, v in sym_map.items():
|
prefix = "hk"
|
||||||
if code_raw.startswith(k):
|
else:
|
||||||
prefix = v
|
sym_map = {"6":"sh","5":"sh","0":"sz","3":"sz"}
|
||||||
break
|
for k, v in sym_map.items():
|
||||||
|
if code_raw.startswith(k):
|
||||||
|
prefix = v
|
||||||
|
break
|
||||||
if not prefix:
|
if not prefix:
|
||||||
prefix = "hk" if len(code_raw) == 5 else "sz"
|
prefix = "sz"
|
||||||
url = f"http://qt.gtimg.cn/q={prefix}{code_raw}"
|
url = f"http://qt.gtimg.cn/q={prefix}{code_raw}"
|
||||||
resp = urllib.request.urlopen(url, timeout=5)
|
resp = urllib.request.urlopen(url, timeout=5)
|
||||||
text = resp.read().decode("gbk")
|
text = resp.read().decode("gbk")
|
||||||
fields = text.split('"')[1].split("~")
|
fields = text.split('"')[1].split("~")
|
||||||
price = float(fields[3]) if fields[3] else 0
|
price = float(fields[3]) if fields[3] else 0
|
||||||
# 港股:腾讯API返回HKD,统一转CNY
|
print(f" 实时价: {price} {'(港股HKD)' if len(code_raw) == 5 and code_raw[0] in '01' else ''}")
|
||||||
if len(code_raw) == 5 and code_raw[0] in '01':
|
|
||||||
try:
|
|
||||||
sys.path.insert(0, '/home/hmo/MoFin')
|
|
||||||
from hk_rate import hkd_to_cny
|
|
||||||
_hkd_rate = hkd_to_cny()
|
|
||||||
except Exception:
|
|
||||||
_hkd_rate = 0.87
|
|
||||||
price = round(price * _hkd_rate, 2)
|
|
||||||
print(f" 实时价: {price} {'(CNY)' if len(code_raw) == 5 and code_raw[0] in '01' else ''}")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" 实时价获取失败: {e}", file=sys.stderr)
|
print(f" 实时价获取失败: {e}", file=sys.stderr)
|
||||||
# Try portfolio.json as fallback (price_monitor keeps live prices)
|
# Try portfolio.json as fallback (price_monitor keeps live prices)
|
||||||
@@ -117,6 +111,8 @@ def main():
|
|||||||
|
|
||||||
# 更新 decisions_map 中对应的条目
|
# 更新 decisions_map 中对应的条目
|
||||||
updated = entry.copy()
|
updated = entry.copy()
|
||||||
|
# 币种标记:HK股保留HKD原始值,A股为CNY
|
||||||
|
is_hk = len(str(code)) == 5 and str(code)[0] in '01'
|
||||||
updated.update({
|
updated.update({
|
||||||
"action": result["action"],
|
"action": result["action"],
|
||||||
"stop_loss": result.get("stop_loss", entry.get("stop_loss")),
|
"stop_loss": result.get("stop_loss", entry.get("stop_loss")),
|
||||||
@@ -128,6 +124,7 @@ def main():
|
|||||||
"rr_ratio": result.get("rr_ratio", entry.get("rr_ratio", 0)),
|
"rr_ratio": result.get("rr_ratio", entry.get("rr_ratio", 0)),
|
||||||
"status": result.get("status", "updated"),
|
"status": result.get("status", "updated"),
|
||||||
"price": price,
|
"price": price,
|
||||||
|
"currency": "HKD" if is_hk else "CNY",
|
||||||
})
|
})
|
||||||
# Save last reassessed price for debounce tracking
|
# Save last reassessed price for debounce tracking
|
||||||
updated["last_reassessed_price"] = price
|
updated["last_reassessed_price"] = price
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ def fetch_prices(codes):
|
|||||||
if not oc:
|
if not oc:
|
||||||
continue
|
continue
|
||||||
p = float(fld[3]) if fld[3] else 0
|
p = float(fld[3]) if fld[3] else 0
|
||||||
|
# NOTE: HK stock prices kept in HKD — decisions.json also stores HK values in HKD
|
||||||
|
# (stop_loss/take_profit/entry). Never convert here or we mismatch CNY price vs HKD stop.
|
||||||
|
# Downstream tools that need CNY should convert at display time.
|
||||||
c = fld[32] if len(fld) > 32 else "0"
|
c = fld[32] if len(fld) > 32 else "0"
|
||||||
results[oc] = (p, c)
|
results[oc] = (p, c)
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
@@ -120,6 +123,10 @@ def main():
|
|||||||
|
|
||||||
issues, flags = [], []
|
issues, flags = [], []
|
||||||
tag = "[自选]" if is_wl else "[持仓]"
|
tag = "[自选]" if is_wl else "[持仓]"
|
||||||
|
# 币种标记(港股HKD vs A股CNY,辅助下游LLM避免混读)
|
||||||
|
currency_suffix = "(HKD)" if len(str(code)) == 5 and str(code)[0] in '01' else ""
|
||||||
|
price_str = f"{price:.2f}{currency_suffix}"
|
||||||
|
buy_zone_str = f"{el}~{eh}{currency_suffix}" if currency_suffix else f"{el}~{eh}"
|
||||||
|
|
||||||
# -- 偏离 --
|
# -- 偏离 --
|
||||||
if is_wl and el and eh:
|
if is_wl and el and eh:
|
||||||
@@ -152,16 +159,16 @@ def main():
|
|||||||
if strategy_deficient:
|
if strategy_deficient:
|
||||||
flags.append("[STRATEGY_STALE]")
|
flags.append("[STRATEGY_STALE]")
|
||||||
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
||||||
issues.append(f"[STRATEGY_STALE] {prefix}价{price:.2f}在买入区{el}~{eh}但策略不完整({'RR='+f'{rr:.2f}<1.5' if rr_invalid else '无止盈位' if not tp else '非买入信号'}),买入区需重评")
|
issues.append(f"[STRATEGY_STALE] {prefix}价{price_str}在买入区{buy_zone_str}但策略不完整({'RR='+f'{rr:.2f}<1.5' if rr_invalid else '无止盈位' if not tp else '非买入信号'}),买入区需重评")
|
||||||
else:
|
else:
|
||||||
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
||||||
issues.append(f"[PUSH] {prefix}价{price:.2f}入买入区{el}~{eh}")
|
issues.append(f"[PUSH] {prefix}价{price_str}入买入区{buy_zone_str}")
|
||||||
elif price > eh * 1.35:
|
elif price > eh * 1.35:
|
||||||
flags.append("[WL_HIGH]")
|
flags.append("[WL_HIGH]")
|
||||||
issues.append(f"价{price:.2f}高出买入区+{((price/eh)-1)*100:.0f}%,买入区需重评")
|
issues.append(f"价{price_str}高出买入区+{((price/eh)-1)*100:.0f}%,买入区需重评")
|
||||||
elif price > eh * 1.20:
|
elif price > eh * 1.20:
|
||||||
flags.append("[WL_DRIFT]")
|
flags.append("[WL_DRIFT]")
|
||||||
issues.append(f"价{price:.2f}高于买入区+{((price/eh)-1)*100:.0f}%")
|
issues.append(f"价{price_str}高于买入区+{((price/eh)-1)*100:.0f}%")
|
||||||
elif not is_wl and eh:
|
elif not is_wl and eh:
|
||||||
dp = (price / eh - 1) * 100
|
dp = (price / eh - 1) * 100
|
||||||
if dp > 35:
|
if dp > 35:
|
||||||
@@ -215,7 +222,7 @@ def main():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if issues:
|
if issues:
|
||||||
print(f"{' '.join(flags)} {tag} {name}({code}) 价{price:.2f}{chg} | 买入{el}~{eh} | {'; '.join(issues)}")
|
print(f"{' '.join(flags)} {tag} {name}({code}) 价{price_str}{chg} | 买入{el}~{eh} | {'; '.join(issues)}")
|
||||||
found += 1
|
found += 1
|
||||||
|
|
||||||
if found == 0:
|
if found == 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user