当前位置:首页>python>第29篇 量化实战 Python构建双均线策略

第29篇 量化实战 Python构建双均线策略

  • 2026-10-11 08:05:22
第29篇 量化实战 Python构建双均线策略

双均线策略是各类股票软件及交易平台的标配功能,无论是同花顺还是券商客户端均广泛支持。本节将简要梳理该策略的逻辑渊源,并演示如何编写其交易信号。

1、双均线策略解析

该策略依托两条移动平均线(MA):一条短周期均线与一条长周期均线。二者均基于不同时间跨度的收盘价均值计算得出。

短周期均线:通常选取近期数据(如10日或20日),旨在捕捉股价的短期波动趋势。

长周期均线:基于较长时段数据(如60日或100日),用于揭示股票的长期运行方向。

策略核心法则:

金叉买入:当短周期均线自下而上穿越长周期均线时,视为买入信号。这暗示短期动能转强,预示价格可能上行。

死叉卖出:当短周期均线自上而下跌破长周期均线时,视为卖出信号。这意味着短期势头走弱,预示价格可能回调。

在A股市场,由于缺乏做空机制,操作简化为“金叉建仓、死叉平仓”。而在具备做空机制的其他市场,逻辑则更为复杂。

2、Python信号编写实战

明确规则后,我们利用Python代码实现该策略。以创业板龙头股特锐德2023年1月至12月的历史数据为例进行演示:

首先导入数据集,并编写基础代码如下:

import pandas as pdimport numpy as nppd.set_option('display.max_rows', 1000) #最大显示的行数pd.set_option('expand_frame_repr', False)  # 当列太多时不换行#读取创业板特锐德数据file_path = '特锐德2023股票数据.csv'data = pd.read_csv(file_path)data = data[['股票名字','交易日期','开盘价','收盘价','最高价','最低价','成交量','成交额']]print(data.head())>>  股票名字        交易日期    开盘价    收盘价    最高价    最低价    成交量          成交额0  特锐德  2023-01-03  15.20  15.45  15.53  15.04  68790  105716309.01  特锐德  2023-01-04  15.44  15.35  15.55  15.25  55797   86230918.02  特锐德  2023-01-05  15.44  15.51  15.61  15.30  65886  102419685.03  特锐德  2023-01-06  15.45  15.57  15.77  15.45  67721  106339926.04  特锐德  2023-01-09  15.75  15.82  16.13  15.65  94456  150887826.0

计算5日与10日均线的值:

# 计算均线,我们以5日线和10日线演示paras = [5,10]data['ma_fast'] = data['收盘价'].rolling(window=paras[0], min_periods=1).mean()data['ma_slow'] = data['收盘价'].rolling(window=paras[1], min_periods=1).mean()

利用rolling函数直接计算均线数值,当然也可借助talib库实现(该部分将留待进阶课程详解)。

构建策略信号:

# 计算信号data['Signal'] = np.NAN#当前快线大于慢线,前一根的块线小于慢线 则开多cond1 = data['ma_fast'] > data['ma_slow']cond2 = data['ma_fast'].shift(1) <= data['ma_slow'].shift(1)open_pos_signal = cond1 & cond2data.loc[open_pos_signal, 'Signal'] = 1#当前快线小于慢线,前一根的快线大于慢线 则平仓cond3 = data['ma_fast'] < data['ma_slow']cond4 = data['ma_fast'].shift(1) >= data['ma_slow'].shift(1)close_pos_signal = cond3 & cond4data.loc[close_pos_signal, 'Signal'] = 0

首先将策略信号列Signal初始化为空值。

构建多头仓位需满足双重条件:

如图所示,红色代表5日快速均线,蓝色代表10日慢速均线。

当今日5日均线高于10日均线(预示股价上行),且昨日5日均线低于10日均线时,两项条件同时成立,确认为开仓信号。随后于次日开盘执行买入,或按前一日收盘价在夜间挂单。

在量化交易中,通常以long指代多头头寸,即买入操作。

