硬性策略质量门禁 validate_strategy()
新增 STRATEGY_QUALITY_GATES 检查清单(9条红线): CRITICAL: 止损/止盈存在+>0, 买入区下沿<上沿 HIGH: 止损≤买入区, 买入推荐含RR≥1.5, 港股标currency=HKD MEDIUM: signal短词, tech_snapshot含技术位 enforce_strategy_quality() 插在写入链的两处: 1. reassess_with_context() return前 → 单只重评必过 2. regenerate_all() for d in decisions: 写DB前 → 批量重评必过 不过的:status=review_needed, signal降级→信号不充分 不会写进DB/JSON,除非修复了CRITICAL问题
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,22 @@
|
||||
记录知微对MoFin系统的缺陷修复和知识萃取项。
|
||||
|
||||
## 2026-07-02 11:30 macro_context_collector.py Pattern 9 百分比阈值修复 + 跨句涨幅匹配修复
|
||||
|
||||
**发现了什么:** 自愈执行器报告false positive——"中概领涨"被标记为HIGH风险。追踪发现Pattern 9 `指数[^。]*?(?:跌幅|下跌)[^。]*?[2-9]%`有两个Bug:
|
||||
1. 小数阈值Bug: `[2-9]%`在"0.3%"中提取"3%"匹配,误将<2%跌幅标为HIGH
|
||||
2. 跨句匹配Bug: "指数集体下跌的背景下...中概收涨近3%"中,`[^。]*?`跨过整个句子把"下跌"和"3%"连起来,但"下跌"是指美股下跌,"3%"是指中概收涨——两个不同语境
|
||||
|
||||
**修改了什么:**
|
||||
- 文件: `/home/hmo/MoFin/scripts/macro_context_collector.py`
|
||||
- Pattern 9: `指数[^。]*?(?:跌幅|下跌)[^。]*?[2-9]%` →
|
||||
`指数[^。]*?(?:跌幅[^。]{0,20}(?:扩大至|达|至|超|为|逾)[^。]*?(?<![0-9.])(?:[2-9]|[1-9][0-9])(?:\.\d+)?%|下跌(?!.*?涨)[^。]*?(?<![0-9.])(?:[2-9]|[1-9][0-9])(?:\.\d+)?%)`
|
||||
- "跌幅"分支:要求跌幅后有测量词(扩大至/达/至/超/为/逾),防止"跌幅"和其他分句的"%"跨句匹配
|
||||
- "下跌"分支:用`(?!.*?涨)`负向前瞻阻断含有"涨"的上下文(如"收涨近3%")
|
||||
- 阈值修复:`(?<![0-9.])(?:[2-9]|[1-9][0-9])(?:\.\d+)?%` 防止"0.3%"中"3%"被提取
|
||||
- Pattern 10: `(?:暴跌|重挫|熔断).*[5-9]%` → 同样加小数排除 + 改成`[5-9]|[1-9][0-9]`范围
|
||||
- `_PATTERN_CHECKS`和`_KNOWN_BAD_SIGS`同步更新
|
||||
- `intraday_health_check.py`: 宏观风险HIGH去重,防止同一风险状态累积多个TODO
|
||||
|
||||
## 2026-06-23 09:00 数据采集脚本修复
|
||||
|
||||
**发现了什么:** `market_watch.py` cron任务报错,exit code 1
|
||||
@@ -132,3 +149,52 @@
|
||||
- 严禁从 multi_tf_cache.json / decisions.json 等缓存文件直接读取价格数据来推操作建议
|
||||
- 唯一允许的价格源:腾讯实时 API(qt.gtimg.cn)或 price_monitor 刚写入的 events/state
|
||||
- 违反这条 → 自动回滚,追加到违规记录
|
||||
|
||||
## 2026-07-02 10:00 盘中自检 NameError 修复
|
||||
|
||||
**发现了什么:** 自愈执行器报 `盘中自检: 价格数据新鲜度检查失败: name 'mo_data' is not defined`
|
||||
- 根因:`intraday_health_check.py` 第11行用 `from mo_data import read_portfolio`(直接导入函数),但第117行写的是 `mo_data.read_portfolio()`(当模块名调用)
|
||||
|
||||
**修改了什么:**
|
||||
- 文件:`/home/hmo/MoFin/scripts/intraday_health_check.py`
|
||||
- 变更:`mo_data.read_portfolio()` → `read_portfolio()`
|
||||
|
||||
**效果预期:** 盘中自检不再因这个 NameError 报异常,能正常检查 portfolio.json 数据新鲜度。
|
||||
|
||||
## 2026-07-02 10:51 宏观风险HIGH升级应对
|
||||
|
||||
**发现了什么:** 自愈执行器上报当日第二次HIGH信号(科创50扩大至-5%、创业板-4%)。同时KOSPI从-7%收窄至-3%(改善方向信号)。
|
||||
|
||||
**修改了什么:**
|
||||
- 文件:`macro_risk_state.json`
|
||||
- 变更:升级模式更新state,分别标注恶化(科创50/创业板扩大跌幅)和改善(KOSPI收窄、恒指+1.3%)两个方向,避免笼统"附加新数据点"
|
||||
|
||||
**萃取知识:**
|
||||
1. B类板块冲击下,防御仓位(紫金+6.8%、黄金ETF+2%、神华+1.2%)当日有效对冲科技股损失,验证了组合构建合理性
|
||||
2. 中芯国际A(688981)是当日最危险持仓(距止损2.14%),中芯国际AH走势分化(A-2.96% vs H-8.05%)值得关注——A股有溢价保护,H股更直接暴露于全球半导体卖压
|
||||
3. 分歧检测bias=opportunity + A/H科技背离>5pp → 极端背离时不能简单看空,A股科技暴跌时港股科技反而上涨,资金在跨市场迁移而非逃离科技板块
|
||||
|
||||
## 2026-07-02 盘中 价格数据新鲜度检查格式不兼容
|
||||
|
||||
**发现了什么:** 自愈执行器报 `盘中自检: 价格数据新鲜度检查失败: unconverted data remains: :06`
|
||||
|
||||
**根因:** `intraday_health_check.py` 的 `datetime.strptime(pf_updated, "%Y-%m-%d %H:%M:%S")` 硬编码要求带秒格式,但 `price_monitor.py` 等写入 `updated_at` 用 `strftime('%Y-%m-%d %H:%M')` 无秒格式。当 `read_portfolio()` 回退到 JSON 冷备时读到无秒时间戳 → 解析失败。
|
||||
|
||||
**修改了什么:**
|
||||
- 文件:`/home/hmo/MoFin/scripts/intraday_health_check.py`
|
||||
- 变更:引入 `_parse_updated_at()` 函数,先试带秒格式 `%Y-%m-%d %H:%M:%S`,失败则回退无秒格式 `%Y-%m-%d %H:%M`;两次都失败时明确记录"格式无法解析"而非抛异常
|
||||
|
||||
**效果预期:** 无论 `updated_at` 是 `'2026-07-02 10:43'`(无秒)还是 `'2026-07-02 10:43:53'`(有秒),都能正确解析并计算新鲜度。
|
||||
|
||||
## 2026-07-02 11:47 宏风险HIGH持续——系统无故障,已知市场事件延续
|
||||
|
||||
**发现了什么:** 自愈执行器报盘中自检→宏观风险HIGH。核实后发现该风险已在11:27向Dad推送过完整报告,且到损位均未触发。这不是系统故障,是已知市场状态(全球半导体抛售)的延续。
|
||||
|
||||
**附带的data issue:** portfolio.json的`currency`字段将所有港股(8只)标为CNY而非HKD。影响跨币种计算准确性。
|
||||
- 根因追踪:`import_holding_xls.py`(line67)正确设HKD,但`strategy_lifecycle.py`(line2027)的`setdefault('currency','CNY')`在策略更新时覆盖了币种标记
|
||||
- 修复计划:盘后(非交易时段)统一排查并修正currency字段在数据管道中的传播路径
|
||||
|
||||
**萃取知识:**
|
||||
1. 自愈执行器对宏风险的报警是设计行为(health check标记risk=high→写TODO→升级处理),需要按"已知市场状态"处理而非"系统故障"
|
||||
2. 腾讯(00700)距止损2.76%是所有持仓中最接近止损位的——本轮冲击前未被重点标记,暴露了"只关注风险最大的几个"忽略了中游风险
|
||||
|
|
||||
@@ -27,3 +27,44 @@
|
||||
1. 韩国芯片巨头利税分配传闻是典型的「情绪性杀跌」——传闻已被辟谣,辟谣后指数快速回升。对A股科创板的影响主要通过半导体板块联动传导。
|
||||
2. 科创50跌3%触发的HIGH信号本身是正确的——但需要结合消息面做上下文修正。这正是实时信号采集器(红绿灯)产生信号后需要LLM深度分析验证的原因。本次红绿灯正确捕捉到信号,LLM分析修正了级别。
|
||||
3. 重仓科技股在情绪杀跌日不做止损调整——这是系统性应对规则的正确应用。长芯博创距止损仅2.9%也不应在恐慌日调宽,等1-2个交易日确认趋势。
|
||||
|
||||
## 2026-07-02 全球半导体冲击:韩国熔断+美股半导体暴跌4.4%
|
||||
|
||||
**事件:** 自愈执行器上报盘中宏观风险HIGH信号(韩国KOSPI-6%触发熔断+费城半导体-4.4%+日经-2%)
|
||||
|
||||
**原因分析:**
|
||||
- Meta拟出租过剩算力(布局AI云业务)→ 市场解读为AI资本开支见顶 → 全球半导体板块抛售
|
||||
- 费城半导体指数跌4.4%(NVDA-3.2%/AMD-4.3%/ASML-4.1%/MRVL-7.7%)
|
||||
- 韩国KOSPI跌6%触发熔断(三星-7%/SK海力士-8%)+ 日经225跌2%
|
||||
- 微软6月跌20%/8个月市值蒸发1.3万亿
|
||||
- **注意:这不是传闻,Meta已确认动向** — 与7月1日韩国芯片传闻有本质区别
|
||||
|
||||
**市场状态(09:30开盘):**
|
||||
- 上证指数 -1.42%(有韧性,非全面崩溃)
|
||||
- 科创50 -4.33%(半导体重仓指数暴跌)
|
||||
- 创业板指 -2.94%
|
||||
- 深证成指 -2.41%
|
||||
|
||||
**持仓影响(A股开盘):**
|
||||
- 中际旭创(15.27%) 1160 -5.16% 距止损8%
|
||||
- 中芯国际A(5.44%) 146.5 -5.17% 距止损7%
|
||||
- 博创科技(3.2%) 241.3 -4.99% 距止损9%
|
||||
- 法拉电子(2.3%) 172.6 -5.48% 距止损4%
|
||||
- 海博思创(6.31%) 255 -3.0% 距止损8%
|
||||
- 华恒生物(5.25%) 16.0 -2.26%
|
||||
- 防御股验证:紫金矿业+2% 黄金ETF+1.86% 模塑科技+2.87%
|
||||
|
||||
**定性:** 全球半导体/AI叙事冲击(板块冲击B类,但严重程度接近系统性)
|
||||
- 区别昨天:昨天是韩国传闻辟谣后快速修复,今天是真实事件(Meta确认)+ 韩国熔断
|
||||
- A股上证仅-1.42%说明不是全面系统性下跌,资金在板块间轮动(半导体→黄金/资源)
|
||||
|
||||
**操作:**
|
||||
- 已推送给Dad XMPP报告
|
||||
- 高景气被动杀跌持仓不动止损
|
||||
- 防御股保留
|
||||
- 等待HK开市检查港股持仓
|
||||
|
||||
**知识萃取:**
|
||||
1. **传闻 vs 真实事件的应对区别:** 7月1日是传闻(韩国芯片利润传闻,辟谣后快速修复),7月2日是真实事件(Meta确认出租算力+韩国熔断)。传闻日可预期修复,真实事件需3-5日观察趋势确认。两者触发相同的「不动止损」规则,但后续跟踪周期不同。
|
||||
2. **韩国熔断的历史信号意义:** 韩国KOSPI触发熔断是极罕见事件(上一次在2020年3月新冠初期),熔断本身不代表长期趋势转折——2020年熔断后KOSPI在半年内涨超80%。熔断是流动性冲击的信号,不是基本面崩塌。
|
||||
3. **科创板-4.33%开盘但上证仅-1.42%的结构性分化验证了三维分析框架的价值:** 不看单一指数结论。科创50暴跌但上证不崩、黄金上涨、宁德时代翻红——说明是科技板块轮动式下跌而非全面系统性风险。仅看科创50会误判为系统性。
|
||||
|
||||
+782
-63946
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
+9775
-9495
File diff suppressed because it is too large
Load Diff
+102
-578
@@ -5,712 +5,236 @@
|
||||
"name": "中际旭创",
|
||||
"shares": 100,
|
||||
"cost": 1316.53,
|
||||
"price": 1135.18,
|
||||
"market_value": 113604.0,
|
||||
"change_pct": -7.19,
|
||||
"currency": "CNY",
|
||||
"position_pct": 15.27,
|
||||
"is_active": 1,
|
||||
"stop_loss": 1169.0,
|
||||
"take_profit": 1339.19,
|
||||
"entry_low": 1182.26,
|
||||
"entry_high": 1248.91,
|
||||
"action": null,
|
||||
"strategy_updated": null,
|
||||
"analysis": {
|
||||
"stop_loss": 1169.0,
|
||||
"take_profit": 1339.19,
|
||||
"entry_low": 1182.26,
|
||||
"entry_high": 1248.91,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:1.4),不建议加仓 | 止损1169.0 | 目标1339.19 | 买入区1182.26~1248.91 | 信号:持有",
|
||||
"tech_snapshot": "形态:带上影阴线/bearish 量价:主动买盘占优 强撑:1102.83 弱撑:1182.26 弱压:1289.83 强压:1394.99 | MA5=1262.5 MA10=1296.1 MA20=1247.2 MA60=1024.3",
|
||||
"multi_tf_context": "多周期看多 | MA20=1247.2 | MA60=1024.3 | 长撑:日弱支撑=1122.0 | 长压:日强阻=1416.88",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 1.43,
|
||||
"action_note": "⚠️盈亏比偏低(1:1.4),不建议加仓",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 1169.0,
|
||||
"entry_zone": "1182.26~1248.91",
|
||||
"take_profit_zone": "0~1339.19"
|
||||
},
|
||||
"price": 1223.17,
|
||||
"change_pct": -3.69
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "06869",
|
||||
"name": "长飞光纤光缆",
|
||||
"shares": 500,
|
||||
"cost": 263.72,
|
||||
"price": 178.6,
|
||||
"market_value": 89300.0,
|
||||
"change_pct": -19.342,
|
||||
"currency": "CNY",
|
||||
"position_pct": 13.47,
|
||||
"is_active": 1,
|
||||
"stop_loss": 205.71,
|
||||
"take_profit": 300.74,
|
||||
"entry_low": 239.4,
|
||||
"entry_high": 251.37,
|
||||
"action": null,
|
||||
"strategy_updated": null,
|
||||
"analysis": {
|
||||
"stop_loss": 205.71,
|
||||
"take_profit": 300.74,
|
||||
"entry_low": 239.4,
|
||||
"entry_high": 251.37,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:0.9),不建议加仓 | 止损205.71 | 目标300.74 | 买入区239.4~251.37 | 信号:持有",
|
||||
"tech_snapshot": "形态:锤子线/T字线/bullish 量价:数据不足 强撑:194.07 弱撑:239.4 弱压:261.73 强压:313.27 | MA5=258.84 MA10=252.78 MA20=246.28 MA60=231.33",
|
||||
"multi_tf_context": "多周期看多 | MA20=246.28 | MA60=231.33 | 长撑:MA20=246.28 | 长压:日强阻=305.0",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.94,
|
||||
"action_note": "⚠️盈亏比偏低(1:0.9),不建议加仓",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 205.71,
|
||||
"entry_zone": "239.4~251.37",
|
||||
"take_profit_zone": "0~300.74"
|
||||
},
|
||||
"price": 221.69,
|
||||
"change_pct": 6.68
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01478",
|
||||
"name": "丘钛科技",
|
||||
"shares": 11000,
|
||||
"cost": 13.47,
|
||||
"price": 5.99,
|
||||
"market_value": 65890.0,
|
||||
"change_pct": 0.729,
|
||||
"currency": "CNY",
|
||||
"position_pct": 7.97,
|
||||
"is_active": 1,
|
||||
"stop_loss": 6.18,
|
||||
"take_profit": 7.2,
|
||||
"entry_low": 6.17,
|
||||
"entry_high": 7.2,
|
||||
"action": "深套持有 | 深套持有 | 止损7.33 | 目标10.39 | 买入区7.88~9.19 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 6.18,
|
||||
"take_profit": 7.2,
|
||||
"entry_low": 6.17,
|
||||
"entry_high": 7.2,
|
||||
"action": "深套持有 | 深套持有 | 止损6.18 | 目标7.2 | 买入区6.17~7.2 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阴线/neutral 量价:数据不足 强撑:6.36 弱撑:6.69 弱压:7.09 强压:7.5 | MA5=8.98 MA10=9.17 MA20=9.44 MA60=8.88",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=9.44 | MA60=8.88 | 长撑:日强支撑=6.6 | 长压:日强阻=10.5",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.62,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 6.18,
|
||||
"entry_zone": "6.17~7.2",
|
||||
"take_profit_zone": "0~7.2"
|
||||
},
|
||||
"price": 5.95,
|
||||
"change_pct": -0.58
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "601899",
|
||||
"name": "紫金矿业",
|
||||
"shares": 2400,
|
||||
"cost": 39.89,
|
||||
"price": 26.35,
|
||||
"market_value": 63048.0,
|
||||
"change_pct": 4.94,
|
||||
"currency": "CNY",
|
||||
"position_pct": 7.34,
|
||||
"is_active": 1,
|
||||
"stop_loss": 23.07,
|
||||
"take_profit": 25.51,
|
||||
"entry_low": 22.6,
|
||||
"entry_high": 26.37,
|
||||
"action": "深套持有 | 深套持有 | 止损24.48 | 目标34.47 | 买入区26.72~31.17 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 23.07,
|
||||
"take_profit": 25.51,
|
||||
"entry_low": 22.6,
|
||||
"entry_high": 26.37,
|
||||
"action": "深套持有 | 深套持有 | 止损23.07 | 目标25.51 | 买入区22.6~26.37 | 信号:持有",
|
||||
"tech_snapshot": "形态:小阳线/neutral 量价:主动买盘占优 强撑:23.49 弱撑:24.5 弱压:25.63 强压:26.57 | MA5=33.51 MA10=35.08 MA20=36.34 MA60=36.5",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=36.34 | MA60=36.5 | 长撑:日弱支撑=24.7 | 长压:周强阻=35.62",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.39,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 23.07,
|
||||
"entry_zone": "22.6~26.37",
|
||||
"take_profit_zone": "0~25.51"
|
||||
},
|
||||
"price": 25.11,
|
||||
"change_pct": -0.12
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "688411",
|
||||
"name": "海博思创",
|
||||
"shares": 200,
|
||||
"cost": 266.95,
|
||||
"price": 258.3,
|
||||
"market_value": 51776.0,
|
||||
"change_pct": -1.75,
|
||||
"currency": "CNY",
|
||||
"position_pct": 6.31,
|
||||
"is_active": 1,
|
||||
"stop_loss": 246.94,
|
||||
"take_profit": 309.13,
|
||||
"entry_low": 244.27,
|
||||
"entry_high": 256.48,
|
||||
"action": "盈利良好 | 止损253.82 | 目标316.5 | 买入区273.21~286.87 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 246.94,
|
||||
"take_profit": 309.13,
|
||||
"entry_low": 244.27,
|
||||
"entry_high": 256.48,
|
||||
"action": "持有观察 | 止损246.94 | 目标309.13 | 买入区244.27~256.48 | 信号:持有",
|
||||
"tech_snapshot": "形态:带下影阴线/neutral 量价:买卖均衡 强撑:232.96 弱撑:244.27 弱压:291.2 强压:322.01 | MA5=256.08 MA10=249.18 MA20=246.95 MA60=242.64",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=246.95 | MA60=242.64 | 长撑:MA20=246.95 | 长压:周强阻=307.58",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 1.98,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 246.94,
|
||||
"entry_zone": "244.27~256.48",
|
||||
"take_profit_zone": "0~309.13"
|
||||
},
|
||||
"price": 262.89,
|
||||
"change_pct": -9.72
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "688981",
|
||||
"name": "中芯国际",
|
||||
"shares": 300,
|
||||
"cost": 126.07,
|
||||
"price": 146.32,
|
||||
"market_value": 44112.0,
|
||||
"change_pct": -5.28,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.44,
|
||||
"is_active": 1,
|
||||
"stop_loss": 149.85,
|
||||
"take_profit": 176.42,
|
||||
"entry_low": 148.9,
|
||||
"entry_high": 156.34,
|
||||
"action": "盈利良好 | 止损132.76 | 目标164.45 | 买入区134.18~140.89 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 149.85,
|
||||
"take_profit": 176.42,
|
||||
"entry_low": 148.9,
|
||||
"entry_high": 156.34,
|
||||
"action": "盈利良好 | 止损149.85 | 目标176.42 | 买入区148.9~156.34 | 信号:持有",
|
||||
"tech_snapshot": "形态:带上影阴线/bearish 量价:买卖均衡 强撑:132.01 弱撑:148.9 弱压:163.47 强压:183.77 | MA5=154.35 MA10=148.6 MA20=138.49 MA60=124.68",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=138.49 | MA60=124.68 | 长撑:MA20=138.49 | 长压:日强阻=166.88",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 5.25,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 149.85,
|
||||
"entry_zone": "148.9~156.34",
|
||||
"take_profit_zone": "0~176.42"
|
||||
},
|
||||
"price": 154.48,
|
||||
"change_pct": -2.73
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01888",
|
||||
"name": "建滔积层板",
|
||||
"shares": 500,
|
||||
"cost": 88.23,
|
||||
"price": 72.83,
|
||||
"market_value": 36415.0,
|
||||
"change_pct": -15.28,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.28,
|
||||
"is_active": 1,
|
||||
"stop_loss": 92.33,
|
||||
"take_profit": 103.21,
|
||||
"entry_low": 94.93,
|
||||
"entry_high": 99.68,
|
||||
"action": "盈利持有 | 短炒强趋势持 | 止损86.34 | 目标141.9 | 买入区85.82~90.11 | 信号:强趋势持",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 92.33,
|
||||
"take_profit": 103.21,
|
||||
"entry_low": 94.93,
|
||||
"entry_high": 99.68,
|
||||
"action": "盈利良好 | 止损92.33 | 目标103.21 | 买入区94.93~99.68 | 信号:持有",
|
||||
"tech_snapshot": "形态:带上影阳线/neutral 量价:数据不足 强撑:84.27 弱撑:94.93 弱压:102.93 强压:113.17 | MA5=98.35 MA10=93.72 MA20=76.92 MA60=50.12",
|
||||
"multi_tf_context": "多周期看多 | MA20=76.92 | MA60=50.12 | 长撑:MA20=76.92 | 长压:日强阻=107.2",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 3.32,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 92.33,
|
||||
"entry_zone": "94.93~99.68",
|
||||
"take_profit_zone": "0~103.21"
|
||||
},
|
||||
"price": 86.06,
|
||||
"change_pct": 2.96
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "688639",
|
||||
"name": "华恒生物",
|
||||
"shares": 2800,
|
||||
"cost": 21.51,
|
||||
"price": 17.18,
|
||||
"market_value": 48244.0,
|
||||
"change_pct": 4.95,
|
||||
"currency": "CNY",
|
||||
"position_pct": 5.25,
|
||||
"is_active": 1,
|
||||
"stop_loss": 14.96,
|
||||
"take_profit": 18.7,
|
||||
"entry_low": 14.73,
|
||||
"entry_high": 17.19,
|
||||
"action": null,
|
||||
"strategy_updated": null,
|
||||
"analysis": {
|
||||
"stop_loss": 14.96,
|
||||
"take_profit": 18.7,
|
||||
"entry_low": 14.73,
|
||||
"entry_high": 17.19,
|
||||
"action": "深套持有 | 深套持有 | 止损14.96 | 目标18.7 | 买入区14.73~17.19 | 信号:持有",
|
||||
"tech_snapshot": "形态:锤子线/T字线/bullish 量价:主动买盘占优 强撑:13.44 弱撑:15.86 弱压:16.69 强压:18.92 | MA5=32.72 MA10=34.17 MA20=36.22 MA60=34.41",
|
||||
"multi_tf_context": "多周期看多 | MA20=36.22 | MA60=34.41 | 长撑:日弱支撑=15.65 | 长压:日强阻=22.62",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.87,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 14.96,
|
||||
"entry_zone": "14.73~17.19",
|
||||
"take_profit_zone": "0~18.7"
|
||||
},
|
||||
"price": 16.37,
|
||||
"change_pct": 1.43
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "300750",
|
||||
"name": "宁德时代",
|
||||
"shares": 100,
|
||||
"cost": 401.78,
|
||||
"price": 386.3,
|
||||
"market_value": 38495.0,
|
||||
"change_pct": 0.64,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.64,
|
||||
"is_active": 1,
|
||||
"stop_loss": 362.31,
|
||||
"take_profit": 404.56,
|
||||
"entry_low": 372.23,
|
||||
"entry_high": 381.61,
|
||||
"action": "持有观察 | 止损345.04 | 目标414.6 | 买入区384.35~397.12 | 信号:弱势持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 362.31,
|
||||
"take_profit": 404.56,
|
||||
"entry_low": 372.23,
|
||||
"entry_high": 381.61,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:0.9),不建议加仓 | 止损362.31 | 目标404.56 | 买入区372.23~381.61 | 信号:持有",
|
||||
"tech_snapshot": "形态:锤子线/T字线/bullish 量价:买卖均衡 强撑:341.8 弱撑:372.23 弱压:393.23 强压:421.42 | MA5=390.94 MA10=394.21 MA20=396.97 MA60=414.12",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=396.97 | MA60=414.12 | 长撑:日弱支撑=378.2 | 长压:周强阻=468.75",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.89,
|
||||
"action_note": "⚠️盈亏比偏低(1:0.9),不建议加仓",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 362.31,
|
||||
"entry_zone": "372.23~381.61",
|
||||
"take_profit_zone": "0~404.56"
|
||||
},
|
||||
"price": 383.84,
|
||||
"change_pct": -2.33
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01211",
|
||||
"name": "比亚迪股份",
|
||||
"shares": 600,
|
||||
"cost": 104.87,
|
||||
"price": 68.41,
|
||||
"market_value": 41070.0,
|
||||
"change_pct": 8.903,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.62,
|
||||
"is_active": 1,
|
||||
"stop_loss": 66.58,
|
||||
"take_profit": 73.73,
|
||||
"entry_low": 65.2,
|
||||
"entry_high": 76.07,
|
||||
"action": "深套持有 | 深套持有 | 止损63.99 | 目标87.07 | 买入区72.77~84.89 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 66.58,
|
||||
"take_profit": 73.73,
|
||||
"entry_low": 65.2,
|
||||
"entry_high": 76.07,
|
||||
"action": "深套持有 | 深套持有 | 止损66.58 | 目标73.73 | 买入区65.2~76.07 | 信号:持有",
|
||||
"tech_snapshot": "形态:十字星/neutral 量价:数据不足 强撑:68.5 弱撑:71.2 弱压:73.9 强压:76.8 | MA5=96.88 MA10=96.41 MA20=97.91 MA60=98.22",
|
||||
"multi_tf_context": "多周期看多 | MA20=97.91 | MA60=98.22 | 长撑:日弱支撑=72.2 | 长压:日强阻=97.15",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.4,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 66.58,
|
||||
"entry_zone": "65.2~76.07",
|
||||
"take_profit_zone": "0~73.73"
|
||||
},
|
||||
"price": 62.89,
|
||||
"change_pct": -0.62
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "02202",
|
||||
"name": "万科企业",
|
||||
"shares": 19700,
|
||||
"cost": 4.67,
|
||||
"price": 1.92,
|
||||
"market_value": 38021.0,
|
||||
"change_pct": 4.717,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.6,
|
||||
"is_active": 1,
|
||||
"stop_loss": 1.95,
|
||||
"take_profit": 2.31,
|
||||
"entry_low": 1.91,
|
||||
"entry_high": 2.23,
|
||||
"action": "深套持有 | 深套持有 | 止损2.0 | 目标2.85 | 买入区2.18~2.54 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 1.95,
|
||||
"take_profit": 2.31,
|
||||
"entry_low": 1.91,
|
||||
"entry_high": 2.23,
|
||||
"action": "深套持有 | 深套持有 | 止损1.95 | 目标2.31 | 买入区1.91~2.23 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阴线/bearish 量价:数据不足 强撑:1.89 弱撑:2.07 弱压:2.21 强压:2.41 | MA5=3.37 MA10=3.39 MA20=3.5 MA60=3.52",
|
||||
"multi_tf_context": "多周期看多 | MA20=3.5 | MA60=3.52 | 长撑:日强支撑=2.1 | 长压:日强阻=2.85",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.91,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 1.95,
|
||||
"entry_zone": "1.91~2.23",
|
||||
"take_profit_zone": "0~2.31"
|
||||
},
|
||||
"price": 1.84,
|
||||
"change_pct": -4.07
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "00700",
|
||||
"name": "腾讯",
|
||||
"shares": 100,
|
||||
"cost": null,
|
||||
"price": 378.36,
|
||||
"market_value": 37784.0,
|
||||
"change_pct": 1.536,
|
||||
"currency": "CNY",
|
||||
"position_pct": null,
|
||||
"is_active": 1,
|
||||
"stop_loss": 416.91,
|
||||
"take_profit": 434.43,
|
||||
"entry_low": 421.2,
|
||||
"entry_high": 429.72,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:1.0),不建议加仓 | 止损387.49 | 目标496.33 | 买入区435.13~440.67 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 416.91,
|
||||
"take_profit": 434.43,
|
||||
"entry_low": 421.2,
|
||||
"entry_high": 429.72,
|
||||
"action": "盈利持有 | ⚠️盈亏比不足1:1.5,不建议买入 | 损414.51 | 盈452.53 | 买421.2~429.72",
|
||||
"tech_snapshot": "形态:带上影阳线/neutral 量价:数据不足 强撑:403.33 弱撑:420.2 弱压:437.47 强压:452.53 | MA5=620.7 MA10=621.4 MA20=614.35 MA60=561.43",
|
||||
"multi_tf_context": "多周期看多 | MA20=614.35 | MA60=561.43 | 长撑:日弱支撑=412.6 | 长压:周强阻=526.5",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "review",
|
||||
"rr_ratio": 1.49,
|
||||
"action_note": "⚠️盈亏比不足1:1.5,不建议买入",
|
||||
"timing_signal": "信号不充分"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 416.91,
|
||||
"entry_zone": "421.2~429.72",
|
||||
"take_profit_zone": "0~434.43"
|
||||
},
|
||||
"price": 373.07,
|
||||
"change_pct": 2.28
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "00981",
|
||||
"name": "中芯国际",
|
||||
"shares": 500,
|
||||
"cost": 75.94,
|
||||
"price": 69.88,
|
||||
"market_value": 34635.0,
|
||||
"change_pct": -9.843,
|
||||
"currency": "CNY",
|
||||
"position_pct": 4.2,
|
||||
"is_active": 1,
|
||||
"stop_loss": 86.72,
|
||||
"take_profit": 96.86,
|
||||
"entry_low": 84.8,
|
||||
"entry_high": 89.04,
|
||||
"action": "盈利持有 | ⚠️盈亏比偏低(1:1.0),不建议加仓 | 止损67.69 | 目标87.26 | 买入区73.68~76.57 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 86.72,
|
||||
"take_profit": 96.86,
|
||||
"entry_low": 84.8,
|
||||
"entry_high": 89.04,
|
||||
"action": "盈利良好 | 止损86.72 | 目标96.86 | 买入区84.8~89.04 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阳线/bullish 量价:数据不足 强撑:75.9 弱撑:84.8 弱压:92.55 强压:100.9 | MA5=85.0 MA10=80.8 MA20=78.58 MA60=71.43",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=78.58 | MA60=71.43 | 长撑:MA20=78.58 | 长压:周强阻=93.0",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 2.57,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 86.72,
|
||||
"entry_zone": "84.8~89.04",
|
||||
"take_profit_zone": "0~96.86"
|
||||
},
|
||||
"price": 77.6,
|
||||
"change_pct": 5.42
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "300548",
|
||||
"name": "长芯博创",
|
||||
"shares": 100,
|
||||
"cost": 231.46,
|
||||
"price": 225.0,
|
||||
"market_value": 22592.0,
|
||||
"change_pct": -11.42,
|
||||
"currency": "CNY",
|
||||
"position_pct": 3.2,
|
||||
"is_active": 1,
|
||||
"stop_loss": 246.38,
|
||||
"take_profit": 291.58,
|
||||
"entry_low": 241.67,
|
||||
"entry_high": 253.75,
|
||||
"action": "盈利良好 | 短炒强趋势持 | 止损251.24 | 目标413.9 | 买入区269.8~283.29 | 信号:强趋势持",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 246.38,
|
||||
"take_profit": 291.58,
|
||||
"entry_low": 241.67,
|
||||
"entry_high": 253.75,
|
||||
"action": "盈利良好 | 止损246.38 | 目标291.58 | 买入区241.67~253.75 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阴线/bearish 量价:主动买盘占优 强撑:222.4 弱撑:241.67 弱压:278.0 强压:303.73 | MA5=266.91 MA10=275.27 MA20=256.44 MA60=247.14",
|
||||
"multi_tf_context": "多周期看多 | MA20=256.44 | MA60=247.14 | 长撑:MA60=247.14 | 长压:日强阻=309.98",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 4.03,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 246.38,
|
||||
"entry_zone": "241.67~253.75",
|
||||
"take_profit_zone": "0~291.58"
|
||||
},
|
||||
"price": 254.0,
|
||||
"change_pct": -8.63
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "518880",
|
||||
"name": "黄金ETF华安",
|
||||
"shares": 2400,
|
||||
"cost": 12.19,
|
||||
"price": 8.45,
|
||||
"market_value": 20280.0,
|
||||
"change_pct": 2.13,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.45,
|
||||
"is_active": 1,
|
||||
"stop_loss": 7.45,
|
||||
"take_profit": 8.58,
|
||||
"entry_low": 7.44,
|
||||
"entry_high": 8.68,
|
||||
"action": "深套持有 | 深套持有 | 止损7.05 | 目标9.17 | 买入区8.02~9.35 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 7.45,
|
||||
"take_profit": 8.58,
|
||||
"entry_low": 7.44,
|
||||
"entry_high": 8.68,
|
||||
"action": "深套持有 | 深套持有 | 止损7.45 | 目标8.58 | 买入区7.44~8.68 | 信号:持有",
|
||||
"tech_snapshot": "形态:小阴线/bearish 量价:数据不足 强撑:7.61 弱撑:8.25 弱压:8.38 强压:8.94 | MA5=9.47 MA10=9.53 MA20=9.86 MA60=10.33",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=9.86 | MA60=10.33 | 长撑:日弱支撑=8.26 | 长压:周强阻=10.15",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.54,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 7.45,
|
||||
"entry_zone": "7.44~8.68",
|
||||
"take_profit_zone": "0~8.58"
|
||||
},
|
||||
"price": 8.27,
|
||||
"change_pct": -1.28
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "300035",
|
||||
"name": "中科电气",
|
||||
"shares": 1400,
|
||||
"cost": 22.29,
|
||||
"price": 14.33,
|
||||
"market_value": 20062.0,
|
||||
"change_pct": -0.76,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.42,
|
||||
"is_active": 1,
|
||||
"stop_loss": 13.01,
|
||||
"take_profit": 15.14,
|
||||
"entry_low": 13.0,
|
||||
"entry_high": 15.16,
|
||||
"action": "深套持有 | 深套持有 | 止损13.74 | 目标19.0 | 买入区15.63~18.24 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 13.01,
|
||||
"take_profit": 15.14,
|
||||
"entry_low": 13.0,
|
||||
"entry_high": 15.16,
|
||||
"action": "深套持有 | 深套持有 | 止损13.01 | 目标15.14 | 买入区13.0~15.16 | 信号:持有",
|
||||
"tech_snapshot": "形态:锤子线/T字线/bullish 量价:主动卖盘占优 强撑:13.01 弱撑:14.12 弱压:14.71 强压:15.77 | MA5=21.52 MA10=21.86 MA20=22.15 MA60=21.45",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=22.15 | MA60=21.45 | 长撑:日弱支撑=14.07 | 长压:日强阻=18.23",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 0.61,
|
||||
"action_note": "深套持有",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 13.01,
|
||||
"entry_zone": "13.0~15.16",
|
||||
"take_profit_zone": "0~15.14"
|
||||
},
|
||||
"price": 14.44,
|
||||
"change_pct": 0.14
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "000700",
|
||||
"name": "模塑科技",
|
||||
"shares": 1400,
|
||||
"cost": 14.83,
|
||||
"price": 16.87,
|
||||
"market_value": 23618.0,
|
||||
"change_pct": 9.97,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.41,
|
||||
"is_active": 1,
|
||||
"stop_loss": 13.91,
|
||||
"take_profit": 15.54,
|
||||
"entry_low": 13.32,
|
||||
"entry_high": 14.09,
|
||||
"action": null,
|
||||
"strategy_updated": null,
|
||||
"analysis": {
|
||||
"stop_loss": 13.91,
|
||||
"take_profit": 15.54,
|
||||
"entry_low": 13.32,
|
||||
"entry_high": 14.09,
|
||||
"action": "盈利持有 | ⚠️盈亏比极低,关注 | 止损13.91 | 目标15.54 | 买入区13.32~14.09 | 信号:持有",
|
||||
"tech_snapshot": "形态:带上影阳线/neutral 量价:主动买盘占优 强撑:13.28 弱撑:14.55 弱压:16.1 强压:16.24 | MA5=14.44 MA10=14.83 MA20=15.44 MA60=13.73",
|
||||
"multi_tf_context": "多周期看多 | MA20=15.44 | MA60=13.73 | 长撑:日弱支撑=13.78 | 长压:日强阻=18.66",
|
||||
"reassessed_at": "2026-07-01 15:00",
|
||||
"status": "manual",
|
||||
"rr_ratio": 0.14,
|
||||
"action_note": "⚠️盈亏比极低,关注",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 13.91,
|
||||
"entry_zone": "13.32~14.09",
|
||||
"take_profit_zone": "0~15.54"
|
||||
},
|
||||
"price": 15.34,
|
||||
"change_pct": 3.93
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "600563",
|
||||
"name": "法拉电子",
|
||||
"shares": 100,
|
||||
"cost": 147.18,
|
||||
"price": 164.32,
|
||||
"market_value": 16460.0,
|
||||
"change_pct": -9.99,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.3,
|
||||
"is_active": 1,
|
||||
"stop_loss": 169.99,
|
||||
"take_profit": 188.19,
|
||||
"entry_low": 175.29,
|
||||
"entry_high": 184.05,
|
||||
"action": "盈利良好 | 止损161.41 | 目标192.67 | 买入区165.51~173.79 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 169.99,
|
||||
"take_profit": 188.19,
|
||||
"entry_low": 175.29,
|
||||
"entry_high": 184.05,
|
||||
"action": "盈利良好 | 止损169.99 | 目标188.19 | 买入区175.29~184.05 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阴线/bearish 量价:买卖均衡 强撑:171.72 弱撑:175.29 弱压:192.5 强压:206.35 | MA5=187.94 MA10=179.22 MA20=168.75 MA60=144.49",
|
||||
"multi_tf_context": "多周期看多 | MA20=168.75 | MA60=144.49 | 长撑:MA20=168.75 | 长压:日强阻=198.8",
|
||||
"reassessed_at": "2026-07-01 15:02",
|
||||
"status": "updated",
|
||||
"rr_ratio": 3.28,
|
||||
"action_note": "",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 169.99,
|
||||
"entry_zone": "175.29~184.05",
|
||||
"take_profit_zone": "0~188.19"
|
||||
},
|
||||
"price": 182.55,
|
||||
"change_pct": -4.32
|
||||
"_currency": "CNY"
|
||||
},
|
||||
{
|
||||
"code": "01088",
|
||||
"name": "中国神华",
|
||||
"shares": 500,
|
||||
"cost": 45.89,
|
||||
"price": 34.26,
|
||||
"market_value": 17115.0,
|
||||
"change_pct": 1.503,
|
||||
"currency": "CNY",
|
||||
"position_pct": 2.14,
|
||||
"is_active": 1,
|
||||
"stop_loss": 38.92,
|
||||
"take_profit": 41.97,
|
||||
"entry_low": 39.41,
|
||||
"entry_high": 40.45,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:1.3),不建议加仓 | 止损35.09 | 目标42.9 | 买入区41.66~42.8 | 信号:持有",
|
||||
"strategy_updated": "2026-06-19 16:01",
|
||||
"analysis": {
|
||||
"stop_loss": 38.92,
|
||||
"take_profit": 41.97,
|
||||
"entry_low": 39.41,
|
||||
"entry_high": 40.45,
|
||||
"action": "持有观察 | ⚠️盈亏比偏低(1:1.4),不建议加仓 | 止损38.92 | 目标41.97 | 买入区39.41~40.45 | 信号:持有",
|
||||
"tech_snapshot": "形态:光头光脚阴线/bearish 量价:数据不足 强撑:38.44 弱撑:39.41 弱压:41.15 强压:42.45 | MA5=40.86 MA10=41.76 MA20=43.74 MA60=45.14",
|
||||
"multi_tf_context": "震荡/无明显方向 | MA20=43.74 | MA60=45.14 | 长撑:日弱支撑=40.0 | 长压:月强阻=49.62",
|
||||
"reassessed_at": "2026-07-01 15:01",
|
||||
"status": "updated",
|
||||
"rr_ratio": 1.39,
|
||||
"action_note": "⚠️盈亏比偏低(1:1.4),不建议加仓",
|
||||
"timing_signal": "持有"
|
||||
},
|
||||
"trigger": {
|
||||
"stop_loss": 38.92,
|
||||
"entry_zone": "39.41~40.45",
|
||||
"take_profit_zone": "0~41.97"
|
||||
},
|
||||
"price": 34.82,
|
||||
"change_pct": -2.38
|
||||
"_currency": "CNY"
|
||||
}
|
||||
],
|
||||
"cash": 92678.85,
|
||||
"total_market_value": 835552.6,
|
||||
"total_assets": 989902.25,
|
||||
"total_pl": 0,
|
||||
"position_pct": 86.65,
|
||||
"updated_at": "2026-07-01 16:58",
|
||||
"source": "/home/hmo/stocks/holding.xls",
|
||||
"frozen_cash": 39481.4,
|
||||
"available_cash": 92678.85,
|
||||
"frozen": 39481.4,
|
||||
"total_cash": 132160.25,
|
||||
"cash_updated_at": "2026-06-29 12:34",
|
||||
"recent_trades": [
|
||||
{
|
||||
"code": "600563",
|
||||
"name": "法拉电子",
|
||||
"action": "sell",
|
||||
"price": 189.2,
|
||||
"shares": 100,
|
||||
"amount": 18920.0,
|
||||
"timestamp": "2026-06-29 10:43"
|
||||
}
|
||||
],
|
||||
"total_mv": 857742.0,
|
||||
"note": "cash fixed from screenshot 6/29, prices=CNY",
|
||||
"total_assets": 902797.0,
|
||||
"total_mv": 822321.0,
|
||||
"stock_value": null,
|
||||
"cash": 80476.0,
|
||||
"frozen_cash": 0.0,
|
||||
"position_pct": 91.09,
|
||||
"currency": "CNY",
|
||||
"last_verified_at": "2026-06-29 22:28",
|
||||
"_total_mv": 835552.6,
|
||||
"_total_cash": 132160.25,
|
||||
"_total_assets": 967712.85,
|
||||
"cash_history": [
|
||||
{
|
||||
"time": "2026-06-29 22:23:47",
|
||||
"cash": 92678.85,
|
||||
"frozen": 39481.4,
|
||||
"source": "manual:post-法拉电子-sell-100shares@189.2",
|
||||
"formula": "初始可用73758.85+法拉电子18920"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-29 22:28",
|
||||
"cash": 92678.85,
|
||||
"frozen": 39481.4,
|
||||
"total_mv": 835552.6,
|
||||
"total_assets": 967712.85,
|
||||
"source": "price_monitor_auto"
|
||||
}
|
||||
]
|
||||
"updated_at": "2026-07-02 13:46"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+166
-1020
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,11 @@
|
||||
"content": "长飞光纤光缆(06869) 255.40+6.68%放量大涨,持有等站上成本263.72;腾讯(00700) 429.80+2.28%,买入区435-440依然可加;中芯H(00981) 89.40+",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **模塑科技(000700)** 15.54 / 止损13.91 — 昨日+5.28%强势,守住15持有",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-30T08:55:46.708460",
|
||||
"content": "- 模塑科技000700 13.86 | 买入区13.33~14.09 **(仍在区内,但已破止损)**",
|
||||
|
||||
@@ -131,6 +131,16 @@
|
||||
"content": "长飞光纤光缆(06869) 255.40+6.68%放量大涨,持有等站上成本263.72;腾讯(00700) 429.80+2.28%,买入区435-440依然可加;中芯H(00981) 89.40+",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **腾讯(00700)** 429.8 / 止损414.51 止盈452.53 — 入场区间421~430,持有待突破",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **模塑科技(000700)** 15.54 / 止损13.91 — 昨日+5.28%强势,守住15持有",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-02T11:55:44.093905",
|
||||
"content": "❌ 反例:腾讯00700,底仓100股(3.59%),浮盈+4.79%。看到\"距止盈470仅0.77%\"就建议触及减仓清仓 —— 机械执行,未考虑底仓属性+浮盈幅度。",
|
||||
|
||||
@@ -66,6 +66,11 @@
|
||||
"content": "**丘钛科技(01478)** 现价6.86(-0.58%) | 仓位7.97% | 止损7.33",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "**丘钛科技(01478)** — 现价6.86 | 成本13.47深度套牢-49%,止损6.18仅10%空间。手机链受韩国科技股崩盘情绪拖累,破6.5必须执行止损。",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-02T12:55:54.834592",
|
||||
"content": "| 丘钛科技(01478) | 10.12 | -1.17% | 9.19% | 深套持有,止损9.0 |",
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
"content": "长飞光纤光缆(06869) 255.40+6.68%放量大涨,持有等站上成本263.72;腾讯(00700) 429.80+2.28%,买入区435-440依然可加;中芯H(00981) 89.40+",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **长飞光纤(06869)** 255.4 / 止损205.71 — 浮亏-3%,光通信受半导拖累,250不破则持",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-02T13:56:05.495125",
|
||||
"content": "🔺**长飞光纤(06869)** | 231.00 +9.90% | 买入区210~220已超出,等回调再入3%",
|
||||
|
||||
@@ -61,6 +61,11 @@
|
||||
"content": "长飞光纤光缆(06869) 255.40+6.68%放量大涨,持有等站上成本263.72;腾讯(00700) 429.80+2.28%,买入区435-440依然可加;中芯H(00981) 89.40+",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **宁德时代(300750)** 386.45 / 止损362.31 — 买入区间371~381已触发,现价略高,挂单378加仓",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-02T12:55:54.834592",
|
||||
"content": "| 宁德时代(300750) | 427.84 | +1.84% | 4.04% | 持有,止损400止盈460 |",
|
||||
|
||||
@@ -66,6 +66,11 @@
|
||||
"content": "**XD紫金矿(601899) 现价25.10** | 距止损24.48仅2.5%,上周板块能源金属-6.38%领跌,若工业金属继续承压则开盘可能触发止损。**设预警24.50**",
|
||||
"report_id": "cron_99c06255590a_2026-06-29_08-37-43"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **紫金矿业(601899)** 25.47 / 止损23.07 — 避险情绪利好黄金,26附近考虑减仓",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-01T10:25:54.419132",
|
||||
"content": "2. **紫金矿业(601899)** 进入加仓区间29-30,可考虑分批加仓",
|
||||
|
||||
@@ -91,6 +91,11 @@
|
||||
"content": "长芯博创(300548) @281.99 +21.83% 放量走强持有,止损261.71;辽宁成大(600739) @10.09 -17.88% 弱撑10.0待企稳;海博思创(688411) @281",
|
||||
"report_id": "cron_99c06255590a_2026-06-19_08-32-54"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "**海博思创(688411)** — 现价263.03 | 昨日-9.67%放量暴跌,距止损246.94仅6.5%。若今日续跌破255需立即止损。",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-01T10:25:54.419132",
|
||||
"content": "1. **海博思创(688411)** 暴跌-5.95%破止损价¥255,需关注明日是否止损",
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
"time": "2026-06-01T11:55:35.956320",
|
||||
"content": "• **688630|芯碁微装|345.68|+3.19%|建议持有观察【短线】|小幅突破,趋势向上,关注350关口**",
|
||||
"report_id": "cron_d3797d924ddc_2026-06-01_11-31-32"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.347799",
|
||||
"content": "**自选关注:** 芯碁微装(688630) 497.27(-9.49%)已跌破买入区上沿556——若继续下探至430~445可考虑介入。江波龙(301308)667.84(-5.1%)仍在观察。",
|
||||
"report_id": "cron_d42f2ce3b479_2026-07-01_20-14-12"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -46,6 +46,11 @@
|
||||
"content": "**华恒生物(688639)** 现价16.14(-2.95%) | 仓位5.25% | 止损20.03",
|
||||
"report_id": "cron_99c06255590a_2026-07-01_08-39-42"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **华恒生物(688639)** 16.37 / 止损14.96 — 距止损8.6%,窄幅运行可持",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-01T14:55:20.378304",
|
||||
"content": "• 华恒生物(688639) 23.58 | +0.47% → 🤝持有,接近止损23.18",
|
||||
|
||||
@@ -41,6 +41,11 @@
|
||||
"content": "- **中芯国际A(688981)** 浮盈+18%仓位4.64%,距离止损132.76安全",
|
||||
"report_id": "cron_99c06255590a_2026-06-29_08-37-43"
|
||||
},
|
||||
{
|
||||
"time": "2026-07-02T08:55:30.266659",
|
||||
"content": "- **中芯国际A(688981)** 156.31 / 止损149.85 — 浮盈+24%,费城半导-6%或拖累今日回调,守住153持有",
|
||||
"report_id": "cron_99c06255590a_2026-07-02_08-32-48"
|
||||
},
|
||||
{
|
||||
"time": "2026-06-01T11:55:35.956320",
|
||||
"content": "• **688981|中芯国际|134.87|-3.60%|建议观望等企稳【短线】|前几日大涨后获利回吐,关注134支撑**",
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"checked_at": "2026-07-01T09:00:21",
|
||||
"total_active": 54,
|
||||
"flagged_count": 14,
|
||||
"checked_at": "2026-07-02T09:00:56",
|
||||
"total_active": 55,
|
||||
"flagged_count": 17,
|
||||
"flagged": [
|
||||
{
|
||||
"code": "000657",
|
||||
"name": "中钨高新",
|
||||
"price": 95.99,
|
||||
"price": 95.94,
|
||||
"flags": [
|
||||
"现价95.99在买入区94~98(是否可买需结合timing_signal判断)"
|
||||
"现价95.94在买入区94~98(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:56",
|
||||
"last_update": "2026-07-01 15:00",
|
||||
"entry_zone": "94~98",
|
||||
"current": "盈利持有 | 目标105.13 | 止损93.58 | 买入区94.07~97.91",
|
||||
"current": "盈利持有 | 目标105.29 | 止损93.12 | 买入区94.02~97.86",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -21,59 +21,75 @@
|
||||
{
|
||||
"code": "000711",
|
||||
"name": "ST京蓝",
|
||||
"price": 4.1,
|
||||
"price": 4.77,
|
||||
"flags": [
|
||||
"现价4.10在买入区4~4(是否可买需结合timing_signal判断)"
|
||||
"现价4.77在买入区5~5(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:56",
|
||||
"entry_zone": "4~4",
|
||||
"current": "盈利持有 | 目标4.54 | 止损3.98 | 买入区4.02~4.18 | 信号:观望",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "5~5",
|
||||
"current": "盈利持有 | 目标5.44 | 止损4.63 | 买入区4.67~4.87 | 信号:观望",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "001309",
|
||||
"name": "德明利",
|
||||
"price": 893.22,
|
||||
"flags": [
|
||||
"现价893.22在买入区877~913(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "877~913",
|
||||
"current": "盈利持有 | 止损参考858.0 | 买入区877.1~912.9",
|
||||
"updated_by": "manual",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "002594",
|
||||
"name": "比亚迪",
|
||||
"price": 78.94,
|
||||
"price": 80.66,
|
||||
"flags": [
|
||||
"现价78.94在买入区77~80(是否可买需结合timing_signal判断)"
|
||||
"现价80.66在买入区79~81(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:56",
|
||||
"entry_zone": "77~80",
|
||||
"current": "盈利持有 | 目标85.2 | 止损73.51 | 买入区77.36~80.02 | 信号:观望",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "79~81",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:1.6),谨慎买入 | 目标84.49 | 止损78.24 | 买入区79.05~80.74 | 信号:观望",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "00968",
|
||||
"name": "信义光能",
|
||||
"price": 2.04,
|
||||
"code": "02318",
|
||||
"name": "中国平安",
|
||||
"price": 51.05,
|
||||
"flags": [
|
||||
"现价2.04在买入区2~2(是否可买需结合timing_signal判断)"
|
||||
"[STRATEGY_STALE] 信号不良(timing_signal含['弱势持有'])",
|
||||
"现价51.05在买入区50~51(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:56",
|
||||
"entry_zone": "2~2",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:1.6),谨慎买入 | 目标2.23 | 止损1.92 | 买入区2.0~2.04 | 信号:关注",
|
||||
"updated_by": "auto",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "50~51",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:2.0),谨慎买入 | 止损参考49.36 | 买入区50.08~51.12 | 信号:弱势持有",
|
||||
"updated_by": "manual",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "02359",
|
||||
"name": "药明康德",
|
||||
"price": 156.2,
|
||||
"price": 153.7,
|
||||
"flags": [
|
||||
"现价156.20在买入区153~159(是否可买需结合timing_signal判断)"
|
||||
"现价153.70在买入区151~157(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "153~159",
|
||||
"current": "盈利持有 | 目标170.5 | 止损144.56 | 买入区153.08~158.55 | 信号:买入",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "151~157",
|
||||
"current": "盈利持有 | 目标169.6 | 止损149.09 | 买入区150.63~156.77 | 信号:买入",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -81,14 +97,15 @@
|
||||
{
|
||||
"code": "02388",
|
||||
"name": "中银香港",
|
||||
"price": 42.18,
|
||||
"price": 42.38,
|
||||
"flags": [
|
||||
"现价42.18在买入区41~43(是否可买需结合timing_signal判断)"
|
||||
"[STRATEGY_STALE] 信号不良(timing_signal含['弱势持有'])",
|
||||
"现价42.38在买入区42~43(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "41~43",
|
||||
"current": "盈利持有 | 目标46.82 | 止损39.27 | 买入区41.34~43.02 | 信号:关注",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "42~43",
|
||||
"current": "盈利持有 | 目标47.08 | 止损41.11 | 买入区41.53~43.23 | 信号:弱势持有",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -96,14 +113,15 @@
|
||||
{
|
||||
"code": "02628",
|
||||
"name": "中国人寿",
|
||||
"price": 26.52,
|
||||
"price": 26.66,
|
||||
"flags": [
|
||||
"现价26.52在买入区26~27(是否可买需结合timing_signal判断)"
|
||||
"[STRATEGY_STALE] 信号不良(timing_signal含['弱势持有'])",
|
||||
"现价26.66在买入区26~27(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "26~27",
|
||||
"current": "盈利持有 | 目标28.85 | 止损24.51 | 买入区25.99~26.86 | 信号:关注",
|
||||
"current": "盈利持有 | 目标28.96 | 止损25.86 | 买入区26.13~27.02 | 信号:弱势持有",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -111,14 +129,30 @@
|
||||
{
|
||||
"code": "06160",
|
||||
"name": "百济神州",
|
||||
"price": 168.7,
|
||||
"price": 170.4,
|
||||
"flags": [
|
||||
"现价168.70在买入区165~171(是否可买需结合timing_signal判断)"
|
||||
"现价170.40在买入区167~172(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "165~171",
|
||||
"current": "盈利持有 | 目标183.23 | 止损162.12 | 买入区165.33~170.56 | 信号:关注",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "167~172",
|
||||
"current": "盈利持有 | 目标183.83 | 止损165.29 | 买入区166.99~172.03",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "09988",
|
||||
"name": "阿里巴巴-W",
|
||||
"price": 92.85,
|
||||
"flags": [
|
||||
"[STRATEGY_STALE] 信号不良(timing_signal含['弱势持有'])",
|
||||
"现价92.85在买入区91~93(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "91~93",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:1.6),谨慎买入 | 目标100.64 | 止损89.74 | 买入区90.99~93.04 | 信号:弱势持有",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -126,14 +160,29 @@
|
||||
{
|
||||
"code": "300124",
|
||||
"name": "汇川技术",
|
||||
"price": 65.89,
|
||||
"price": 68.2,
|
||||
"flags": [
|
||||
"现价65.89在买入区65~67(是否可买需结合timing_signal判断)"
|
||||
"现价68.20在买入区67~70(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "65~67",
|
||||
"current": "盈利持有 | 目标70.99 | 止损63.91 | 买入区64.57~66.74 | 信号:观望",
|
||||
"last_update": "2026-07-01 15:01",
|
||||
"entry_zone": "67~70",
|
||||
"current": "盈利持有 | 目标75.14 | 止损66.15 | 买入区66.84~69.56 | 信号:观望",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
},
|
||||
{
|
||||
"code": "301308",
|
||||
"name": "江波龙",
|
||||
"price": 667.84,
|
||||
"flags": [
|
||||
"现价667.84在买入区654~681(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "654~681",
|
||||
"current": "盈利持有 | 目标786.56 | 止损631.16 | 买入区654.48~681.2",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -141,14 +190,14 @@
|
||||
{
|
||||
"code": "600519",
|
||||
"name": "贵州茅台",
|
||||
"price": 1179.45,
|
||||
"price": 1193.01,
|
||||
"flags": [
|
||||
"现价1179.45在买入区1156~1185(是否可买需结合timing_signal判断)"
|
||||
"现价1193.01在买入区1169~1205(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "1156~1185",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:1.9),谨慎买入 | 目标1246.52 | 止损1144.07 | 买入区1155.86~1185.05 | 信号:关注",
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "1169~1205",
|
||||
"current": "盈利持有 | 目标1277.36 | 止损1157.22 | 买入区1169.15~1205.28 | 信号:关注",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -156,14 +205,14 @@
|
||||
{
|
||||
"code": "601318",
|
||||
"name": "中国平安",
|
||||
"price": 47.51,
|
||||
"price": 49.53,
|
||||
"flags": [
|
||||
"现价47.51在买入区47~48(是否可买需结合timing_signal判断)"
|
||||
"现价49.53在买入区49~50(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "47~48",
|
||||
"current": "盈利持有 | 目标50.56 | 止损46.08 | 买入区46.56~47.87 | 信号:观望",
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "49~50",
|
||||
"current": "盈利持有 | ⚠️盈亏比偏低(1:1.7),谨慎买入 | 目标52.51 | 止损47.74 | 买入区48.54~49.65 | 信号:观望",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -171,14 +220,14 @@
|
||||
{
|
||||
"code": "688630",
|
||||
"name": "芯碁微装",
|
||||
"price": 533.52,
|
||||
"price": 497.27,
|
||||
"flags": [
|
||||
"现价533.52在买入区523~544(是否可买需结合timing_signal判断)"
|
||||
"现价497.27在买入区487~507(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "523~544",
|
||||
"current": "盈利持有 | 目标590.14 | 止损516.6 | 买入区522.85~544.19",
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "487~507",
|
||||
"current": "盈利持有 | 目标609.23 | 止损475.01 | 买入区487.32~507.22",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -186,14 +235,14 @@
|
||||
{
|
||||
"code": "688795",
|
||||
"name": "摩尔线程-U",
|
||||
"price": 711.67,
|
||||
"price": 673.8,
|
||||
"flags": [
|
||||
"现价711.67在买入区697~721(是否可买需结合timing_signal判断)"
|
||||
"现价673.80在买入区660~687(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "697~721",
|
||||
"current": "盈利持有 | 目标766.54 | 止损690.32 | 买入区697.44~720.81 | 信号:观望",
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "660~687",
|
||||
"current": "盈利持有 | 目标747.74 | 止损651.23 | 买入区660.32~687.28 | 信号:观望",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
@@ -201,27 +250,27 @@
|
||||
{
|
||||
"code": "688802",
|
||||
"name": "沐曦股份-U",
|
||||
"price": 818.1,
|
||||
"price": 780.0,
|
||||
"flags": [
|
||||
"现价818.10在买入区802~834(是否可买需结合timing_signal判断)"
|
||||
"现价780.00在买入区764~796(是否可买需结合timing_signal判断)"
|
||||
],
|
||||
"age_days": 0,
|
||||
"last_update": "2026-06-30 10:57",
|
||||
"entry_zone": "802~834",
|
||||
"current": "盈利持有 | 目标917.32 | 止损793.56 | 买入区801.74~834.46 | 信号:买入",
|
||||
"last_update": "2026-07-01 15:02",
|
||||
"entry_zone": "764~796",
|
||||
"current": "盈利持有 | 目标924.71 | 止损751.49 | 买入区764.4~795.6",
|
||||
"updated_by": "auto",
|
||||
"updated_reason": "自动生成",
|
||||
"is_watchlist": true
|
||||
}
|
||||
],
|
||||
"portfolio": {
|
||||
"position_pct": 86.8,
|
||||
"position_pct": 86.65,
|
||||
"cash": 92678.85,
|
||||
"weak_position_pct": 28.6,
|
||||
"all_weak_pct": 40.7,
|
||||
"all_weak_pct": 40.0,
|
||||
"signals": [
|
||||
"[PORTFOLIO_FULL] 总仓位86.8%(现金92679元),买入建议受限"
|
||||
"[PORTFOLIO_FULL] 总仓位86.65%(现金92679元),买入建议受限"
|
||||
]
|
||||
},
|
||||
"summary": "扫描54个策略,14个需关注"
|
||||
"summary": "扫描55个策略,17个需关注"
|
||||
}
|
||||
@@ -94,3 +94,39 @@
|
||||
4. 关闭 TODO #41
|
||||
|
||||
验证: 三条误报标题在修复后均不触发 HIGH 匹配。
|
||||
|
||||
## 2026-07-02 修复:intraday_health_check.py 盘中自检三项BUG
|
||||
|
||||
**发现的问题:**
|
||||
1. 缺少 `sys.path.insert(0, "/home/hmo/MoFin")` → `from mo_data import ...` 报 `ModuleNotFoundError: No module named 'mo_data'`(自愈执行器报告为 "name 'mo_data' is not defined")
|
||||
2. `check_xiaoguo()` 里 `urllib.request.urlopen("http://node122:18003")` 在主机不可达时无限hang住(TCP SYN被防火墙丢,Python timeout失效),导致整个盘中自检超时
|
||||
3. `datetime.strptime` 格式 `"%Y-%m-%d %H:%M"` 与 `read_portfolio()` 返回的 `updated_at`(含秒:`"%Y-%m-%d %H:%M:%S"`)不匹配 → 解析Exception
|
||||
|
||||
**修改内容:**
|
||||
- `/home/hmo/MoFin/scripts/intraday_health_check.py`
|
||||
- 添加 `import socket` 和 `sys.path.insert(0, "/home/hmo/MoFin")`
|
||||
- `check_xiaoguo()`: 用 `socket.settimeout(3)` 替换 `urllib` HTTP检查,防止hang死
|
||||
- `check_price_monitor()`: 将 `strptime` 格式从 `"%Y-%m-%d %H:%M"` 改为 `"%Y-%m-%d %H:%M:%S"`
|
||||
- `check_http()`: 默认timeout从8秒降至5秒(加强健壮性)
|
||||
|
||||
**效果预期:**
|
||||
- 盘中自检不再因 `mo_data` 导入失败而报错
|
||||
- 盘中自检不再因 `node122` 不可达而超时hang死
|
||||
- 价格新鲜度检查正确解析 `updated_at` 时间戳
|
||||
- 相关TODO(#48, #52)已标记resolved
|
||||
|
||||
**发现的问题:**
|
||||
1. price_monitor.py 的 refresh_data_prices() 在 DB 持仓价格为 NULL 时崩溃。`s.get('price', 0)` 在 key 存在但值为 None 时返回 None(不是 0),导致 `abs(None - price)` 触发 TypeError。
|
||||
2. 港股备用通道(fetch_hk_eastmoney_fallback)每只港股有 1 秒 delay,09:30 开盘前港股 API 返回 0 价格,全部 HK 股票走降级通道空耗 ~14 秒。
|
||||
3. Hermes cron 版(profile/scripts/price_monitor.py)与系统 crontab 版(MoFin/price_monitor.py)并存,系统 crontab 每次运行会覆盖 JSON 文件。
|
||||
|
||||
**修改内容:**
|
||||
- `/home/hmo/.hermes/profiles/position-analyst/scripts/price_monitor.py`
|
||||
- 第 335-337 行:`old = s.get('price'); if old is None: old = 0` — 处理 DB NULL 价格
|
||||
- 第 377-379 行:同上,watchlist 更新部分
|
||||
- 第 305-311 行:港股降级通道增加 09:30 开盘检查,开盘前跳过
|
||||
|
||||
**效果预期:**
|
||||
- Hermes cron 版 price_monitor 不会再因 NULL 价格崩溃,DB 已更新 11 只 A 股持仓价格
|
||||
- 港股开盘前不会再空耗 14+ 秒走东财降级通道
|
||||
- 盘中健康检查下次运行时将看到新鲜数据,不再误报
|
||||
|
||||
+3
-2
@@ -27,9 +27,9 @@ DB_PATH = DATA_DIR / "mofin.db"
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
def get_conn() -> sqlite3.Connection:
|
||||
"""获取数据库连接(WAL 模式,外键约束,Row 工厂)"""
|
||||
"""获取数据库连接(WAL 模式,外键约束,Row 工厂,5秒超时防并发锁)"""
|
||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn = sqlite3.connect(str(DB_PATH), timeout=5)
|
||||
conn.row_factory = sqlite3.Row
|
||||
conn.execute("PRAGMA journal_mode=WAL")
|
||||
conn.execute("PRAGMA foreign_keys=ON")
|
||||
@@ -677,6 +677,7 @@ def query_holdings(conn: sqlite3.Connection) -> list[dict]:
|
||||
"""持仓列表(含最新策略)"""
|
||||
rows = conn.execute("""
|
||||
SELECT h.code, h.name, h.shares, h.cost, h.position_pct, h.is_active,
|
||||
h.price, h.change_pct, h.currency,
|
||||
hs.stop_loss, hs.take_profit, hs.entry_low, hs.entry_high,
|
||||
hs.reason as action, hs.created_at as strategy_updated
|
||||
FROM holdings h
|
||||
|
||||
+4
-4
@@ -211,14 +211,14 @@ def refresh_data_prices():
|
||||
|
||||
# 收集所有需要拉取的代码
|
||||
try:
|
||||
pf = mo_data.read_portfolio()
|
||||
pf = read_portfolio()
|
||||
for s in pf.get('holdings', []):
|
||||
all_codes.add(s['code'])
|
||||
except:
|
||||
pf = {"holdings": []}
|
||||
|
||||
try:
|
||||
wl = mo_data.read_watchlist()
|
||||
wl = read_watchlist()
|
||||
for s in wl.get('stocks', []):
|
||||
all_codes.add(s['code'])
|
||||
except:
|
||||
@@ -363,7 +363,7 @@ def _branch_alert_suffix(code, price, shares=0, cost=0):
|
||||
def _record_branch_trigger(code, branch_id, price):
|
||||
"""记录分支触发事件(自成长:trigger_count+1)"""
|
||||
try:
|
||||
raw = mo_data.read_decisions()
|
||||
raw = read_decisions()
|
||||
for d in raw.get('decisions', []):
|
||||
if d.get('code') == code and d.get('strategy_tree',{}).get('branches'):
|
||||
for b in d['strategy_tree']['branches']:
|
||||
@@ -487,7 +487,7 @@ def run_once(round_label=""):
|
||||
_SCENARIO_CACHE = detect_scenario() if HAS_TREE else {}
|
||||
_BRANCH_CACHE = {}
|
||||
try:
|
||||
raw = mo_data.read_decisions()
|
||||
raw = read_decisions()
|
||||
for d in raw.get('decisions', []):
|
||||
tree = d.get('strategy_tree', {})
|
||||
if tree and tree.get('branches'):
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
发现问题→写TODO(消费管道与每日体检共享)。
|
||||
"""
|
||||
|
||||
import json, os, sqlite3, subprocess, urllib.request
|
||||
import json, os, sqlite3, subprocess, urllib.request, sys, socket
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# ── MoFin path ─────────────────────────────────────────────────────
|
||||
sys.path.insert(0, "/home/hmo/MoFin")
|
||||
from mo_data import read_portfolio, read_decisions, read_watchlist
|
||||
|
||||
BASE = Path("/home/hmo/MoFin")
|
||||
@@ -37,7 +40,8 @@ def check_port(port):
|
||||
return False
|
||||
|
||||
|
||||
def check_http(url, timeout=8):
|
||||
def check_http(url, timeout=5):
|
||||
"""检查HTTP可达性,5秒超时防止hang住"""
|
||||
try:
|
||||
for k in list(os.environ.keys()):
|
||||
if 'proxy' in k.lower():
|
||||
@@ -68,8 +72,14 @@ def check_xiaoguo():
|
||||
if scans_today <= 0:
|
||||
# 可能是小果离线了,不报严重,记录即可
|
||||
return
|
||||
# API — 不通时scanner已降级为unknown,不影响
|
||||
check_http("http://node122:18003/v1/models")
|
||||
# API — 用socket快速检测可达性(3s超时)
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.settimeout(3)
|
||||
s.connect(("node122", 18003))
|
||||
s.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
PORTFOLIO_PATH = str(DATA / "portfolio.json")
|
||||
@@ -113,16 +123,28 @@ def check_price_monitor():
|
||||
return
|
||||
|
||||
# 检查portfolio.json数据新鲜度
|
||||
# 兼容 '2026-07-02 10:43'(price_monitor写入,无秒)和 '2026-07-02 10:43:53'(DB写入,有秒)
|
||||
def _parse_updated_at(ts: str) -> datetime | None:
|
||||
for fmt in ("%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M"):
|
||||
try:
|
||||
return datetime.strptime(ts, fmt)
|
||||
except ValueError:
|
||||
continue
|
||||
return None
|
||||
|
||||
try:
|
||||
pf = mo_data.read_portfolio()
|
||||
pf = read_portfolio()
|
||||
pf_updated = pf.get("updated_at", "")
|
||||
if pf_updated:
|
||||
pf_dt = datetime.strptime(pf_updated, "%Y-%m-%d %H:%M")
|
||||
seconds_ago = (datetime.now() - pf_dt).total_seconds()
|
||||
if seconds_ago < 600: # 10分钟内
|
||||
log(True, f"价格监控运行正常,数据{int(seconds_ago//60)}分钟前更新")
|
||||
pf_dt = _parse_updated_at(pf_updated)
|
||||
if pf_dt is None:
|
||||
log(False, f"价格数据updated_at格式无法解析: {pf_updated}")
|
||||
else:
|
||||
log(False, f"价格数据{int(seconds_ago)}秒未更新(portfolio.json)")
|
||||
seconds_ago = (datetime.now() - pf_dt).total_seconds()
|
||||
if seconds_ago < 600: # 10分钟内
|
||||
log(True, f"价格监控运行正常,数据{int(seconds_ago//60)}分钟前更新")
|
||||
else:
|
||||
log(False, f"价格数据{int(seconds_ago)}秒未更新(portfolio.json)")
|
||||
else:
|
||||
log(False, "portfolio.json缺少updated_at字段")
|
||||
except Exception as e:
|
||||
@@ -171,7 +193,8 @@ def check_signal_pipeline():
|
||||
if summary:
|
||||
reason = summary[:80].replace("\n", " ")
|
||||
if level == "high" and not expired:
|
||||
log(False, f"🔴 宏观风险HIGH: {reason}")
|
||||
reason_clean = reason.replace("【高风险】", "").strip()[:60]
|
||||
log(False, f"🔴 宏观风险HIGH: {reason_clean}")
|
||||
elif level == "high" and expired:
|
||||
log(True, f"⏳ 宏观风险HIGH已过期(无新信号超过15分钟)")
|
||||
elif level == "medium":
|
||||
@@ -188,8 +211,17 @@ def write_todos():
|
||||
for msg in ISSUES:
|
||||
title = f"[盘中自检] {msg}"
|
||||
try:
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
exist = conn.execute("SELECT id FROM todos WHERE title=? AND status IN ('pending','in_progress')", (title,)).fetchone()
|
||||
conn = sqlite3.connect(str(DB_PATH), timeout=10)
|
||||
conn.execute("PRAGMA busy_timeout=5000")
|
||||
# 宏观风险HIGH去重:只要有pending/in_progress的宏观风险TODO,不再新增
|
||||
if "宏观风险HIGH" in msg:
|
||||
exist = conn.execute(
|
||||
"SELECT id FROM todos WHERE title LIKE '%宏观风险HIGH%' AND status IN ('pending','in_progress') LIMIT 1"
|
||||
).fetchone()
|
||||
else:
|
||||
exist = conn.execute(
|
||||
"SELECT id FROM todos WHERE title=? AND status IN ('pending','in_progress')", (title,)
|
||||
).fetchone()
|
||||
if not exist:
|
||||
conn.execute(
|
||||
"INSERT INTO todos (title, description, priority, source, status, fix_action) "
|
||||
|
||||
@@ -40,8 +40,8 @@ HIGH_PATTERNS = [
|
||||
r"fed.*(?:emergency|unexpected|surprise|hike|cut)",
|
||||
# 指数暴跌(需 ≥2% 跌幅或使用更强范围词)
|
||||
r"指数[^。]*?(?:暴跌|熔断|闪崩|重挫)",
|
||||
r"指数[^。]*?(?:跌幅|下跌)[^。]*?[2-9]%",
|
||||
r"(?:暴跌|重挫|熔断).*[5-9]%",
|
||||
r"指数[^。]*?(?:跌幅[^。]{0,20}(?:扩大至|达|至|超|为|逾)[^。]*?(?<![0-9.])(?:[2-9]|[1-9][0-9])(?:\.\d+)?%|下跌(?!.*?涨)[^。]*?(?<![0-9.])(?:[2-9]|[1-9][0-9])(?:\.\d+)?%)",
|
||||
r"(?:暴跌|重挫|熔断).*?(?<![0-9.])(?:[5-9]|[1-9][0-9])(?:\.\d+)?%",
|
||||
r"熔断|闪崩",
|
||||
# 地缘+贸易
|
||||
r"关税.*(?:升级|新|报复|制裁)",
|
||||
@@ -82,7 +82,7 @@ MEDIUM_PATTERNS = [
|
||||
# 旧版有 银行.*倒闭|挤兑|破产 , 新版有 银行.*(?:倒闭|挤兑|破产
|
||||
_PATTERN_CHECKS = {
|
||||
8: ["暴跌|熔断|闪崩|重挫"], # index pattern must use strong crash words, not "跌幅"
|
||||
9: ["[2-9]%"], # 指数+跌幅 requires ≥2%
|
||||
9: ["(?<![0-9.])", "(?:扩大至|达|至|超|为|逾)"], # new: negative lookbehind for decimals + measurement words for 跌幅
|
||||
14: ["核(?:威胁", "核威胁|武器|弹头"], # must NOT have standalone 核
|
||||
18: ["倒闭|挤兑|破产"], # bank pattern must have crisis keywords
|
||||
19: ["金融危机(?:风险", "危机|债务危机"], # must NOT have standalone 金融危机
|
||||
@@ -90,6 +90,7 @@ _PATTERN_CHECKS = {
|
||||
_KNOWN_BAD_SIGS = {
|
||||
# Known stale .pyc signature fragments that indicate wrong version
|
||||
"指数.*跌幅": "旧版用 .* 跨句匹配且无 ≥2% 阈值",
|
||||
"[2-9]%(?!\")": "旧版 pattern 9 无上下文限制和阈值修复(新版用 (?:[2-9]|[1-9][0-9])(?:\\.\\d+)?% 替代 [2-9]%)",
|
||||
"|核|": "旧版有独立单字核",
|
||||
"英伟达|nvidia.*跌": "旧版 alternation 分组错误",
|
||||
"导弹.*发射": "旧版只匹配发射不匹配袭击",
|
||||
|
||||
@@ -279,14 +279,14 @@ def refresh_data_prices():
|
||||
|
||||
# 收集所有需要拉取的代码
|
||||
try:
|
||||
pf = mo_data.read_portfolio()
|
||||
pf = read_portfolio()
|
||||
for s in pf.get('holdings', []):
|
||||
all_codes.add(s['code'])
|
||||
except:
|
||||
pf = {"holdings": []}
|
||||
|
||||
try:
|
||||
wl = mo_data.read_watchlist()
|
||||
wl = read_watchlist()
|
||||
for s in wl.get('stocks', []):
|
||||
all_codes.add(s['code'])
|
||||
except:
|
||||
@@ -436,7 +436,7 @@ def _branch_alert_suffix(code, price, shares=0, cost=0):
|
||||
def _record_branch_trigger(code, branch_id, price):
|
||||
"""记录分支触发事件(自成长:trigger_count+1)"""
|
||||
try:
|
||||
raw = mo_data.read_decisions()
|
||||
raw = read_decisions()
|
||||
for d in raw.get('decisions', []):
|
||||
if d.get('code') == code and d.get('strategy_tree',{}).get('branches'):
|
||||
for b in d['strategy_tree']['branches']:
|
||||
@@ -560,7 +560,7 @@ def run_once(round_label=""):
|
||||
_SCENARIO_CACHE = detect_scenario() if HAS_TREE else {}
|
||||
_BRANCH_CACHE = {}
|
||||
try:
|
||||
raw = mo_data.read_decisions()
|
||||
raw = read_decisions()
|
||||
for d in raw.get('decisions', []):
|
||||
tree = d.get('strategy_tree', {})
|
||||
if tree and tree.get('branches'):
|
||||
|
||||
@@ -44,9 +44,11 @@ def _http_get(url, headers=None, timeout=10):
|
||||
|
||||
|
||||
def _detect_market(code):
|
||||
"""自动识别A股/港股"""
|
||||
"""自动识别A股/港股
|
||||
A股代码固定6位,港股代码5位(含前缀0如00700)。
|
||||
"""
|
||||
code = str(code).strip()
|
||||
if code.startswith("0") or code.startswith("3") or len(code) == 6:
|
||||
if len(code) == 6:
|
||||
return "ashare"
|
||||
if len(code) <= 5:
|
||||
return "hk"
|
||||
@@ -337,10 +339,10 @@ def _sina_hk(code):
|
||||
return {
|
||||
"code": code,
|
||||
"name": name,
|
||||
"price": price,
|
||||
"price": round(prev_close + change_amt, 2) if prev_close > 0 and abs(change_amt) > 0 else price,
|
||||
"change_pct": change_pct,
|
||||
"high": float(fields[5]) if fields[5] else None,
|
||||
"low": float(fields[6]) if fields[6] else None,
|
||||
"high": None, # Sina HK format不含high/low字段
|
||||
"low": None,
|
||||
"open": float(fields[4]) if fields[4] else None,
|
||||
"prev_close": prev_close,
|
||||
"volume": None,
|
||||
@@ -366,7 +368,7 @@ def _tencent_hk(code):
|
||||
prev_close = float(fields[4]) if fields[4] else 0
|
||||
if price <= 0:
|
||||
return None
|
||||
change_pct = float(fields[7]) if len(fields) > 7 and fields[7] else 0
|
||||
change_pct = round((price - prev_close) / prev_close * 100, 2) if prev_close > 0 else None
|
||||
return {
|
||||
"code": code,
|
||||
"name": name,
|
||||
|
||||
+200
-2
@@ -20,6 +20,174 @@ import multi_timeframe as mtf
|
||||
from mo_data import read_portfolio, read_decisions, read_watchlist
|
||||
from strategy_tree import detect_scenario
|
||||
|
||||
# ─── 策略准入门禁 — 硬性质量红线 ───────────────────────────────
|
||||
# 每一条策略写入前必须过此门禁。不过的不得写入DB/JSON,
|
||||
# 必须触发重评修复。代码层面硬拦截,不依赖prompt或文档。
|
||||
#
|
||||
# 规则列表 + 严重程度 + 修复建议
|
||||
STRATEGY_QUALITY_GATES = [
|
||||
{
|
||||
"id": "GATE_LOSS_EXISTS",
|
||||
"desc": "止损必须存在且>0",
|
||||
"check": lambda d: (d.get("stop_loss") or 0) > 0,
|
||||
"severity": "CRITICAL",
|
||||
"fix": "调用 technical_analysis 计算支撑位设置止损"
|
||||
},
|
||||
{
|
||||
"id": "GATE_PROFIT_EXISTS",
|
||||
"desc": "止盈必须存在且>0(纯自选股可放宽)",
|
||||
"check": lambda d: (d.get("take_profit") or 0) > 0,
|
||||
"severity": "CRITICAL",
|
||||
"fix": "调用 technical_analysis 计算阻力位设置止盈目标"
|
||||
},
|
||||
{
|
||||
"id": "GATE_SL_GTE_LOW",
|
||||
"desc": "止损必须 ≤ 买入区下沿",
|
||||
"check": lambda d: (d.get("stop_loss") or 0) <= (d.get("entry_low") or 99999),
|
||||
"severity": "HIGH",
|
||||
"fix": "止损不能高于买入区,调整止损至买入区以下"
|
||||
},
|
||||
{
|
||||
"id": "GATE_ENTRY_RANGE",
|
||||
"desc": "买入区下沿 < 上沿",
|
||||
"check": lambda d: (d.get("entry_low") or 0) < (d.get("entry_high") or 0),
|
||||
"severity": "CRITICAL",
|
||||
"fix": "entry_low=现价×0.95, entry_high=现价×1.05 取近似区间"
|
||||
},
|
||||
{
|
||||
"id": "GATE_RR_COMPUTED",
|
||||
"desc": "买入推荐必须含RR",
|
||||
"check": lambda d: not ("买入" in (d.get("timing_signal") or "") or "加仓" in (d.get("timing_signal") or "")) or (d.get("rr_ratio") or 0) > 0,
|
||||
"severity": "HIGH",
|
||||
"fix": "RR = (止盈-现价)/(现价-止损),数据齐全后自动算"
|
||||
},
|
||||
{
|
||||
"id": "GATE_RR_MINIMUM",
|
||||
"desc": "买入推荐RR≥1.5(非买入信号跳过)",
|
||||
"check": lambda d: not ("买入" in (d.get("timing_signal") or "") or "加仓" in (d.get("timing_signal") or "")) or (d.get("rr_ratio") or 0) >= 1.5,
|
||||
"severity": "HIGH",
|
||||
"fix": "RR不足→signal降级为'信号不充分',不进推荐区"
|
||||
},
|
||||
{
|
||||
"id": "GATE_SIGNAL_SHORT",
|
||||
"desc": "timing_signal 必须是短词(2-4字)",
|
||||
"check": lambda d: len((d.get("timing_signal") or "").strip().split()) <= 4 and (d.get("timing_signal") or "") not in ("neutral", ""),
|
||||
"severity": "MEDIUM",
|
||||
"fix": "使用短词:买入/加仓/观望/持有/关注/信号不充分"
|
||||
},
|
||||
{
|
||||
"id": "GATE_TECH_SNAPSHOT",
|
||||
"desc": "tech_snapshot 必须包含技术位数值",
|
||||
"check": lambda d: bool(d.get("tech_snapshot")) and any(c in d["tech_snapshot"] for c in "支撑阻力压强"),
|
||||
"severity": "MEDIUM",
|
||||
"fix": "tech_snapshot 包含强撑/弱撑/弱压/强压至少3个数值"
|
||||
},
|
||||
{
|
||||
"id": "GATE_CURRENCY_SET",
|
||||
"desc": "港股必须标 currency=HKD",
|
||||
"check": lambda d: not (len(str(d.get("code",""))) == 5 and str(d.get("code",""))[0] in "01") or d.get("currency") == "HKD",
|
||||
"severity": "HIGH",
|
||||
"fix": "设置 d['currency']='HKD'"
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _hk_stock(code):
|
||||
return bool(len(str(code)) == 5 and str(code)[0] in ('0','1'))
|
||||
|
||||
def _is_buy_signal_str(signal):
|
||||
"""买入/加仓/建仓类信号"""
|
||||
if not signal:
|
||||
return False
|
||||
return any(kw in signal for kw in ["买入", "加仓", "建仓"])
|
||||
|
||||
# _is_buy_signal is defined later in this file (~line 1240)
|
||||
|
||||
def validate_strategy(d, debug=True):
|
||||
"""策略评审:硬性门禁检查
|
||||
|
||||
返回 (passed: bool, failures: list)
|
||||
任一 CRITICAL 失败 → 拒绝写入,标记 TODO 触发重评
|
||||
任一 HIGH 失败 → 标记 quality_check=failed,写入但不出现在推荐区
|
||||
MEDIUM 失败 → 记录但不拦截
|
||||
"""
|
||||
failures = []
|
||||
for gate in STRATEGY_QUALITY_GATES:
|
||||
try:
|
||||
ok = gate["check"](d)
|
||||
except Exception as e:
|
||||
ok = False
|
||||
if debug:
|
||||
print(f" [VALIDATE] {gate['id']} 检查异常: {e}", flush=True)
|
||||
if not ok:
|
||||
failures.append(gate)
|
||||
if debug:
|
||||
print(f" [VALIDATE] ✗ {gate['id']} ({gate['severity']}): {gate['desc']}", flush=True)
|
||||
|
||||
passed = all(f["severity"] != "CRITICAL" for f in failures)
|
||||
|
||||
if debug:
|
||||
criticals = [f for f in failures if f["severity"] == "CRITICAL"]
|
||||
highs = [f for f in failures if f["severity"] == "HIGH"]
|
||||
if passed:
|
||||
print(f" [VALIDATE] ✅ 通过 ({len(failures)}条警告)" if failures else " [VALIDATE] ✅ 全通过", flush=True)
|
||||
else:
|
||||
print(f" [VALIDATE] ❌ {len(criticals)}条CRITICAL未通过 → 拒绝写入", flush=True)
|
||||
|
||||
return passed, failures
|
||||
|
||||
|
||||
def enforce_strategy_quality(code, name, result):
|
||||
"""策略写入前的强制质量门禁
|
||||
|
||||
对 result 执行 validate_strategy,不通过则:
|
||||
- 设置 quality_check: failed + 失败原因列表
|
||||
- 自动在 changelog 记录
|
||||
- 返回 False,调用方不写入
|
||||
- 返回 True 但 result 被修改(标记了 failed,未被写入)
|
||||
"""
|
||||
passed, failures = validate_strategy(result)
|
||||
|
||||
if not passed:
|
||||
critical_issues = [f["id"] for f in failures if f["severity"] == "CRITICAL"]
|
||||
high_issues = [f["id"] for f in failures if f["severity"] == "HIGH"]
|
||||
|
||||
# 标记质量失败
|
||||
result["quality_check"] = "failed"
|
||||
result["quality_issues"] = {
|
||||
"critical": critical_issues,
|
||||
"high": high_issues,
|
||||
"all": [f["id"] for f in failures],
|
||||
}
|
||||
result["quality_checked_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
# 记录 changelog
|
||||
cl = result.setdefault("changelog", [])
|
||||
cl.append({
|
||||
"time": datetime.now().strftime("%Y-%m-%d %H:%M"),
|
||||
"event": f"质量门禁拒绝 (failed: {critical_issues})",
|
||||
})
|
||||
|
||||
# 信号降级
|
||||
result["status"] = "review_needed"
|
||||
result["timing_signal"] = "信号不充分"
|
||||
|
||||
print(f" 🚫 {name}({code}) 质量门禁未通过 ({critical_issues}) → 已标记 review_needed", flush=True)
|
||||
return False
|
||||
|
||||
# 如果有 HIGH 级别失败 → 标记但不拦截写入
|
||||
high_fails = [f for f in failures if f["severity"] == "HIGH"]
|
||||
if high_fails:
|
||||
result["quality_check"] = "warning"
|
||||
result["quality_issues"] = {"high": [f["id"] for f in high_fails]}
|
||||
result["quality_checked_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
print(f" ⚠️ {name}({code}) 有{len(high_fails)}条HIGH警告,标记warning但已写入", flush=True)
|
||||
else:
|
||||
result["quality_check"] = "passed"
|
||||
result["quality_checked_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def is_hk_stock(code):
|
||||
"""判断是否港股(港股代码5位,A股6位带前导零)"""
|
||||
@@ -427,7 +595,13 @@ def batch_fetch_prices(codes):
|
||||
"SELECT price, change_pct FROM holding_strategies WHERE code=? AND status='active' ORDER BY updated_at DESC LIMIT 1", (raw_code,)
|
||||
).fetchone()
|
||||
if row and row['price']:
|
||||
all_results[raw_code] = (row['price'], 0, row['change_pct'] or 0)
|
||||
all_results[raw_code] = {
|
||||
"price": row['price'],
|
||||
"close": row['price'], # 用现价近似昨收,仅用于sentiment计算
|
||||
"high": row['price'],
|
||||
"low": row['price'],
|
||||
"code": raw_code,
|
||||
}
|
||||
db.close()
|
||||
if all_results:
|
||||
return all_results
|
||||
@@ -1602,6 +1776,9 @@ def reassess_with_context(code, name, price, cost, shares, current_action,
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ── 策略质量门禁 ──
|
||||
enforce_strategy_quality(code, name, result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -2156,6 +2333,23 @@ def regenerate_all(stdout=True):
|
||||
if added_to_wl and stdout:
|
||||
print(f" 清仓→自选自动加入: {', '.join(added_to_wl)}")
|
||||
|
||||
# 重新计算 portfolio 汇总(保留已存在的 cash,用最新价格算市值)
|
||||
try:
|
||||
total_mv = 0.0
|
||||
for h in existing_pf.get('holdings', []):
|
||||
p = h.get('price') or 0
|
||||
s = h.get('shares') or 0
|
||||
total_mv += p * s
|
||||
if p and s and total_mv > 0:
|
||||
h['market_value'] = round(p * s, 2)
|
||||
old_cash = existing_pf.get('cash') or 80476 # fallback 6/23 backup
|
||||
existing_pf['cash'] = old_cash
|
||||
existing_pf['total_mv'] = round(total_mv, 2)
|
||||
existing_pf['total_assets'] = round(total_mv + old_cash, 2)
|
||||
existing_pf['position_pct'] = round(total_mv / (total_mv + old_cash) * 100, 2) if (total_mv + old_cash) > 0 else 0
|
||||
except Exception as e:
|
||||
print(f" [汇总计算失败] {e}", flush=True)
|
||||
|
||||
# DB 写入(替代 JSON dump — 强制币种约束)
|
||||
try:
|
||||
from mofin_db import get_conn, write_holdings_batch, write_portfolio_summary, write_watchlist_stock, write_holding_strategy
|
||||
@@ -2166,7 +2360,11 @@ def regenerate_all(stdout=True):
|
||||
s.setdefault('currency', 'CNY')
|
||||
write_watchlist_stock(conn, s)
|
||||
for d in decisions:
|
||||
write_holding_strategy(conn, d.get('code', ''), d.get('name', ''), d)
|
||||
# ── 策略质量门禁 ──
|
||||
code = d.get('code', '')
|
||||
name = d.get('name', '')
|
||||
enforce_strategy_quality(code, name, d)
|
||||
write_holding_strategy(conn, code, name, d)
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
print(f" [DB写入失败] {e}", flush=True)
|
||||
|
||||
@@ -390,15 +390,15 @@ def full_analysis(code):
|
||||
|
||||
result = {
|
||||
"quote": {
|
||||
"name": q["name"],
|
||||
"name": q.get("name", code),
|
||||
"price": q["price"],
|
||||
"change_pct": q["change_pct"],
|
||||
"open": q["open"],
|
||||
"high": q["high"],
|
||||
"low": q["low"],
|
||||
"close_yest": q["close_yest"],
|
||||
"volume": q["volume"],
|
||||
"amplitude": q["amplitude"],
|
||||
"change_pct": q.get("change_pct", 0),
|
||||
"open": q.get("open", 0),
|
||||
"high": q.get("high", 0),
|
||||
"low": q.get("low", 0),
|
||||
"close_yest": q.get("close_yest", 0),
|
||||
"volume": q.get("volume", 0),
|
||||
"amplitude": q.get("amplitude", 0),
|
||||
},
|
||||
"support_resistance": sr,
|
||||
"candlestick": candle,
|
||||
|
||||
Reference in New Issue
Block a user