v1.7.0: 每日定时报告(工作日9:00盘前分析/15:30盘后总结) - 全球市场数据+报告引擎(简版邮件正文+详细版HTML附件)+cron定时+手动触发+发送日志; 修复模拟数据换手率失真
This commit is contained in:
+32
-2
@@ -15,6 +15,7 @@
|
||||
"""
|
||||
import argparse
|
||||
import datetime as dt
|
||||
import json
|
||||
import math
|
||||
import random
|
||||
import sys
|
||||
@@ -238,7 +239,8 @@ def gen_daily(dates):
|
||||
drift = {0: 0.0011, 1: 0.00025, 2: -0.00085}[trend]
|
||||
# 最近30天加速(制造趋势分化,让荐股有区分度)
|
||||
recent_drift = {0: 0.0045, 1: 0.0001, 2: -0.0045}[trend]
|
||||
base_vol = float_shares * 10000 * random.uniform(0.8, 2.2) # 基准成交量(万股)
|
||||
# 基准成交量(万股)= 流通盘 × 0.4%~1.5% 日换手(贴近真实市场)
|
||||
base_vol = float_shares * 10000 * random.uniform(0.004, 0.015)
|
||||
for i, d in enumerate(dates):
|
||||
phase = max(0, i - (len(dates) - 30))
|
||||
dr = drift + (recent_drift if phase > 0 else 0)
|
||||
@@ -250,7 +252,7 @@ def gen_daily(dates):
|
||||
open_p = prev * (1 + random.gauss(0, vol * 0.5))
|
||||
high = max(open_p, p) * (1 + abs(random.gauss(0, vol * 0.35)))
|
||||
low = min(open_p, p) * (1 - abs(random.gauss(0, vol * 0.35)))
|
||||
volume = base_vol * (1 + 3 * abs(r) / vol) * random.uniform(0.6, 1.4)
|
||||
volume = base_vol * (1 + 1.5 * abs(r) / vol) * random.uniform(0.6, 1.4)
|
||||
amount = volume * (open_p + p) / 2 # 万元
|
||||
chg = (p - prev) / prev * 100
|
||||
daily.append((code, d, round(open_p, 2), round(high, 2), round(low, 2),
|
||||
@@ -339,6 +341,30 @@ def _recent_days(n):
|
||||
return dates
|
||||
|
||||
|
||||
GLOBAL_INDICES = [
|
||||
("dji", "道琼斯", 34000), ("nasdaq", "纳斯达克", 12800), ("sp500", "标普500", 4400),
|
||||
("hsi", "恒生指数", 17500), ("nikkei", "日经225", 33000), ("kospi", "韩国KOSPI", 2500),
|
||||
("dax", "德国DAX", 16000), ("cac", "法国CAC40", 7000), ("ftse", "英国FTSE100", 7500),
|
||||
]
|
||||
|
||||
|
||||
def _gen_global(dates):
|
||||
"""生成全球主要指数模拟序列(随机游走,chg 基于前一交易日)"""
|
||||
vals = {k: v for k, _, v in GLOBAL_INDICES}
|
||||
prev = dict(vals)
|
||||
out = {}
|
||||
for d in dates:
|
||||
row = {}
|
||||
for k, label, _v in GLOBAL_INDICES:
|
||||
vals[k] *= (1 + random.gauss(0.0002, 0.009))
|
||||
row[k] = {"label": label, "value": round(vals[k], 2),
|
||||
"chg": round((vals[k] - prev[k]) / prev[k] * 100, 2)}
|
||||
for k in prev:
|
||||
prev[k] = vals[k]
|
||||
out[d] = row
|
||||
return out
|
||||
|
||||
|
||||
def gen_holdings(price, dates):
|
||||
"""基金季度持仓:2025Q4 / 2026Q1 / 2026Q2"""
|
||||
rows = []
|
||||
@@ -424,6 +450,10 @@ def main():
|
||||
"VALUES(?,?,?,?,?,?,?,?,?)", daily)
|
||||
executemany("INSERT OR REPLACE INTO market_index(date,sh,sz,cy) VALUES(?,?,?,?)",
|
||||
[(d, v["sh"], v["sz"], v["cy"]) for d, v in index.items()])
|
||||
# 全球市场指数(模拟)
|
||||
gm = _gen_global(dates)
|
||||
executemany("INSERT OR REPLACE INTO global_markets(date,data) VALUES(?,?)",
|
||||
[(d, json.dumps(v, ensure_ascii=False)) for d, v in gm.items()])
|
||||
# 回填市值
|
||||
for code, name, industry, board, base, fs, trend, vol, biz in STOCKS:
|
||||
from database import execute as ex
|
||||
|
||||
Reference in New Issue
Block a user