# 计算信号data['Signal'] = np.NAN#当前快线大于慢线,前一根的块线小于慢线 则开多cond1 = data['ma_fast'] > data['ma_slow']cond2 = data['ma_fast'].shift(1) <= data['ma_slow'].shift(1)open_pos_signal = cond1 & cond2data.loc[open_pos_signal, 'Signal'] = 1#当前快线小于慢线,前一根的快线大于慢线 则平仓cond3 = data['ma_fast'] < data['ma_slow']cond4 = data['ma_fast'].shift(1) >= data['ma_slow'].shift(1)close_pos_signal = cond3 & cond4data.loc[close_pos_signal, 'Signal'] = 0print(data[['股票名字','交易日期','收盘价','ma_fast','ma_slow','Signal']].head(20))>>股票名字        交易日期    收盘价    ma_fast    ma_slow  Signal219  特锐德  2023-11-29  19.15  18.946000  18.982000     NaN220  特锐德  2023-11-30  19.17  18.990000  19.015000     NaN221  特锐德  2023-12-01  18.93  19.034000  18.990000     1.0222  特锐德  2023-12-04  18.84  19.034000  18.952000     NaN223  特锐德  2023-12-05  18.63  18.944000  18.903000     NaN224  特锐德  2023-12-06  18.73  18.860000  18.903000     0.0225  特锐德  2023-12-07  18.79  18.784000  18.887000     NaN226  特锐德  2023-12-08  19.03  18.804000  18.919000     NaN227  特锐德  2023-12-11  19.29  18.894000  18.964000     NaN

针对12月1日的交易信号进行解析:

当日快速均线(ma-fast)为19.034,高于慢速均线(ma-slow)的18.99;而前一日11月30日,快速均线18.99低于慢速均线19.01。

这种由下向上的穿越形态触发策略生成信号1,指示执行做多操作。

再看12月6日的平仓信号:当日快速均线18.73跌破慢速均线18.90;反观前一日12月5日,快速均线18.63尚高于慢速均线18.94(注:此处依原文数据逻辑陈述)。

这种由上向下的穿越导致策略输出信号0,意味着执行平仓指令。

3、信号数据清洗

观察数据表可知,存在大量NaN空值,严重干扰视觉判断。为了提升可读性,我们截取前20行数据进行详细审视:

股票名字        交易日期    收盘价    ma_fast    ma_slow  Signal0    特锐德  2023-01-03  15.45  15.450000  15.450000     NaN1    特锐德  2023-01-04  15.35  15.400000  15.400000     NaN2    特锐德  2023-01-05  15.51  15.436667  15.436667     NaN3    特锐德  2023-01-06  15.57  15.470000  15.470000     NaN4    特锐德  2023-01-09  15.82  15.540000  15.540000     NaN5    特锐德  2023-01-10  15.98  15.646000  15.613333     1.06    特锐德  2023-01-11  15.71  15.718000  15.627143     NaN7    特锐德  2023-01-12  15.82  15.780000  15.651250     NaN8    特锐德  2023-01-13  15.86  15.838000  15.674444     NaN9    特锐德  2023-01-16  15.96  15.866000  15.703000     NaN10   特锐德  2023-01-17  16.11  15.892000  15.769000     NaN11   特锐德  2023-01-18  16.20  15.990000  15.854000     NaN12   特锐德  2023-01-19  16.43  16.112000  15.946000     NaN13   特锐德  2023-01-20  16.50  16.240000  16.039000     NaN14   特锐德  2023-01-30  16.86  16.420000  16.143000     NaN15   特锐德  2023-01-31  16.95  16.588000  16.240000     NaN16   特锐德  2023-02-01  17.36  16.820000  16.405000     NaN17   特锐德  2023-02-02  17.14  16.962000  16.537000     NaN18   特锐德  2023-02-03  17.12  17.086000  16.663000     NaN19   特锐德  2023-02-06  17.33  17.180000  16.800000     NaN20   特锐德  2023-02-07  17.60  17.310000  16.949000     NaN21   特锐德  2023-02-08  17.33  17.304000  17.062000     NaN22   特锐德  2023-02-09  17.42  17.360000  17.161000     NaN23   特锐德  2023-02-10  17.52  17.440000  17.263000     NaN24   特锐德  2023-02-13  17.70  17.514000  17.347000     NaN25   特锐德  2023-02-14  18.45  17.684000  17.497000     NaN26   特锐德  2023-02-15  19.21  18.060000  17.682000     NaN27   特锐德  2023-02-16  18.23  18.222000  17.791000     NaN28   特锐德  2023-02-17  18.00  18.318000  17.879000     NaN29   特锐德  2023-02-20  17.90  18.358000  17.936000     NaN30   特锐德  2023-02-21  17.96  18.260000  17.972000     NaN31   特锐德  2023-02-22  17.98  18.014000  18.037000     0.032   特锐德  2023-02-23  17.60  17.888000  18.055000     NaN33   特锐德  2023-02-24  17.34  17.756000  18.037000     NaN34   特锐德  2023-02-27  17.40  17.656000  18.007000     NaN

