理查德·唐迁(Richard Donchian)是20世纪中期美国职业期货交易员,被誉为“趋势交易之父”。他最著名的贡献之一是发明了“四周规则”(Four-Week Rule)。具体操作如下:
- 只要价格涨过前四周内的最高价,就平掉空头仓位并做多;
- 只要价格跌破前四周内的最低价,就平掉多头仓位并做空。
操作逻辑是:如果价格超过了四周的最高价,说明目前是上升趋势,在上升趋势中,高点会一个比一个高,故做多。如果价格低于了四周的最低价,说明目前是下跌趋势,在下跌趋势中,低点会一个比一个低,故做空。
该系统跟踪市场趋势,交易频率较低,操作简单。

国内有些交易者把四周法则的四周时间改为了4个交易日,用于股市交易,也许是我们的大A牛短熊长,更适合做短线。
下面我们就用python代码,在QMT量化系统上编写这一策略。
#encoding:gbk
'''
四周法则策略,股价大于前4日最高价,全仓买入,小于前4日最低价,全仓卖出
注意:本策仅用于python量化学习,不用于真实交易
'''
import pandas as pd
import numpy as np
def init(C):
# 设置股票代码和账户ID
C.stock= C.stockcode + '.' +C.market
C.accID = 'your accID'
# 设置周期
C.MY_period = 4
def handlebar(C):
# 计算前4日最高价和最低价,及最新收盘价
bar_date = timetag_to_datetime(C.get_bar_timetag(C.barpos), '%Y%m%d%H%M%S') #当前k线日期
data = C.get_market_data_ex(
['close', 'high', 'low'],
[C.stock],
end_time=bar_date,
period=C.period,
dividend_type='none',
subscribe = True
)
close = data[C.stock]['close']
high = data[C.stock]['high']
low = data[C.stock]['low']
HIGH_4 = pd.Series(high).rolling(window=C.MY_period).max() #计算四日最大值
LOW_4 = pd.Series(low).rolling(window=C.MY_period).min() #计算四日最小值
# 获取账户信息
account_info = get_trade_detail_data(C.accID, 'stock', 'account')
if not account_info:
print("无法获取账户信息")
return
account_info = account_info[0]
available_cash = int(account_info.m_dAvailable) # 可用资金
holdings = get_trade_detail_data(C.accID, 'stock', 'position')
holdings = {i.m_strInstrumentID + '.' + i.m_strExchangeID : i.m_nVolume for i in holdings}
holding_vol = holdings[C.stock] if C.stock in holdings else 0
# 全仓买入逻辑
if holding_vol == 0 and close[-1] > HIGH_4[-2]:
print("此时超过了最高价!")
# 计算买入数量,向下取整
buy_volume = available_cash // close[-1]
# 下单买入
passorder(23, 1101, C.accID, C.stock, 5, -1, buy_volume, C)
print(f"{bar_date} 开仓")
print("holding_vol=",holding_vol)
C.draw_text(1, 1, '买')
# 全仓卖出逻辑
elif holding_vol > 0 and close.iloc[-1] < LOW_4.iloc[-2]:
print("此时低于最低价!")
# 获取持仓信息
position_info = get_trade_detail_data(C.accID, 'stock', 'position')
if not position_info:
print("无法获取持仓信息")
return
# 下单卖出
passorder(24, 1101, C.accID, C.stock, 5, -1, holding_vol, C)
print(f"{bar_date} 平仓")
C.draw_text(1, 1, '卖')
holdings = get_trade_detail_data(C.accID, 'stock', 'position')
holdings = {i.m_strInstrumentID + '.' + i.m_strExchangeID : i.m_nVolume for i in holdings}
holding_vol = holdings[C.stock] if C.stock in holdings else 0
print("现在持股数量为:",holding_vol)
account_info = get_trade_detail_data(C.accID, 'stock', 'account')
account_info = account_info[0]
available_cash = int(account_info.m_dAvailable) # 可用资金
print("可用资金为:",available_cash)
首先在init(C)中设定计算周期,即要计算多少天内的最高价和最低价:
C.MY_period = 4 (4为4个交易日,如果你想完全按理查德·唐迁的四周法则,那么周期就设为20)
接着用data = C.get_market_data_ex()来获取行情数据,只提取收盘价、最高价和最低价,分别是:
收盘价: close = data[C.stock][‘close’]
最高价: high = data[C.stock][‘high’]
最低价: low = data[C.stock][‘low’]
这里得到的收盘价、最高价和最低价,都是Series数据,所谓Series数据,它 是 Pandas 库中的一种基本数据结构,由一组数据和行索引构成。
再用pandas里的max()函数计算前四个交易日的最高价,用min()函数来计算最低价,并用rolling()来进行滚动计算,(window=C.MY_period)是滚动计算的范围,之前设定了MY_period=4,也就是滚动计算4天内的最高价和最低价:
HIGH_4 = pd.Series(high).rolling(window=C.MY_period).max() #计算四日最大值
LOW_4 = pd.Series(low).rolling(window=C.MY_period).min() #计算四日最小值
最后我们就比较收盘价与最高价、最低价的高低来进行买卖,下单函数我们已在之前的文章中做过介绍。
代码写好后,我们来看看回测结果:






以上图片为选择4个交易日的回测结果,初始本金1000000元,三年时间,累积到了1765751元。如果C.MY_period = 20 又会如何呢?以下是20个交易日是回测结果:

选择20个交易日内的最高价和最低价,年化收益反而更低了。
我们再改一下,还是C.MY_period = 4 ,但我们用周线来回测:

年化收益为-0.3118,居然亏了!!
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/73460
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!