From 8f830b8de2c1cf342922b1180cd9af9dba8287d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Wed, 24 Jun 2026 14:39:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=A1=E4=B9=89=E5=85=89=E8=83=BD=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=EF=BC=9A=E4=B8=A4=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E8=BF=87=E6=BB=A4+=E8=B6=8B=E5=8A=BF=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug 1 — strategy_lifecycle.py: enrich_timing_signal 用 factors[-1] 当信号 信义光能: base_signal=neutral, factors=[大盘中性,行业偏弱,高估值] 旧逻辑: factors[-1]='行业偏弱'→成为timing_signal→无效信号 新逻辑: 先找有效操作方向(买入/加仓/观望/持有/关注/信号不充分), 找不到→信号不充分。不再从上下文因子里拼凑信号。 Bug 2 — stale_push_wlin.py: 信号过滤太松 旧逻辑: 只跳过特定关键词(等企稳/关注/信号不充分/持有) 新逻辑: 信号必须含"买入"或"加仓"才进推荐,其他一律跳过 Check 3 — 趋势检查(新增) fetch_trend_data(): 取实时行情+30日K线计算MA排列 空头排列/弱势震荡→不推荐 药明康德通过(多头排列+买入信号) 信义光能不通过(空头+行业偏弱) --- .../strategy_lifecycle.cpython-312.pyc | Bin 69486 -> 69701 bytes data/decisions.json | 239 +++++++++++++----- data/portfolio.json | 92 +++++-- data/price_history.json | 10 +- scripts/stale_push_wlin.py | 98 ++++++- strategy_lifecycle.py | 18 +- 6 files changed, 351 insertions(+), 106 deletions(-) diff --git a/__pycache__/strategy_lifecycle.cpython-312.pyc b/__pycache__/strategy_lifecycle.cpython-312.pyc index 8be88f34cee317630f6459ba4abf6bf9df27cb57..9600637487317d8ba3da18b509e416031c90153f 100644 GIT binary patch delta 3207 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 delta 2976 zcma)8dr(x@8Rsm!3+#3QrLYKUm!~d9!50alOpH|-PtI@Ga zszx*=r1MFzid6g15o3&V$s`dUu|DDqOoFyEajtD`I})ntppByFG?Sj+S&Gi|pEAR5 zzw^D$`5xyx_xwI{f15eE%i*xaiN6mQmsg+6IhO2P!J>NMiqj@nJd2CtW`IS28ZVSw zu6kZ5etDAM(0pH^eVj?GY*4c6rOJTGnhkm^O%5z}3_Ebgb1O9l3e5jCqdx^)%&vbE zxX4&0U8v4uF8yZp%gj0o)>*Wmw!>Zqat5GWPpaF=*a&J1<=Ur%GZj!uU7_XH$sjXn za=3`ir&q#1Vbkb%c)HyMcA@}Pq2e+prA8Lh@<=vo);C0ckj8fD=Qp2WBU^-mI9wS* zN&#%AU0d_nZvEueZ%pY{AvIV)6(NeqhXSY18@5|p;e9W?y8X?vr$H`-?Ho8uFj&M$ zh=f&7#HaDS5Vi?064xr;8jmle85S+9d29JW%H2`I-qU}$!^bjY(#Ak}EMT;N7rB|b z-<-vC-S+d3O>D1z?yW`4dI;h}dgj}onOQOQ?ObC$4bCa@HRqc;8HG1z(65?HiaG_? zi1#Z#UVx*W!qTMr4U^{Q7qGB$#jA!x{470aE@9nz(K{Y!8%u(X5pwwob}zhq8>#%Dtf)#n1PHvt3vk@gf2I5A@U4`RuBGzV!{p z>h;RD(nM#%hB!Z~c@jHphzprF*!;6c2?M%zU?TfKcN}atu?h6ip|ZT+3187nA?oYg z())J9^-j8evhmBd*KcfV9A8mZQsCylrSG=qE6bD{2*B9R$(M! zSla$Xb`-_EetLgz(}&kTYV6&*wYT979uPdYjXK*GnA}-3;_x{8G6W#|?iHGIc!mAX zSYHDK=>5Y>OlsCpFIma)P6EB~Zo2KEkXp^6&A7h$-5KWmyh-m*_+-@ODGPp4-c$8b z&yQZdRJE+W@`~NL%h_Xh^_X3QcWY?GF;`Yqk?GUqJmAy}fjvbjRkJKTGg;Lv{kdbo z1fOi+d*X<(THsXfBz^;jxe53R@YsQ|{5RD9394U!k*o$+g}k+%m0q6~<|;n{$w`20 z_@~JEacAl8#X6cQ3|+3?rp6lw8hTH)_q}y=hKrvSlJz#%cr{$>_jt8gvWs{M>`N)} zcnLd0WygyH69vOCd!t&|oz9yf-GgH+15^N-080S7Al(fp!4kRS?*T?)nFbgE(7`(k z>H|PFpqqM*&&{fYWFa6nDL}1T-@1xi*HGnbcQIRy~KavZ1vz<2=zR>Ax7$glhM zH1I-dI_DWdf@>s&l(n9Smuo6-r*F??+f3LU@DDxz{0b(v-*#b%Ib$FEd@ev0|8Yap z>k@s@Rm8^8n69z*4k%m(WYN5?Io2%rnL?y3A^^@XS{OngLF_b~|HJ7Tm;o29!gb$!&hDJhE;m*&;qn@-(O(fD`%t+y|8o zUJf7^&<0)}sC^o?jG#$M;q^X@?$%~Z7B@p8=JJY)}v}+UyW**A}jg#h~3YwJOZ2VLvgMEBY`Vw zv{noT#9$ zM^%(v>=@x1e3+s671a%9jvgM?+ydqVaUR2h=JE1k+CTUN%cIW*Gnte61}j*pUije0 z%(78vmg!p_+R|8jOOu1W%I3H9JJ=ZeOgLW%KNT$*$t*XsQqYF|*}6!WYjZgdb3PB! z`7Kq+Y;Luz;-g~8M@oka`2p4q>MB515$}VX|8fj-OgWB&7>OQF$Xlm)Jh9K{4p`vx p`C;PBy0AZ5t5oo9E#D@yD+y~D%ek$^xBMlAm9r%+S*dKoe*kz#Fwp=2 diff --git a/data/decisions.json b/data/decisions.json index d54f0d4..7254fa7 100644 --- a/data/decisions.json +++ b/data/decisions.json @@ -85,17 +85,17 @@ { "code": "000711", "name": "ST京蓝", - "price": 5.05, + "price": 5.06, "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | ⚠️盈亏比偏低(1:1.7),谨慎买入 | 目标5.38 | 止损4.86 | 买入区4.95~5.07 | 信号:观望", + "action": "盈利持有 | ⚠️盈亏比偏低(1:1.6),谨慎买入 | 目标5.38 | 止损4.86 | 买入区4.96~5.07 | 信号:观望", "stop_loss": 4.86, - "entry_low": 4.95, + "entry_low": 4.96, "entry_high": 5.07, "tech_snapshot": "形态:长影星线/neutral 量价:主动卖盘占优 强撑:4.86 弱撑:4.86 弱压:5.25 强压:5.38", "timing_signal": "观望", - "rr_ratio": 1.74, + "rr_ratio": 1.6, "status": "updated", "note": "⚠️盈亏比偏低(1:1.6),谨慎买入", "timestamp": "2026-06-24 14:23", @@ -140,12 +140,12 @@ "condition": { "scenario": "weak_consolidation", "price": "<=5.07", - "price_lower": ">=4.95" + "price_lower": ">=4.96" }, "action": { "type": "buy", "amount": "normal", - "limit": 4.95, + "limit": 4.96, "reason": "回调支撑买入" }, "priority": 1, @@ -352,17 +352,17 @@ { "code": "002594", "name": "比亚迪", - "price": 83.45, + "price": 83.44, "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | 目标92.76 | 止损80.95 | 买入区81.78~85.12 | 信号:观望", - "stop_loss": 80.95, - "entry_low": 81.78, - "entry_high": 85.12, - "tech_snapshot": "形态:带下影阴线/neutral 量价:主动卖盘占优 强撑:76.5 弱撑:82.59 弱压:85.0 强压:92.76", + "action": "盈利持有 | 目标92.76 | 止损80.94 | 买入区81.77~85.11 | 信号:观望", + "stop_loss": 80.94, + "entry_low": 81.77, + "entry_high": 85.11, + "tech_snapshot": "形态:带下影阴线/neutral 量价:主动卖盘占优 强撑:76.5 弱撑:82.58 弱压:85.0 强压:92.76", "timing_signal": "观望", - "rr_ratio": 3.72, + "rr_ratio": 3.73, "status": "updated", "note": "", "timestamp": "2026-06-24 14:23", @@ -389,7 +389,7 @@ { "id": "002594_stop_loss", "condition": { - "price": "<80.95" + "price": "<80.94" }, "action": { "type": "sell", @@ -406,13 +406,13 @@ "id": "002594_buy_dip", "condition": { "scenario": "weak_consolidation", - "price": "<=85.12", - "price_lower": ">=81.78" + "price": "<=85.11", + "price_lower": ">=81.77" }, "action": { "type": "buy", "amount": "normal", - "limit": 81.78, + "limit": 81.77, "reason": "回调支撑买入" }, "priority": 1, @@ -2391,13 +2391,13 @@ "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | 目标180.8 | 止损155.91 | 买入区162.39~168.76", - "stop_loss": 155.91, + "action": "盈利持有 | 目标180.97 | 止损160.73 | 买入区162.39~168.83", + "stop_loss": 160.73, "entry_low": 162.39, - "entry_high": 168.76, - "tech_snapshot": "形态:倒T线/射击之星/bearish 量价:数据不足 强撑:151.2 弱撑:160.9 弱压:168.2 强压:180.8", - "timing_signal": "行业偏强", - "rr_ratio": 3.04, + "entry_high": 168.83, + "tech_snapshot": "形态:带上影阳线/neutral 量价:数据不足 强撑:151.29 弱撑:160.9 弱压:168.47 强压:180.97", + "timing_signal": "信号不充分", + "rr_ratio": 3.07, "status": "updated", "note": "", "timestamp": "2026-06-24 14:24", @@ -2409,7 +2409,7 @@ "position_advice": "正常配置", "time_horizon": "数月~1年", "created_at": "2026-06-24 14:24", - "take_profit": 180.8, + "take_profit": 180.97, "changelog": [ { "date": "2026-06-24 14:24", @@ -2418,7 +2418,110 @@ "reason": "初始策略创建 | 形态:倒T线/射击之星/bearish 量价:数据不足 强撑:151.2 弱撑:160.9 弱压:168.2 强压:18", "trigger": "初始创建" } - ] + ], + "strategy_tree": { + "branches": [ + { + "id": "06160_stop_loss", + "condition": { + "price": "<160.73" + }, + "action": { + "type": "sell", + "amount": "all", + "reason": "止损" + }, + "priority": 0, + "rationale": "止损保护本金", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + }, + { + "id": "06160_buy_dip", + "condition": { + "scenario": "weak_consolidation", + "price": "<=168.83", + "price_lower": ">=162.39" + }, + "action": { + "type": "buy", + "amount": "normal", + "limit": 162.39, + "reason": "回调支撑买入" + }, + "priority": 1, + "rationale": "价格回调到支撑区,弱势市场低吸", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + }, + { + "id": "06160_breakout_chase", + "condition": { + "scenario": "bullish_recovery", + "price": ">=180.97" + }, + "action": { + "type": "buy", + "amount": "normal", + "limit": "market", + "reason": "突破确认追涨" + }, + "priority": 2, + "rationale": "价格突破阻力,确认上升趋势后买入", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + }, + { + "id": "06160_trim", + "condition": { + "scenario": "sharp_decline", + "loss_pct": "<-15%" + }, + "action": { + "type": "sell", + "amount": "half", + "reason": "急跌降风险" + }, + "priority": 3, + "rationale": "急跌市场,深套股减半仓减少敞口", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + }, + { + "id": "06160_take_profit", + "condition": { + "price": ">=180.97" + }, + "action": { + "type": "sell", + "amount": "half", + "reason": "止盈锁利" + }, + "priority": 4, + "rationale": "达到目标价,减半仓锁定利润", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + }, + { + "id": "06160_hold", + "condition": {}, + "action": { + "type": "hold", + "reason": "无明确信号,继续持有" + }, + "priority": 99, + "rationale": "没有分支匹配时的默认动作", + "trigger_count": 0, + "success_rate": null, + "last_triggered": null + } + ] + } }, { "code": "06869", @@ -3191,17 +3294,17 @@ { "code": "300124", "name": "汇川技术", - "price": 66.41, + "price": 66.53, "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | 目标73.17 | 止损64.42 | 买入区65.08~67.74 | 信号:观望", - "stop_loss": 64.42, - "entry_low": 65.08, - "entry_high": 67.74, - "tech_snapshot": "形态:倒T线/射击之星/bearish 量价:主动卖盘占优 强撑:59.93 弱撑:65.6 弱压:67.35 强压:73.17", + "action": "盈利持有 | 目标73.2 | 止损64.53 | 买入区65.2~67.86 | 信号:观望", + "stop_loss": 64.53, + "entry_low": 65.2, + "entry_high": 67.86, + "tech_snapshot": "形态:长影星线/neutral 量价:主动卖盘占优 强撑:59.96 弱撑:65.68 弱压:67.43 强压:73.2", "timing_signal": "观望", - "rr_ratio": 3.4, + "rr_ratio": 3.34, "status": "updated", "note": "", "timestamp": "2026-06-24 14:24", @@ -3213,7 +3316,7 @@ "position_advice": "减仓或观望", "time_horizon": "观望", "created_at": "2026-06-24 14:24", - "take_profit": 73.17, + "take_profit": 73.2, "changelog": [ { "date": "2026-06-24 14:24", @@ -3228,7 +3331,7 @@ { "id": "300124_stop_loss", "condition": { - "price": "<64.42" + "price": "<64.53" }, "action": { "type": "sell", @@ -3245,13 +3348,13 @@ "id": "300124_buy_dip", "condition": { "scenario": "weak_consolidation", - "price": "<=67.74", - "price_lower": ">=65.08" + "price": "<=67.86", + "price_lower": ">=65.2" }, "action": { "type": "buy", "amount": "normal", - "limit": 65.08, + "limit": 65.2, "reason": "回调支撑买入" }, "priority": 1, @@ -3264,7 +3367,7 @@ "id": "300124_breakout_chase", "condition": { "scenario": "bullish_recovery", - "price": ">=73.17" + "price": ">=73.2" }, "action": { "type": "buy", @@ -3298,7 +3401,7 @@ { "id": "300124_take_profit", "condition": { - "price": ">=73.17" + "price": ">=73.2" }, "action": { "type": "sell", @@ -3990,17 +4093,17 @@ { "code": "601318", "name": "中国平安", - "price": 49.1, + "price": 49.12, "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | 目标53.6 | 止损47.63 | 买入区48.12~50.02 | 信号:观望", - "stop_loss": 47.63, - "entry_low": 48.12, - "entry_high": 50.02, - "tech_snapshot": "形态:光头光脚阴线/bearish 量价:主动卖盘占优 强撑:45.74 弱撑:48.46 弱压:50.4 强压:53.6", + "action": "盈利持有 | 目标53.61 | 止损47.65 | 买入区48.14~50.03 | 信号:观望", + "stop_loss": 47.65, + "entry_low": 48.14, + "entry_high": 50.03, + "tech_snapshot": "形态:光头光脚阴线/bearish 量价:主动卖盘占优 强撑:45.75 弱撑:48.47 弱压:50.4 强压:53.61", "timing_signal": "观望", - "rr_ratio": 3.06, + "rr_ratio": 3.05, "status": "updated", "note": "", "timestamp": "2026-06-24 14:24", @@ -4012,7 +4115,7 @@ "position_advice": "减仓或观望", "time_horizon": "观望", "created_at": "2026-06-24 14:24", - "take_profit": 53.6, + "take_profit": 53.61, "changelog": [ { "date": "2026-06-24 14:24", @@ -4027,7 +4130,7 @@ { "id": "601318_stop_loss", "condition": { - "price": "<47.63" + "price": "<47.65" }, "action": { "type": "sell", @@ -4044,13 +4147,13 @@ "id": "601318_buy_dip", "condition": { "scenario": "weak_consolidation", - "price": "<=50.02", - "price_lower": ">=48.12" + "price": "<=50.03", + "price_lower": ">=48.14" }, "action": { "type": "buy", "amount": "normal", - "limit": 48.12, + "limit": 48.14, "reason": "回调支撑买入" }, "priority": 1, @@ -4063,7 +4166,7 @@ "id": "601318_breakout_chase", "condition": { "scenario": "bullish_recovery", - "price": ">=53.6" + "price": ">=53.61" }, "action": { "type": "buy", @@ -4097,7 +4200,7 @@ { "id": "601318_take_profit", "condition": { - "price": ">=53.6" + "price": ">=53.61" }, "action": { "type": "sell", @@ -4705,17 +4808,17 @@ { "code": "688795", "name": "摩尔线程-U", - "price": 705.0, + "price": 704.0, "cost": 0, "shares": 0, "avg_price": 0, - "action": "盈利持有 | 目标831.84 | 止损676.81 | 买入区690.9~719.1 | 信号:观望", - "stop_loss": 676.81, - "entry_low": 690.9, - "entry_high": 719.1, - "tech_snapshot": "形态:带下影阳线/neutral 量价:主动卖盘占优 强撑:563.22 弱撑:676.81 弱压:725.39 强压:831.84", + "action": "盈利持有 | 目标831.51 | 止损676.14 | 买入区689.92~718.08 | 信号:观望", + "stop_loss": 676.14, + "entry_low": 689.92, + "entry_high": 718.08, + "tech_snapshot": "形态:锤子线/T字线/neutral 量价:主动卖盘占优 强撑:563.22 弱撑:676.14 弱压:724.72 强压:831.51", "timing_signal": "观望", - "rr_ratio": 4.5, + "rr_ratio": 4.58, "status": "updated", "note": "", "timestamp": "2026-06-24 14:24", @@ -4727,7 +4830,7 @@ "position_advice": "正常配置", "time_horizon": "数月~1年", "created_at": "2026-06-24 14:24", - "take_profit": 831.84, + "take_profit": 831.51, "changelog": [ { "date": "2026-06-24 14:24", @@ -4742,7 +4845,7 @@ { "id": "688795_stop_loss", "condition": { - "price": "<676.81" + "price": "<676.14" }, "action": { "type": "sell", @@ -4759,13 +4862,13 @@ "id": "688795_buy_dip", "condition": { "scenario": "weak_consolidation", - "price": "<=719.1", - "price_lower": ">=690.9" + "price": "<=718.08", + "price_lower": ">=689.92" }, "action": { "type": "buy", "amount": "normal", - "limit": 690.9, + "limit": 689.92, "reason": "回调支撑买入" }, "priority": 1, @@ -4778,7 +4881,7 @@ "id": "688795_breakout_chase", "condition": { "scenario": "bullish_recovery", - "price": ">=831.84" + "price": ">=831.51" }, "action": { "type": "buy", @@ -4812,7 +4915,7 @@ { "id": "688795_take_profit", "condition": { - "price": ">=831.84" + "price": ">=831.51" }, "action": { "type": "sell", @@ -5028,5 +5131,5 @@ } ], "total": 39, - "regenerated_at": "2026-06-24 14:25" + "regenerated_at": "2026-06-24 14:37" } \ No newline at end of file diff --git a/data/portfolio.json b/data/portfolio.json index e37f270..1908c91 100644 --- a/data/portfolio.json +++ b/data/portfolio.json @@ -25,7 +25,9 @@ "rr_ratio": 0.51, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 8.52, + "change_pct": -0.23 }, { "code": "600563", @@ -52,7 +54,9 @@ "rr_ratio": 3.54, "action_note": "", "timing_signal": "持有" - } + }, + "price": 178.76, + "change_pct": 10.0 }, { "code": "601899", @@ -79,7 +83,9 @@ "rr_ratio": 0.71, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 27.59, + "change_pct": -0.58 }, { "code": "603259", @@ -106,7 +112,9 @@ "rr_ratio": 3.44, "action_note": "", "timing_signal": "持有" - } + }, + "price": 115.11, + "change_pct": 8.28 }, { "code": "688411", @@ -133,7 +141,9 @@ "rr_ratio": 0.98, "action_note": "⚠️盈亏比偏低(1:1.0),不建议加仓", "timing_signal": "持有" - } + }, + "price": 266.44, + "change_pct": -2.13 }, { "code": "688639", @@ -160,7 +170,9 @@ "rr_ratio": 1.09, "action_note": "⚠️盈亏比偏低(1:1.1),不建议加仓", "timing_signal": "持有" - } + }, + "price": 21.43, + "change_pct": -1.83 }, { "code": "688981", @@ -187,7 +199,9 @@ "rr_ratio": 2.34, "action_note": "", "timing_signal": "持有" - } + }, + "price": 151.59, + "change_pct": 6.98 }, { "code": "000700", @@ -214,7 +228,9 @@ "rr_ratio": 3.83, "action_note": "", "timing_signal": "持有" - } + }, + "price": 14.5, + "change_pct": -3.2 }, { "code": "001309", @@ -241,7 +257,9 @@ "rr_ratio": 0.03, "action_note": "⚠️盈亏比偏低(1:0.5),不建议加仓", "timing_signal": "持有" - } + }, + "price": 803.93, + "change_pct": 6.48 }, { "code": "300035", @@ -268,7 +286,9 @@ "rr_ratio": 0.98, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 16.02, + "change_pct": -2.08 }, { "code": "300548", @@ -295,7 +315,9 @@ "rr_ratio": 5.93, "action_note": "短炒强趋势持", "timing_signal": "持有" - } + }, + "price": 280.8, + "change_pct": -1.83 }, { "code": "300750", @@ -322,7 +344,9 @@ "rr_ratio": 0.9, "action_note": "⚠️盈亏比偏低(1:0.9),不建议加仓", "timing_signal": "弱势持有" - } + }, + "price": 395.88, + "change_pct": 0.86 }, { "code": "00700", @@ -349,7 +373,9 @@ "rr_ratio": 0.95, "action_note": "⚠️盈亏比偏低(1:1.0),不建议加仓", "timing_signal": "持有" - } + }, + "price": 430.0, + "change_pct": 3.66 }, { "code": "00981", @@ -376,7 +402,9 @@ "rr_ratio": 3.21, "action_note": "", "timing_signal": "持有" - } + }, + "price": 84.45, + "change_pct": 8.48 }, { "code": "01088", @@ -403,7 +431,9 @@ "rr_ratio": 0.92, "action_note": "⚠️盈亏比偏低(1:0.9),不建议加仓", "timing_signal": "持有" - } + }, + "price": 41.86, + "change_pct": -0.33 }, { "code": "01211", @@ -430,7 +460,9 @@ "rr_ratio": 0.95, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 76.1, + "change_pct": 0.33 }, { "code": "01478", @@ -457,7 +489,9 @@ "rr_ratio": 0.99, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 7.7, + "change_pct": -2.28 }, { "code": "01888", @@ -484,7 +518,9 @@ "rr_ratio": 7.36, "action_note": "短炒强趋势持", "timing_signal": "持有" - } + }, + "price": 94.6, + "change_pct": 8.42 }, { "code": "02202", @@ -511,7 +547,9 @@ "rr_ratio": 1.11, "action_note": "深套持有", "timing_signal": "持有" - } + }, + "price": 2.35, + "change_pct": -1.67 }, { "code": "02318", @@ -538,7 +576,9 @@ "rr_ratio": 14.89, "action_note": "⚠️盈亏比偏低(1:1.0),不建议加仓", "timing_signal": "持有" - } + }, + "price": 52.75, + "change_pct": -1.59 }, { "code": "02388", @@ -565,7 +605,9 @@ "rr_ratio": 2.45, "action_note": "", "timing_signal": "持有" - } + }, + "price": 46.78, + "change_pct": -0.47 }, { "code": "06869", @@ -592,7 +634,9 @@ "rr_ratio": 7.68, "action_note": "短炒强趋势持", "timing_signal": "持有" - } + }, + "price": 264.8, + "change_pct": 0.08 }, { "code": "09868", @@ -619,7 +663,9 @@ "rr_ratio": 21.64, "action_note": "⚠️盈亏比偏低(1:1.0),不建议加仓", "timing_signal": "持有" - } + }, + "price": 49.5, + "change_pct": 0.28 } ], "cash": 20371, diff --git a/data/price_history.json b/data/price_history.json index 5b6b264..ecaf37e 100644 --- a/data/price_history.json +++ b/data/price_history.json @@ -108,7 +108,7 @@ "date": "2026-06-24", "high": 88.32, "low": 82.78, - "close": 83.45 + "close": 83.44 } ], "00700": [ @@ -1004,7 +1004,7 @@ "date": "2026-06-24", "high": 168.6, "low": 160.0, - "close": 165.6 + "close": 166.0 } ], "06869": [ @@ -1284,7 +1284,7 @@ "date": "2026-06-24", "high": 68.8, "low": 65.74, - "close": 66.41 + "close": 66.52 } ], "300548": [ @@ -2316,7 +2316,7 @@ "date": "2026-06-24", "high": 745.2, "low": 660.01, - "close": 705.0 + "close": 704.0 } ], "688802": [ @@ -2610,7 +2610,7 @@ "date": "2026-06-24", "high": 52.43, "low": 49.03, - "close": 49.1 + "close": 49.12 } ], "002171": [ diff --git a/scripts/stale_push_wlin.py b/scripts/stale_push_wlin.py index bc71ea2..848d673 100644 --- a/scripts/stale_push_wlin.py +++ b/scripts/stale_push_wlin.py @@ -27,6 +27,72 @@ except ImportError: sys.path.insert(0, "/home/hmo/MoFin/scripts") from stock_scorer import score_future_outlook, is_hk_stock, settlement_delay_note +# ── 趋势检查 ──────────────────────────────────────────────────── +def fetch_trend_data(code): + """取均线数据判断趋势状态。返回 (current_price, ma5, trend_label) 或 None""" + try: + prefix = "sh" if code.startswith(('60','68','51','56','50')) else "sz" if code.startswith(('00','30','15')) else "hk" + url = f"http://qt.gtimg.cn/q={prefix}{code}" + req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) + resp = urlopen(req, timeout=5).read().decode('gbk') + fld = resp.split('=')[1].strip().strip('"').strip(';').split('~') + current = float(fld[3]) if len(fld) > 3 else 0 + except: + return None + + try: + url = f"http://ifzq.gtimg.cn/appstock/app/fqkline/get?param={prefix}{code},day,,,30,qfq" + req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) + resp = urlopen(req, timeout=5).read().decode('utf-8') + data = json.loads(resp) + day_key = 'qfqday' if prefix != 'hk' else 'day' + bars = data.get('data', {}).get(f'{prefix}{code}', {}).get(day_key, []) + except: + return None + + if not bars or current <= 0: + return None + closes = [float(b[2]) for b in bars] + if len(closes) < 5: + return None + + def ma(n): + return sum(closes[-n:]) / n + ma5 = ma(5) + ma10 = ma(10) if len(closes) >= 10 else None + ma20 = ma(20) if len(closes) >= 20 else None + + # 趋势分析 + pct_above_ma5 = (current - ma5) / ma5 * 100 + uptrend = False + + if ma20 and ma10: + if ma5 > ma10 > ma20: + trend_label = "多头排列" + uptrend = True + elif current < ma5 and ma5 < ma10 and current < ma10: + trend_label = "空头排列" + elif current > ma5 and ma5 > ma10: + trend_label = "短期转强" + uptrend = True + else: + trend_label = "震荡" + if current > ma5 > ma10: + uptrend = True + else: + trend_label = "数据不足" + + return { + 'price': current, + 'ma5': round(ma5, 2), + 'ma10': round(ma10, 2) if ma10 else None, + 'ma20': round(ma20, 2) if ma20 else None, + 'pct_above_ma5': round(pct_above_ma5, 1), + 'trend': trend_label, + 'uptrend': uptrend, + } + +# ── XMPP XMPP_BRIDGE = "http://127.0.0.1:5805/" XMPP_USER = "hmo@yoin.fun" @@ -278,10 +344,11 @@ def main(): -code_data.get(s[1], {}).get("rr_ratio", 0) )) - # 只展示有清晰操作信号的个股:不含"等企稳""关注""信号不充分""neutral"及纯持有信号 - SKIP_KEYWORDS = ["等企稳", "关注", "信号不充分"] - - BUY_KEYWORDS = ["买入", "加仓"] + # 只展示有清晰操作信号的个股 + # timing_signal 必须是明确操作方向:买入/加仓/观望/关注/信号不充分 + # 行业描述(行业偏弱/行业偏强/大盘变盘等)不是操作信号,一律跳过 + VALID_SIGNALS = {"买入", "加仓", "观望", "关注", "信号不充分"} + SKIP_KEYWORDS = ["等企稳", "信号不充分"] actionable = [] for s in stocks: @@ -292,9 +359,19 @@ def main(): if any(kw in sig for kw in SKIP_KEYWORDS): continue # 中性信号跳过 - stripped = sig.strip().lower() - if not stripped or stripped in ("", "neutral", "持有", "深套持有", "弱势持有"): + stripped = sig.strip() + if not stripped or stripped.lower() in ("", "neutral", "持有", "深套持有", "弱势持有"): continue + # 信号必须含买入/加仓才推荐——其他非操作信号跳过 + if not any(kw in sig for kw in ["买入", "加仓"]): + continue + # 趋势检查:必须不是空头排列(价格在MA5以下且MA5