Files
chan.py/Debug/xgboost_eval.py
T
2025-06-10 01:16:09 +08:00

167 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
from typing import Dict, TypedDict
import sys
import os
sys.path.append(os.path.abspath("/Users/jack/Project/chan.py"))
sys.path.append(os.path.abspath("/Users/jack/Project/chan.py/Debug"))
import xgboost as xgb
from BuySellPoint.BS_Point import CBS_Point
from Chan import CChan
from ChanConfig import CChanConfig
from ChanModel.Features import CFeatures
from Common.CEnum import AUTYPE, DATA_SRC, KL_TYPE, BSP_TYPE, MACD_ALGO
from Common.CTime import CTime
from Plot.PlotDriver import CPlotDriver
from Bi.Bi import CBi
from FeatureDict import FeatureDict
class T_SAMPLE_INFO(TypedDict):
feature: CFeatures
is_buy: bool
open_time: CTime
def plot(chan, plot_marker):
plot_config = {
"plot_kline": True,
"plot_bi": True,
"plot_seg": True,
"plot_zs": True,
"plot_bsp": True,
"plot_marker": True,
"plot_macd": True,
}
plot_para = {
"figure": {
"x_range": 4000,
},
"marker": {
"markers": plot_marker
}
}
plot_driver = CPlotDriver(
chan,
plot_config=plot_config,
plot_para=plot_para,
)
plot_driver.save2img("eval.png")
def predict_bsp(last_bsp: CBS_Point):
model = xgb.Booster()
if last_bsp.is_buy:
model.load_model("buy_model.json")
else:
model.load_model("sell_model.json")
meta = json.load(open("feature.meta", "r"))
missing = -9999999
feature_arr = [missing] * len(meta)
for feat_name, feat_value in last_bsp.features.items():
if feat_name in meta:
feature_arr[meta[feat_name]] = feat_value
feature_arr = [feature_arr]
dtest = xgb.DMatrix(feature_arr, missing=missing)
return model.predict(dtest)
if __name__ == "__main__":
"""
本demo主要演示如何记录策略产出的买卖点的特征
然后将这些特征作为样本,训练一个模型(以XGB为demo)
用于预测买卖点的准确性
请注意,demo训练预测都用的是同一份数据,这是不合理的,仅仅是为了演示
"""
code = "BTC/USDT:USDT"
begin_time = "2024-12-1"
end_time = "2024-12-20"
data_src = DATA_SRC.CCXT
lv_list = [KL_TYPE.K_1M]
config = CChanConfig({
"trigger_step": True, # 打开开关!
"bi_strict": True,
"skip_step": 0,
"divergence_rate": float("inf"),
"bsp2_follow_1": False,
"bsp3_follow_1": False,
"min_zs_cnt": 0,
"bs1_peak": False,
"macd_algo": "peak",
"bs_type": '1,2,3a,1p,2s,3b',
"print_warning": True,
"zs_algo": "normal",
"cal_rsi": True,
"cal_kdj": True,
})
chan = CChan(
code=code,
begin_time=begin_time,
end_time=end_time,
data_src=data_src,
lv_list=lv_list,
config=config,
autype=AUTYPE.QFQ,
)
bsp_dict: Dict[int, T_SAMPLE_INFO] = {} # 存储策略产出的bsp的特征
# 跑策略,保存买卖点的特征
index = 0
evals_count = 0
eval_klu_list = []
for chan_snapshot in chan.step_load():
last_klu = chan_snapshot[0][-1][-1]
bsp_list = chan_snapshot.get_bsp()
if not bsp_list:
continue
last_bsp = bsp_list[-1]
cur_lv_chan = chan_snapshot[0]
if BSP_TYPE.T1 in last_bsp.type or BSP_TYPE.T1P in last_bsp.type:
if last_bsp.klu.idx not in bsp_dict and cur_lv_chan[-2].idx == last_bsp.klu.klc.idx:
# 假如策略是:买卖点分形第三元素出现时交易
bsp_dict[last_bsp.klu.idx] = {
"feature": last_bsp.features,
"is_buy": last_bsp.is_buy,
"open_time": last_klu.time,
}
bsp_dict[last_bsp.klu.idx]['feature'].add_feat(FeatureDict().stragety_feature(last_bsp)) # 开仓K线特征
score = predict_bsp(last_bsp)
ok = ""
if score > 0.5:
ok = "OK"
evals_count = evals_count + 1
eval_klu_list.append(last_bsp.klu.idx)
print(index, last_bsp.klu.time, last_bsp.is_buy, score, ok)
index += 1
# 生成libsvm样本特征
bsp_academy = [bsp.klu.idx for bsp in chan.get_bsp()]
feature_meta = {} # 特征meta
cur_feature_idx = 0
plot_marker = {}
fid = open("eval_feature.libsvm", "w")
label_count = 0
for bsp_klu_idx, feature_info in bsp_dict.items():
label = int(bsp_klu_idx in bsp_academy) # 以买卖点识别是否准确为label
features = [] # List[(idx, value)]
for feature_name, value in feature_info['feature'].items():
if feature_name not in feature_meta:
feature_meta[feature_name] = cur_feature_idx
cur_feature_idx += 1
features.append((feature_meta[feature_name], value))
features.sort(key=lambda x: x[0])
feature_str = " ".join([f"{idx}:{value}" for idx, value in features])
fid.write(f"{label} {feature_str}\n")
plot_marker[feature_info["open_time"].to_str()] = ("√ "+ feature_info["open_time"].to_str() if label else "×", "down" if feature_info["is_buy"] else "up")
if label:
label_count = label_count + 1
fid.close()
print("Evals count: ", evals_count, "Lable count: ", label_count)
with open("feature.meta", "w") as fid:
# meta保存下来,实盘预测时特征对齐用
fid.write(json.dumps(feature_meta))
# 画图检查label是否正确
plot(chan, plot_marker)