观察发现,1月3日至9日信号均为NaN空值。

9日后本应确立多头仓位,却仍显示为空;直至2月22日触发平仓后,后续空仓期间也全为NaN。显然,这些缺失值必须经过处理才能使用。

# 对信号列进行处理# 对NaN信号,使用之前的值进行补全data['Signal'].fillna(method='ffill',inplace=True)# 对于初始的信号还是有一些空值,我们需要把这些signal值补全为0,表示没有交易信号data['Signal'].fillna(value=0, inplace=True)print(data[['股票名字','交易日期','收盘价','ma_fast','ma_slow','Signal']])

打印数据看一下结果:

股票名字        交易日期    收盘价    ma_fast    ma_slow  Signal0    特锐德  2023-01-03  15.45  15.450000  15.450000     0.01    特锐德  2023-01-04  15.35  15.400000  15.400000     0.02    特锐德  2023-01-05  15.51  15.436667  15.436667     0.03    特锐德  2023-01-06  15.57  15.470000  15.470000     0.04    特锐德  2023-01-09  15.82  15.540000  15.540000     0.05    特锐德  2023-01-10  15.98  15.646000  15.613333     1.06    特锐德  2023-01-11  15.71  15.718000  15.627143     1.07    特锐德  2023-01-12  15.82  15.780000  15.651250     1.08    特锐德  2023-01-13  15.86  15.838000  15.674444     1.09    特锐德  2023-01-16  15.96  15.866000  15.703000     1.010   特锐德  2023-01-17  16.11  15.892000  15.769000     1.011   特锐德  2023-01-18  16.20  15.990000  15.854000     1.012   特锐德  2023-01-19  16.43  16.112000  15.946000     1.013   特锐德  2023-01-20  16.50  16.240000  16.039000     1.014   特锐德  2023-01-30  16.86  16.420000  16.143000     1.015   特锐德  2023-01-31  16.95  16.588000  16.240000     1.016   特锐德  2023-02-01  17.36  16.820000  16.405000     1.017   特锐德  2023-02-02  17.14  16.962000  16.537000     1.018   特锐德  2023-02-03  17.12  17.086000  16.663000     1.019   特锐德  2023-02-06  17.33  17.180000  16.800000     1.020   特锐德  2023-02-07  17.60  17.310000  16.949000     1.021   特锐德  2023-02-08  17.33  17.304000  17.062000     1.022   特锐德  2023-02-09  17.42  17.360000  17.161000     1.023   特锐德  2023-02-10  17.52  17.440000  17.263000     1.024   特锐德  2023-02-13  17.70  17.514000  17.347000     1.025   特锐德  2023-02-14  18.45  17.684000  17.497000     1.026   特锐德  2023-02-15  19.21  18.060000  17.682000     1.027   特锐德  2023-02-16  18.23  18.222000  17.791000     1.028   特锐德  2023-02-17  18.00  18.318000  17.879000     1.029   特锐德  2023-02-20  17.90  18.358000  17.936000     1.030   特锐德  2023-02-21  17.96  18.260000  17.972000     1.031   特锐德  2023-02-22  17.98  18.014000  18.037000     0.032   特锐德  2023-02-23  17.60  17.888000  18.055000     0.033   特锐德  2023-02-24  17.34  17.756000  18.037000     0.034   特锐德  2023-02-27  17.40  17.656000  18.007000     0.0

对Signal列执行前向填充(fillna(method='ffill')),旨在保持持仓状态连贯。例如1月10日开仓后,若无新信号,每日信号均维持为1。

初始阶段(1月3日至9日)的空值则统一补0。

此为双均线策略基础,作为量化入门经典案例。

最新文章

随机文章