时间序列挖掘的数据标签(第2部分):使用Python制作带有趋势标记的数据集·综合运用
📘

时间序列挖掘的数据标签(第2部分):使用Python制作带有趋势标记的数据集·综合运用

第 3/3 篇

拿到序列后先人工过三道筛

基础清洗跑完不代表能直接喂模型。想拿更稳的标注样本,还得靠人肉介入做几步校验,这里只点方向不展开论证。 数据完整性是第一关。它衡量的是记录是否缺失——整条断档算缺失,某个字段空着也算。评估不难:拉统计里的记录数和唯一值数就能看出端倪。比如 M15 周期里,上期收盘 1000、下期开盘突然掉到 10,中间大概率漏了棒,必须查数据源补。外汇和贵金属从 MT5 客户端导出的缺口通常少,但你要是接了外部天气或交通时间序列,这种错位极常见,高风险品种尤其要警惕幽灵缺口。 标注准不准得肉眼复核。pytrendseries 自动打的趋势标签可能过敏或迟钝,把该拆的并了、该并的拆了。这时候只能把图拉出来看,分类边界不对就手动重切。这一步最耗精力,没有捷径。 最后做点统计验证看标注分布合不合理:完整性分布图看缺失集中在哪;热图扫两个变量的相关强弱;层次聚类看不同类数据是抱团还是散沙。方法不止这三种,但这三样开 MT5 导完数用 Python 跑一遍就能筛掉大半脏样本。

◍ 把趋势段写回 MT5 行情表

下面这段 Python 把前文检测出的下行趋势段,重新映射回从 MT5 拉取的 GOLD_micro M15 行情里,生成可供训练打标签用的 trend / trend_index 两列。 初始化时若写死终端路径 D:\\Project\\mt\\MT5\\terminal64.exe,换机器必须改成你本机 terminal64.exe 实际位置,否则 mt.initialize() 会直接返回失败。行情通过 copy_rates_from_pos("GOLD_micro", mt.TIMEFRAME_M15, 0, 1000) 取最近 1000 根 15 分钟 K 线,缺失的 GOLD_micro_M15.csv 也默认落在客户端根目录。 趋势检测参数 td='downtrend'wd=120limit=6,意思是在 120 根窗口内、至少连续 6 根确认一段下行。循环里把每段 downtrend 的 trend 置 1,并用 trend_index 记录段内相对位置,便于后续做序列标签。 外汇与贵金属杠杆高、滑点大,这套标签逻辑仅用于离线数据挖掘,实盘信号有效性需自行回测验证,不预示任何方向。

MQL5 / C++
# Copyright class="num">2021, MetaQuotes Ltd.
# [MQL5官方文档]
class="kw">import MetaTrader5 as mt
class="kw">import pandas as pd
class="kw">import pytrendseries as pts
if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"):
    print(&class="macro">#x27;initialize() failed!&class="macro">#x27;)
else:
    print(mt.version())
    sb=mt.symbols_total()
    rts=None
    if sb > class="num">0:
        rts=mt.copy_rates_from_pos("GOLD_micro",mt.TIMEFRAME_M15,class="num">0,class="num">1000)
    mt.shutdown()
    rts_fm=pd.DataFrame(rts)
    rts_fm[&class="macro">#x27;time&class="macro">#x27;]=pd.to_datetime(rts_fm[&class="macro">#x27;time&class="macro">#x27;], unit=&class="macro">#x27;s&class="macro">#x27;)
    td_data=rts_fm[[&class="macro">#x27;time&class="macro">#x27;,&class="macro">#x27;close&class="macro">#x27;]].set_index(&class="macro">#x27;time&class="macro">#x27;)
    # print(td_data.head(class="num">10))
td=&class="macro">#x27;downtrend&class="macro">#x27; # or "uptrend"
wd=class="num">120
limit=class="num">6
trends=pts.detecttrend(td_data,trend=td,limit=limit,window=wd)
# print(trends.head(class="num">15))
# pts.vizplot.plot_trend(td_data,trends)
rts_fm[&class="macro">#x27;trend&class="macro">#x27;]=class="num">0
rts_fm[&class="macro">#x27;trend_index&class="macro">#x27;]=class="num">0
max_len_rts=len(rts_fm)
max_len=len(trends)
last_start=class="num">0
last_end=class="num">0
for trend in trends.iterrows():
    start=trend[class="num">1][&class="macro">#x27;index_from&class="macro">#x27;]
    end=trend[class="num">1][&class="macro">#x27;index_to&class="macro">#x27;]
    if trend[class="num">0]==class="num">1 and start!=class="num">0:
        # Since the rts_fm["trend"] itself has been initialized to class="num">0, there is no need to change the "trend" column
        rts_fm[&class="macro">#x27;trend_index&class="macro">#x27;][class="num">0:start]=list(range(class="num">0,start))
    elif trend[class="num">0]==max_len and end!=max_len_rts-class="num">1:
        class="macro">#we need to see if it ends in a downtrend at the end of the data
        rts_fm[&class="macro">#x27;trend_index&class="macro">#x27;][last_end+class="num">1:len(rts_fm)]=list(range(class="num">0,max_len_rts-last_end-class="num">1))
    else:
        class="macro">#Process the uptrend segments other than the beginning and end of the data
        rts_fm["trend_index"][last_end+class="num">1:start]=list(range(class="num">0,start-last_end-class="num">1))
    
    class="macro">#Process each segments of the downtrend
    rts_fm["trend"][start:end+class="num">1]=class="num">1
    rts_fm["trend_index"][start:end+class="num">1]=list(range(class="num">0,end-start+class="num">1))
    last_start=start
    last_end=end

「最后说句实在话」

把趋势片段切出来落盘,只需一行 loc 切片加 to_csv,就能把 M15 黄金微结构存成 GOLD_micro_M15.csv 供后续回测。 这套切法依赖 trends 表首行的 index_from 作为起点,若首行被异常值污染,导出的样本会整体偏移,开 MT5 前先 print 一下起点索引。 外汇与贵金属杠杆高、跳空频繁,导出的片段只代表历史微观结构,实盘信号概率会变,别当确定性依据。

MQL5 / C++
class="macro">#rts_fm=rts_fm.iloc[trends.iloc[class="num">0,:][&class="macro">#x27;index_from&class="macro">#x27;]:end,:]
rts_fm.to_csv(&class="macro">#x27;GOLD_micro_M15.csv&class="macro">#x27;)

常见问题

先过三道筛:去掉非交易时段噪点、标出明显高低点、确认每段是否够一个完整波动周期,只留能讲清逻辑的部分。
在行情表加趋势方向、起止价、持续时间三列,用简短代码段批量回写,后面翻历史一眼能定位。
可以,小布能按你设的阈值跑三道筛并生成带标签的数据集,你只需复核关键段,省掉重复劳动。
可能把震荡当趋势标进去了,建议只留完整周期段,外汇贵金属高风险,标签干净才能看出真实概率。
画得少看得清,只标大级别段,小波动交给工具,最后说句实在话:标签是辅助不是圣经。