- 新增 strategy_research_methodology.md(由果及因/12维/铁律/支撑压力规范) - 新增 predictive_oversold_strategy.md(v5定稿,年化18.57%) - 新增 deployment-plan-predictive-oversold.md(整合部署计划) - 归档 docs/research/(63份研究过程文档)+ scripts/research/(19个研究脚本) - 更新 docs/README.md 文档中心(策略研究章节)
52 lines
2.1 KiB
Python
52 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""step45_negative_v2.py — 负面过滤 v2(时间稳健版)
|
|
问题:绝对阈值(mkt_news5>=1500)受新闻量逐年增长影响,早年信号被误杀
|
|
改进:新闻量用"当年分位"(年内相对热度),不受绝对量影响
|
|
同时用交易数据验证:年份内相对特征是否仍是负面因子
|
|
"""
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
print("=== 加载 ===", flush=True)
|
|
tr = pd.read_csv("/tmp/step43_trades.csv")
|
|
tr["year"] = tr["date"].str[:4]
|
|
print("交易:", len(tr), flush=True)
|
|
|
|
# 年内新闻分位(每笔交易按其所在年份的新闻量排名)
|
|
tr["news_yq"] = tr.groupby("year")["mkt_news5"].rank(pct=True)
|
|
# 年内 adx 分位
|
|
tr["adx_yq"] = tr.groupby("year")["sig_mkt_adx"].rank(pct=True)
|
|
|
|
def evaluate(cond, label):
|
|
sub = tr[cond]
|
|
if len(sub) < 50:
|
|
print("{}: n={} 不足".format(label, len(sub)), flush=True)
|
|
return
|
|
avg = sub["ret"].mean()
|
|
wr = (sub["ret"]>0).mean()*100
|
|
big_loss = (sub["ret"]<-10).mean()*100
|
|
print("{}: n={} avg={:.2f}% wr={:.1f}% 大亏率={:.1f}%".format(
|
|
label, len(sub), avg, wr, big_loss), flush=True)
|
|
return len(sub)
|
|
|
|
print("\n=== 年内分位版负面因子 ===", flush=True)
|
|
print("\n-- 新闻年内分位 --", flush=True)
|
|
for t in [0.3, 0.5, 0.6, 0.7]:
|
|
evaluate(tr["news_yq"] >= t, "news年内分位>={}".format(t))
|
|
|
|
print("\n-- adx年内分位 --", flush=True)
|
|
for t in [0.5, 0.6, 0.7]:
|
|
evaluate(tr["adx_yq"] >= t, "adx年内分位>={}".format(t))
|
|
|
|
print("\n-- 组合(年内分位) --", flush=True)
|
|
evaluate((tr["news_yq"] >= 0.5) & (tr["mkt_down_days"] <= 2), "news50%+down<=2")
|
|
evaluate((tr["news_yq"] >= 0.5) & (tr["mkt_down_days"] <= 2) & (tr["sig_flow1"] >= -1e7), "news50%+down<=2+flow>-1e7")
|
|
evaluate((tr["news_yq"] >= 0.5) & (tr["adx_yq"] >= 0.5) & (tr["mkt_down_days"] <= 2), "news50%+adx50%+down<=2")
|
|
|
|
# 分年覆盖
|
|
comb = (tr["news_yq"] >= 0.5) & (tr["mkt_down_days"] <= 2) & (tr["sig_flow1"] >= -1e7)
|
|
print("\n组合分年:", tr[comb]["year"].value_counts().sort_index().to_dict(), flush=True)
|
|
print("保留:", comb.sum(), "/", len(tr), "({:.1f}%)".format(comb.mean()*100), flush=True)
|
|
|
|
print("\n=== 完成 ===", flush=True)
|