trading: 日内T/长桥/六合彩文档与脚本 + quant-factor-mining 新目录
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
"""
|
||||
082 期特码分析 (纯挂牌, 纯挂牌, 不混 Qi 期数据 (Qi 期已开, 用挂牌做前瞻))
|
||||
088 期特码分析 (纯挂牌, 纯挂牌, 不混 Qi 期数据 (Qi 期已开, 用挂牌做前瞻))
|
||||
按 user 2026-07-30 实战需求:
|
||||
1. 不跑频率 (5 期数据无意义)
|
||||
2. 不混 Qi 期号码 (Qi 期已开, 用挂牌做前瞻, 不算 Nq 资料)
|
||||
3. 只用挂牌 + 玄机诗 + 红字 推演
|
||||
4. 输出 5 个候选特码 (有重点, 按挂牌共识排序)
|
||||
5. 不强行 4 框架 (河洛/梅花/玄空/奇门) 公式 (reference 没推演方法)
|
||||
|
||||
🚨 默认期号必须用 v_xg.json Nq (未开下期), 不是 Qi (已开)
|
||||
(2026-08-13 修过, 详见 SKILL.md 硬规则 4 + 9)
|
||||
改 main() default period 时只动 Nq + fallback, 别碰 Qi 字段注释
|
||||
"""
|
||||
import re
|
||||
import json
|
||||
@@ -13,7 +17,7 @@ import sqlite3
|
||||
import subprocess
|
||||
import datetime
|
||||
import os
|
||||
from collections import Counter
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
|
||||
DB_PATH = os.path.expanduser('~/.hermes/trading/lottery.db')
|
||||
@@ -169,7 +173,7 @@ def fetch_sol_detail(path):
|
||||
return fields
|
||||
|
||||
|
||||
def get_te_ma_candidates(period='082'):
|
||||
def get_te_ma_candidates(period='088'):
|
||||
"""特码候选 - 按挂牌共识排序
|
||||
|
||||
规则:
|
||||
@@ -180,10 +184,19 @@ def get_te_ma_candidates(period='082'):
|
||||
5. 玄机字字型 (权重 × 2)
|
||||
"""
|
||||
weights = Counter()
|
||||
# 同步记录每个号码的来源 (用于输出表格)
|
||||
src_tracker = defaultdict(list)
|
||||
|
||||
def add(n, w, src):
|
||||
if 1 <= n <= 49:
|
||||
weights[n] += w
|
||||
if src not in src_tracker[n]:
|
||||
src_tracker[n].append(src)
|
||||
|
||||
# Step 1: 综合挂牌 列表 + 详情
|
||||
# 2026-08-20 改: 多抓几页 (3 → 8), 挂牌稀疏时也能拿到更多数据源
|
||||
gua_html = curl_url('https://sol.2344a.cc/zongheguapai/')
|
||||
gua_links = re.findall(rf'href="(/zongheguapai/\d+\.html)"[^>]*>.*?{period}期', gua_html)[:3]
|
||||
gua_links = re.findall(rf'href="(/zongheguapai/\d+\.html)"[^>]*>.*?{period}期', gua_html)[:8]
|
||||
|
||||
for link in gua_links:
|
||||
f = fetch_sol_detail(link)
|
||||
@@ -191,19 +204,40 @@ def get_te_ma_candidates(period='082'):
|
||||
if '正版彩图挂' in f:
|
||||
m = re.search(r'\d+', f['正版彩图挂'])
|
||||
if m:
|
||||
weights[int(m.group(0))] += 5 # 彩图挂直接给号最高权重
|
||||
add(int(m.group(0)), 5, '挂牌 彩图挂直接给号')
|
||||
# 另版挂 给出号
|
||||
if '另版挂' in f:
|
||||
m = re.search(r'\d+', f['另版挂'])
|
||||
if m:
|
||||
weights[int(m.group(0))] += 3
|
||||
add(int(m.group(0)), 3, f'挂牌 另版挂 ({f["另版挂"]})')
|
||||
# 尾数 (如 1尾,3尾) -> +10, +30
|
||||
if '尾数' in f:
|
||||
for m in re.finditer(r'(\d+)尾', f['尾数']):
|
||||
weights[int(m.group(1))] += 2
|
||||
weights[int(m.group(1)) + 10] += 1
|
||||
weights[int(m.group(1)) + 20] += 1
|
||||
weights[int(m.group(1)) + 30] += 1
|
||||
tail_str = f['尾数']
|
||||
for m in re.finditer(r'(\d+)尾', tail_str):
|
||||
base = int(m.group(1))
|
||||
add(base, 2, f'挂牌 尾数 {base}尾 (本)')
|
||||
add(base + 10, 1, f'挂牌 尾数 {base}尾 (+10)')
|
||||
add(base + 20, 1, f'挂牌 尾数 {base}尾 (+20)')
|
||||
add(base + 30, 1, f'挂牌 尾数 {base}尾 (+30)')
|
||||
# 火烧 (特码生肖提示 — 数字解码: 加 1 个本年生肖号 +2)
|
||||
# 2026-08-20 改: 解码本年生肖, 让挂牌稀疏时多一个号 (单条+2 不至于污染权重)
|
||||
SX_TO_BENSHENG = { # 本年生肖 → 该生肖的"本数" (单数尾数对应)
|
||||
'鼠': 23, '牛': 22, '虎': 21, '兔': 20, '龙': 19, '蛇': 18,
|
||||
'马': 17, '羊': 16, '猴': 15, '鸡': 14, '狗': 13, '猪': 12,
|
||||
}
|
||||
if '火烧' in f:
|
||||
for sx, num in SX_TO_BENSHENG.items():
|
||||
if sx in f['火烧']:
|
||||
add(num, 2, f'挂牌 火烧 {sx}={num} (本年生肖)')
|
||||
break
|
||||
# 出肖 / 六肖 (2026-08-20 改: 解码所有提到的生肖本数, 各 +1)
|
||||
for kw in ['出肖', '六肖']:
|
||||
if kw in f:
|
||||
sxs = re.findall(r'[鼠牛虎兔龙蛇羊猴鸡狗猪]', f[kw])
|
||||
for sx in sxs:
|
||||
num = SX_TO_BENSHENG.get(sx)
|
||||
if num:
|
||||
add(num, 1, f'挂牌 {kw} {sx}={num}')
|
||||
|
||||
# Step 2: 玄机诗 (xuanjiziliao)
|
||||
xuan = fetch_sol_list('/xuanjiziliao/', f'{period}期', limit=20)
|
||||
@@ -213,21 +247,19 @@ def get_te_ma_candidates(period='082'):
|
||||
for m in re.finditer(r'[((](\d+)[))]', line):
|
||||
num = int(m.group(1))
|
||||
if 1 <= num <= 49:
|
||||
weights[num] += 3
|
||||
add(num, 3, f'玄机诗 诗象 ({line[:30]}...)')
|
||||
# 彩霸王 三一玄数
|
||||
if '三一' in line or '一三' in line:
|
||||
weights[3] += 2
|
||||
weights[1] += 2
|
||||
weights[13] += 2
|
||||
weights[31] += 2
|
||||
for n in [3, 1, 13, 31]:
|
||||
add(n, 2, '玄机诗 彩霸王 三一玄数')
|
||||
# 玄机字 (沐字型 8 划)
|
||||
if '《沐》' in line:
|
||||
weights[8] += 2
|
||||
add(8, 2, '玄机字 (沐 8 划)')
|
||||
# 红马蓝狗 (马 红色 = 偏红, 狗 蓝色 = 偏蓝)
|
||||
if '红马' in line:
|
||||
weights[12] += 1 # 马=12 偏红
|
||||
add(12, 1, '玄机诗 红马 (马=12 偏红)')
|
||||
if '蓝狗' in line:
|
||||
weights[18] += 1 # 狗=18 偏蓝
|
||||
add(18, 1, '玄机诗 蓝狗 (狗=18 偏蓝)')
|
||||
|
||||
# Step 3: 六信红字 (红字 大数偏多)
|
||||
hong = fetch_sol_list('/lxhz/', f'{period}期', limit=5)
|
||||
@@ -235,15 +267,15 @@ def get_te_ma_candidates(period='082'):
|
||||
if '頤養' in line or '天年' in line:
|
||||
# 大数偏多 (>25)
|
||||
for n in range(25, 50):
|
||||
weights[n] += 1
|
||||
add(n, 1, '六信红字 大数偏多 (頤養/天年)')
|
||||
|
||||
return weights
|
||||
return weights, src_tracker
|
||||
|
||||
|
||||
def format_te_ma_result(weights, period=None, budget=15, qi_week=None, qi_day=None, qi_nq=None):
|
||||
def format_te_ma_result(weights, src_tracker=None, period=None, budget=15, qi_week=None, qi_day=None, qi_nq=None):
|
||||
"""输出特码候选 + 推荐分配
|
||||
|
||||
period: 要分析哪期 (None=自动取 v_xg.json Qi)
|
||||
period: 要分析哪期 (None=自动取 v_xg.json Nq 未开)
|
||||
qi_week / qi_day / qi_nq: v_xg.json 字段 (None=自动取)
|
||||
"""
|
||||
# 一次性查 v_xg.json 拿所有字段
|
||||
@@ -261,9 +293,10 @@ def format_te_ma_result(weights, period=None, budget=15, qi_week=None, qi_day=No
|
||||
qi_xg = nq_xg = '???'
|
||||
week_xg = day_xg = '?'
|
||||
|
||||
# 如果用户没传 period, 默认用 Qi
|
||||
# 如果用户没传 period, 默认取 Nq (未开下期, 跟 main() 一致)
|
||||
# (2026-08-13 修: 之前注释写"默认用 Qi"是错的, Qi=已开期跟分析目的相反)
|
||||
if period is None:
|
||||
period = qi_xg
|
||||
period = nq_xg
|
||||
if qi_week is None:
|
||||
qi_week = week_xg
|
||||
if qi_day is None:
|
||||
@@ -303,27 +336,38 @@ def format_te_ma_result(weights, period=None, budget=15, qi_week=None, qi_day=No
|
||||
L.append("")
|
||||
|
||||
# 排序 Top 5+
|
||||
# 2026-08-20 改: 保证至少 4-5 个候选。如果 top<4, 兜底补足 (标记来源为占位)
|
||||
top = weights.most_common(8)
|
||||
if len(top) < 4:
|
||||
# most_common 不返回权重 0 的号, 这里显式补足到 5 个 (权重 0 = 占位,排最后)
|
||||
need = 5 - len(top)
|
||||
existing = {n for n, _ in top}
|
||||
for n in range(1, 50):
|
||||
if n not in existing:
|
||||
top.append((n, 0))
|
||||
existing.add(n)
|
||||
if len(top) >= 5:
|
||||
break
|
||||
L.append("🏆 特码候选 (按挂牌共识权重):")
|
||||
L.append("")
|
||||
L.append("| 排序 | 特码 | 权重 | 来源 |")
|
||||
L.append("|---|---|---|---|")
|
||||
|
||||
# 常见号映射 (通用)
|
||||
src_map = {
|
||||
9: '诗象 (09, 47 单出) + 彩图挂 09',
|
||||
33: '彩图挂 33',
|
||||
5: '彩图挂 05',
|
||||
47: '诗象 (单, 单出)',
|
||||
13: '彩霸王 三一玄数',
|
||||
3: '彩霸王 三一',
|
||||
1: '彩霸王 一三',
|
||||
31: '彩霸王 一三',
|
||||
8: '玄机字 (沐 8 划) + 中宫生气',
|
||||
}
|
||||
# 来源映射 — 优先用 src_tracker (实际抓取), 再 fallback 硬编码
|
||||
def get_src(num, w):
|
||||
if w == 0:
|
||||
return '兜底占位 (挂牌稀疏)'
|
||||
if src_tracker and num in src_tracker and src_tracker[num]:
|
||||
# 显示前 2 个来源, 多了写 ...
|
||||
srcs = src_tracker[num][:2]
|
||||
txt = ' + '.join(srcs)
|
||||
if len(src_tracker[num]) > 2:
|
||||
txt += f' (+{len(src_tracker[num]) - 2})'
|
||||
return txt
|
||||
return '其他挂牌提示'
|
||||
|
||||
for i, (num, w) in enumerate(top, 1):
|
||||
src = src_map.get(num, '其他挂牌提示')
|
||||
src = get_src(num, w)
|
||||
emoji = ['🥇', '🥈', '🥉', '4', '5', '6', '7', '8'][i-1]
|
||||
L.append(f"| {emoji} | **{num}** | {w} | {src} |")
|
||||
|
||||
@@ -393,18 +437,19 @@ if __name__ == '__main__':
|
||||
sys.exit(0)
|
||||
|
||||
# 默认: 跑分析 (period 第一个参数)
|
||||
# 🚨 默认取 v_xg.json Nq (未开下期), 不是 Qi (已开) — 见 SKILL.md 硬规则 4
|
||||
period = cmd
|
||||
if period is None:
|
||||
# 自动取 v_xg.json Qi
|
||||
# 自动取 v_xg.json Nq (未开下期, 不是 Qi 已开)
|
||||
try:
|
||||
import urllib.request
|
||||
req = urllib.request.Request('https://btc.tktk.app/data/v_xg.json',
|
||||
headers={'User-Agent': 'Mozilla/5.0'})
|
||||
with urllib.request.urlopen(req, timeout=10) as r:
|
||||
period = json.loads(r.read().decode('utf-8')).get('Qi', '082')
|
||||
period = json.loads(r.read().decode('utf-8')).get('Nq', '088')
|
||||
except Exception:
|
||||
period = '082'
|
||||
weights = get_te_ma_candidates(period)
|
||||
period = '088'
|
||||
weights, src_tracker = get_te_ma_candidates(period)
|
||||
# 自动取 v_xg.json Qi + Week + Day + Nq 一次, 传所有
|
||||
# (period 保留用户 CLI 传的, 不要被 Qi 覆盖 — Qi 只用来推算开彩日)
|
||||
try:
|
||||
@@ -436,4 +481,4 @@ if __name__ == '__main__':
|
||||
# 对所有未中奖的 analysis 更新 hit (开彩后)
|
||||
check_hits()
|
||||
|
||||
print(format_te_ma_result(weights, period, 15, qi_week, qi_day, qi_nq))
|
||||
print(format_te_ma_result(weights, src_tracker, period, 15, qi_week, qi_day, qi_nq))
|
||||
@@ -1,25 +1,29 @@
|
||||
#!/bin/bash
|
||||
# Lottery cron wrapper - 直接调 lottery_特码.py 输出
|
||||
# cron no_agent 模式: 模型不参与,脚本输出直接推送
|
||||
#
|
||||
# 🚨 默认期号 = v_xg.json Nq (未开下期), 不是 Qi (已开)
|
||||
# (2026-08-13 修过: Qi→Nq, fallback 082→088)
|
||||
# 改这里时立刻 grep -n "Qi\|Nq" lottery_特码.py lottery_特码_cron.sh 对照
|
||||
set -e
|
||||
|
||||
cd /home/openclaw/.hermes/skills/trading/lottery-hk
|
||||
|
||||
# 自动取 Qi 期
|
||||
QI=$(python3 -c "
|
||||
# 自动取 Nq 期 (未开下期, 不是 Qi 已开)
|
||||
NQ=$(python3 -c "
|
||||
import json, urllib.request
|
||||
try:
|
||||
req = urllib.request.Request('https://btc.tktk.app/data/v_xg.json',
|
||||
headers={'User-Agent': 'Mozilla/5.0'})
|
||||
with urllib.request.urlopen(req, timeout=10) as r:
|
||||
d = json.loads(r.read().decode('utf-8'))
|
||||
print(d['Qi'])
|
||||
print(d['Nq'])
|
||||
except Exception:
|
||||
print('082') # fallback
|
||||
print('088') # fallback
|
||||
")
|
||||
|
||||
echo "🎯 分析期号: ${QI} (v_xg.json Qi)"
|
||||
echo "🎯 分析期号: ${NQ} (v_xg.json Nq 未开下期)"
|
||||
echo ""
|
||||
|
||||
# 跑真脚本
|
||||
python3 /home/openclaw/.hermes/skills/trading/lottery-hk/scripts/lottery_特码.py "${QI}" 2>&1
|
||||
python3 /home/openclaw/.hermes/skills/trading/lottery-hk/scripts/lottery_特码.py "${NQ}" 2>&1
|
||||
@@ -1,48 +1,122 @@
|
||||
#!/bin/bash
|
||||
# 核验当前期预测 vs 实际开奖,记录命中率
|
||||
# 22:30 北京时间(开奖21:30后1小时)跑
|
||||
#
|
||||
# 流程 (2026-08-13 重写):
|
||||
# 1. curl v_xg.json (带 UA + proxy fallback) → Qi + Data.1-7 (真开彩, 2026-08-04 验证)
|
||||
# 2. 失败 fallback: 已有 draws 表数据 OR 提示用户手填
|
||||
# 3. draws 表空 → 自动 add_draw (触发 check_hits 更新所有 analysis hit 状态)
|
||||
# 4. 找 Qi 期分析 .md, 输出核验报告
|
||||
#
|
||||
# ⚠️ Qi→Nq 修复后: cron 11:30 北京 分析 Nq 期 (未开下期), 22:30 北京 verify 时 Qi 已经是新一期,
|
||||
# 分析文件就是 Qi 期 (刚开的那期), 不是 Qi-1
|
||||
#
|
||||
# 🚨 marksix6.com 真开彩验证源: 必须用 browser (Vue SSR, curl 拿不到), 不在本脚本里跑
|
||||
# (no_agent 模式没 browser 工具); cron 改 no_agent 时改这里
|
||||
|
||||
set -e
|
||||
|
||||
DB="$HOME/.hermes/trading/lottery.db"
|
||||
OUT_DIR="$HOME/.hermes/cron/output/lottery-verify"
|
||||
mkdir -p "$OUT_DIR"
|
||||
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
# 当前期号 - 优先代理,失败直连(VPS 出口有时被墙)
|
||||
QI=$(curl -s --proxy http://127.0.0.1:7890 --max-time 8 "https://btc.tktk.app/data/v_xg.json" 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('Qi',''))" 2>/dev/null)
|
||||
if [ -z "$QI" ]; then
|
||||
QI=$(curl -s --noproxy '*' --max-time 8 "https://btc.tktk.app/data/v_xg.json" 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('Qi',''))" 2>/dev/null)
|
||||
fi
|
||||
if [ -z "$QI" ]; then
|
||||
echo "❌ 无法获取当前期号(代理+直连都失败)"
|
||||
exit 1
|
||||
# === Step 1: 取 v_xg.json (Qi + Data.1-7) ===
|
||||
fetch_v_xg() {
|
||||
local out
|
||||
# 优先代理,失败直连(VPS 出口有时被墙)
|
||||
out=$(curl -s --proxy http://127.0.0.1:7890 --max-time 8 \
|
||||
-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
|
||||
"https://btc.tktk.app/data/v_xg.json" 2>/dev/null || true)
|
||||
if [ -z "$out" ] || echo "$out" | grep -q "请求出错\|Cann't connect"; then
|
||||
out=$(curl -s --noproxy '*' --max-time 8 \
|
||||
-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
|
||||
"https://btc.tktk.app/data/v_xg.json" 2>/dev/null || true)
|
||||
fi
|
||||
# 校验是不是 JSON 且有 Qi
|
||||
if echo "$out" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); assert d.get('Qi')" 2>/dev/null; then
|
||||
echo "$out"
|
||||
fi
|
||||
}
|
||||
|
||||
V_XG=$(fetch_v_xg || true)
|
||||
NEED_FETCH=0
|
||||
if [ -z "$V_XG" ]; then
|
||||
NEED_FETCH=1
|
||||
echo "⚠️ v_xg.json 暂不可用 (DB 故障或网络被墙), 尝试从 draws 表读已有数据"
|
||||
fi
|
||||
|
||||
# 实际开奖结果
|
||||
ACTUAL=$(sqlite3 "$DB" "SELECT n1||','||n2||','||n3||','||n4||','||n5||','||n6||','||special FROM draws WHERE period='$QI';")
|
||||
# === Step 2: 解析 Qi + 真开彩 ===
|
||||
QI=""
|
||||
ACTUAL=""
|
||||
if [ "$NEED_FETCH" = "0" ]; then
|
||||
eval "$(echo "$V_XG" | python3 -c "
|
||||
import json, sys
|
||||
d = json.loads(sys.stdin.read())
|
||||
qi = d.get('Qi','')
|
||||
data = d.get('Data', {})
|
||||
nums = [int(data[str(i)]['number']) for i in range(1, 8) if str(i) in data]
|
||||
special = nums[6] if len(nums) >= 7 else 0
|
||||
print(f'QI={qi!r}')
|
||||
print(f'SPECIAL={special}')
|
||||
print(f'N1={nums[0] if len(nums)>0 else 0}')
|
||||
print(f'N2={nums[1] if len(nums)>1 else 0}')
|
||||
print(f'N3={nums[2] if len(nums)>2 else 0}')
|
||||
print(f'N4={nums[3] if len(nums)>3 else 0}')
|
||||
print(f'N5={nums[4] if len(nums)>4 else 0}')
|
||||
print(f'N6={nums[5] if len(nums)>5 else 0}')
|
||||
")"
|
||||
if [ -n "$QI" ]; then
|
||||
ACTUAL="$N1,$N2,$N3,$N4,$N5,$N6,$SPECIAL"
|
||||
echo "📡 v_xg.json: Qi=$QI 真开彩=$N1 $N2 $N3 $N4 $N5 $N6 特=$SPECIAL"
|
||||
fi
|
||||
fi
|
||||
|
||||
# === Step 3: 兜底从 draws 表读 (手填或之前入库) ===
|
||||
if [ -z "$ACTUAL" ]; then
|
||||
echo "❌ 期号 $QI 还没入库开奖结果"
|
||||
exit 1
|
||||
# v_xg 拿不到, 尝试从最近 Qi 期读
|
||||
if [ -z "$QI" ]; then
|
||||
QI=$(sqlite3 "$DB" "SELECT period FROM draws ORDER BY period DESC LIMIT 1;" 2>/dev/null || true)
|
||||
fi
|
||||
if [ -n "$QI" ]; then
|
||||
ACTUAL=$(sqlite3 "$DB" "SELECT n1||','||n2||','||n3||','||n4||','||n5||','||n6||','||special FROM draws WHERE period='$QI';" 2>/dev/null || true)
|
||||
fi
|
||||
if [ -z "$ACTUAL" ]; then
|
||||
echo "❌ 无法获取 $QI 期开奖结果 (v_xg.json 宕机 + draws 表空)"
|
||||
echo " 手动填: python3 $SKILL_DIR/scripts/lottery_特码.py add $QI <special> <n1..n6>"
|
||||
exit 1
|
||||
fi
|
||||
echo "📂 draws 表读 $QI 期: $ACTUAL"
|
||||
fi
|
||||
|
||||
IFS=',' read -r A1 A2 A3 A4 A5 A6 AS <<< "$ACTUAL"
|
||||
ACTUAL_FLAT="$A1 $A2 $A3 $A4 $A5 $A6"
|
||||
ACTUAL_SPECIAL="$AS"
|
||||
|
||||
# 找对应的分析文件 - 看 Qi 是几(7-19/21的cron跑的就是 Qi-1 期预测)
|
||||
QI_NUM=$((10#$QI))
|
||||
PREV_PERIOD=$((QI_NUM - 1))
|
||||
# 标题格式有几种:'077期热数据采集' / '热数据采集 · 077期' / '077期数据汇总'
|
||||
# 简单找包含期号+期 的最近文件
|
||||
ANALYSIS_FILE=$(grep -lE "${PREV_PERIOD}期数据汇总|${PREV_PERIOD}期热数据采集|热数据采集.*${PREV_PERIOD}期" "$HOME/.hermes/cron/output/5bec1f60f77f/"*.md 2>/dev/null | tail -1)
|
||||
[ -z "$ANALYSIS_FILE" ] && ANALYSIS_FILE=$(grep -l "${PREV_PERIOD}期" "$HOME/.hermes/cron/output/5bec1f60f77f/"*.md 2>/dev/null | tail -1)
|
||||
# === Step 4: 检查 draws 表, 没数据就入库 (v_xg 真开彩可用时) ===
|
||||
EXISTING=$(sqlite3 "$DB" "SELECT special FROM draws WHERE period='$QI';" 2>/dev/null || true)
|
||||
if [ -z "$EXISTING" ] && [ -n "$SPECIAL" ] && [ "$SPECIAL" != "0" ]; then
|
||||
echo "💾 draws 表 $QI 期空, 自动入库..."
|
||||
python3 "$SKILL_DIR/scripts/lottery_特码.py" add "$QI" "$SPECIAL" "$N1" "$N2" "$N3" "$N4" "$N5" "$N6" 2>&1 || echo "⚠️ add_draw 失败"
|
||||
fi
|
||||
|
||||
# === Step 5: 跑 check_hits (确保所有 analysis 行 hit 状态更新) ===
|
||||
python3 "$SKILL_DIR/scripts/lottery_特码.py" hits 2>&1 | tail -3
|
||||
|
||||
# === Step 6: 找 Qi 期分析 .md ===
|
||||
ANALYSIS_FILE=$(grep -lE "${QI}期" "$HOME/.hermes/cron/output/5bec1f60f77f/"*.md 2>/dev/null | tail -1)
|
||||
|
||||
# === Step 7: 查 analysis 表最近一条 ===
|
||||
ANALYSIS_HIT=$(sqlite3 "$DB" "SELECT actual_special || '|' || hit FROM analysis WHERE period='$QI' ORDER BY id DESC LIMIT 1;" 2>/dev/null || echo "|")
|
||||
|
||||
# === Step 8: 输出核验报告 ===
|
||||
OUT_FILE="$OUT_DIR/$(date +%Y-%m-%d_%H-%M-%S)_${QI}.md"
|
||||
{
|
||||
echo "## 🎯 核验报告 | $QI期"
|
||||
echo ""
|
||||
echo "**开奖时间**: $(date +%Y-%m-%d) 21:30 北京"
|
||||
echo "**核验时间**: $(date +%Y-%m-%d) 22:30 北京"
|
||||
echo "**数据源**: v_xg.json Data.1-7 (2026-08-04 marksix6.com 验证)"
|
||||
echo ""
|
||||
echo "### 实际开奖"
|
||||
echo "| 位置 | 号码 |"
|
||||
@@ -53,44 +127,63 @@ echo ""
|
||||
|
||||
if [ -n "$ANALYSIS_FILE" ]; then
|
||||
echo "### 分析文件"
|
||||
echo "📄 $ANALYSIS_FILE"
|
||||
echo "📄 \`$ANALYSIS_FILE\`"
|
||||
echo ""
|
||||
echo "### 预测 vs 实际"
|
||||
PREDICTED_SPECIAL=$(grep -o "特码重点.*\*\*[0-9]\+\*\*\|特码.*\*\*[0-9]\+\*\*" "$ANALYSIS_FILE" | head -1)
|
||||
PREDICTED_FLAT=$(grep "平码优先" "$ANALYSIS_FILE" | head -1)
|
||||
echo "**预测**: $PREDICTED_SPECIAL · $PREDICTED_FLAT"
|
||||
|
||||
# 提取 Top 5 候选 (新格式: "| 🥇 | **42** | 3 | 挂牌 另版挂 (42) |")
|
||||
TOP_CANDIDATES=$(grep -oE '\| \*\*[0-9]+\*\*' "$ANALYSIS_FILE" | head -5 | grep -oE '[0-9]+')
|
||||
echo "### 预测 Top 5"
|
||||
echo "| 排序 | 特码 |"
|
||||
echo "|---|---|"
|
||||
i=1
|
||||
for c in $TOP_CANDIDATES; do
|
||||
emoji=$([ $i -eq 1 ] && echo "🥇" || ([ $i -eq 2 ] && echo "🥈" || ([ $i -eq 3 ] && echo "🥉" || echo "$i")))
|
||||
echo "| $emoji | $c |"
|
||||
i=$((i+1))
|
||||
done
|
||||
echo ""
|
||||
echo "### 命中分析"
|
||||
|
||||
|
||||
HIT_SPECIAL="❌ 未中"
|
||||
if echo "$PREDICTED_SPECIAL" | grep -q "\*\*$AS\*\*"; then
|
||||
if echo " $TOP_CANDIDATES " | grep -q " $AS "; then
|
||||
HIT_SPECIAL="✅ **特码命中**"
|
||||
fi
|
||||
echo "### 命中"
|
||||
echo "- 特码 $AS: $HIT_SPECIAL"
|
||||
|
||||
HIT_FLAT=$(echo "$ACTUAL_FLAT" | tr ' ' '\n' | while read n; do
|
||||
if echo "$PREDICTED_FLAT" | grep -q "\*\*$n\*\*\|\b$n\b"; then
|
||||
echo "✅ $n"
|
||||
|
||||
HIT_FLAT=""
|
||||
for n in $A1 $A2 $A3 $A4 $A5 $A6; do
|
||||
if echo " $TOP_CANDIDATES " | grep -q " $n "; then
|
||||
HIT_FLAT="$HIT_FLAT ✅$n"
|
||||
fi
|
||||
done | tr '\n' ' ')
|
||||
echo "- 平码命中: ${HIT_FLAT:-无}"
|
||||
|
||||
TOTAL_HIT=$(echo "$ACTUAL_FLAT" | tr ' ' '\n' | while read n; do
|
||||
if grep -qE "\*\*$n\*\*| $n[、,,]|\b$n( |$)" "$ANALYSIS_FILE"; then
|
||||
echo "1"
|
||||
fi
|
||||
done | wc -l)
|
||||
done
|
||||
echo "- 平码命中:${HIT_FLAT:- 无}"
|
||||
|
||||
TOTAL=0
|
||||
if echo " $TOP_CANDIDATES " | grep -q " $AS "; then TOTAL=$((TOTAL+1)); fi
|
||||
for n in $A1 $A2 $A3 $A4 $A5 $A6; do
|
||||
if echo " $TOP_CANDIDATES " | grep -q " $n "; then TOTAL=$((TOTAL+1)); fi
|
||||
done
|
||||
echo ""
|
||||
echo "**总命中**: 特码 + 平码 共 $((TOTAL_HIT+0)) / 7 球"
|
||||
echo "**总命中**: Top 5 候选命中 $TOTAL / 7 球 (特码+平码)"
|
||||
else
|
||||
echo "### ⚠️ 未找到分析文件"
|
||||
echo " 查找路径: $HOME/.hermes/cron/output/5bec1f60f77f/"
|
||||
echo " 期号: $QI"
|
||||
fi
|
||||
|
||||
ACTUAL_FROM_DB=$(echo "$ANALYSIS_HIT" | cut -d'|' -f1)
|
||||
HIT_FROM_DB=$(echo "$ANALYSIS_HIT" | cut -d'|' -f2)
|
||||
if [ -n "$HIT_FROM_DB" ]; then
|
||||
HIT_ICON=$([ "$HIT_FROM_DB" = "1" ] && echo "✅ 中奖" || echo "❌ 未中")
|
||||
echo ""
|
||||
echo "### SQLite analysis 标记"
|
||||
echo "- actual_special: $ACTUAL_FROM_DB"
|
||||
echo "- hit: $HIT_ICON"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "---"
|
||||
echo "_生成时间: $(date '+%Y-%m-%d %H:%M:%S')_"
|
||||
echo "_生成时间: $(date '+%Y-%m-%d %H:%M:%S') 北京_"
|
||||
} > "$OUT_FILE"
|
||||
|
||||
cat "$OUT_FILE"
|
||||
cat "$OUT_FILE"
|
||||
Reference in New Issue
Block a user