
많은 거래 전략 중에서 Donchian Channel 전략은 가장 고전적인 돌파구 전략 중 하나여야 합니다. 1970년대 초에 잘 알려져 있었습니다. 그 당시 외국 회사가 주류 프로그램 거래 전략에 대한 시뮬레이션 테스트와 연구를 수행했습니다. 그 결과는 다음과 같습니다. 모든 전략 테스트 중에서 돈키안 채널 전략이 가장 성공적이었습니다.
그 후, 거래 역사상 가장 유명한 “거북이” 거래자 훈련이 미국에서 이루어졌고, 이는 엄청난 성공을 거두었습니다. 당시 ‘거북이’의 거래 방식은 비밀로 유지됐지만 10여년 후 ‘거북이 거래 규칙’이 공개되자 ‘거북이’가 돈키안 채널을 개량한 버전을 사용하고 있다는 사실이 드러났다. 전략.
돌파 거래 전략은 비교적 매끄러운 추세를 가진 상품 거래에 적합합니다. 가장 일반적인 돌파 거래 방법은 가격과 지지 및 저항 사이의 상대적 위치 관계를 사용하여 특정 거래 매수 및 매도 지점을 결정하는 것입니다. 이 섹션의 돈키안 채널 전략은 이 원칙에 기초하고 있습니다.
돈키안 채널은 추세 지표이며, 그 모양과 신호는 볼린저 밴드 지표와 다소 비슷합니다. 하지만 돈키안의 가격 채널은 특정 기간 내의 최고 가격과 최저가를 기반으로 구성됩니다. 예를 들어: 최신 50개 K-라인의 최고 가격의 최대값을 계산하여 상단 트랙을 형성합니다. 최신 50개 K-라인의 최저 가격의 최소값을 계산하여 하단 트랙을 형성합니다.

위 그림에서 보여지는 것처럼: 이 지표는 서로 다른 색상의 세 개의 곡선으로 구성되어 있습니다. 기본값은 20주기 내의 최고가와 최저가로 시장 가격의 변동성을 보여줍니다. 채널이 좁을 때 시장 변동성이 작다는 것을 의미합니다. , 그렇지 않으면 채널이 좁습니다. 범위가 넓으면 시장이 더 변동성이 크다는 것을 나타냅니다.
가격이 상단 트랙 위로 오르면 매수 신호이고, 반대로 가격이 하단 트랙 아래로 떨어지면 매도 신호입니다. 상단 및 하단 트랙은 최고 가격과 최저 가격을 사용하여 계산되므로, 일반적인 상황에서는 가격이 동시에 상단 및 하단 채널선 아래로 오르거나 내리는 경우가 거의 없습니다. 대부분의 경우, 가격은 상단이나 하단 트랙을 따라 일방적으로 움직이거나 상단과 하단 트랙 사이에서 움직입니다.
Donchian Channel을 사용하는 방법은 여러 가지가 있습니다. 단독으로 사용하거나 다른 지표와 함께 사용할 수 있습니다. 이 과정에서는 가장 간단한 방법을 사용하겠습니다. 즉, 가격이 바닥에서 꼭대기까지 상단 트랙을 돌파할 때, 즉 상단 압력선을 돌파할 때, 우리는 강세력이 강해지고 상승장세가 형성되었으며 매수 개시 신호라고 믿습니다. 생성된다; 가격이 상단에서 하단으로 떨어지고 하단 트랙을 돌파할 때, 즉 지지선을 아래로 떨어질 때, 우리는 숏 사이드가 강해지고 하락 추세가 형성되었으며 매도 오픈이 되었다고 믿는다. 신호가 생성됩니다.

롱 포지션이 오픈된 후 가격이 Donchian Channel의 중간 트랙으로 다시 떨어지면 우리는 강세가 약화되고 있거나 약세가 강해지고 있다고 믿고 매도 신호가 생성됩니다. 가격이 중간 트랙으로 다시 떨어지면 Donchian Channel의 숏 포지션이 오픈된 후 트랙이 상승할 때 우리는 황소가 약해지고 있거나 곰이 강해지고 있다고 믿고 매도 신호가 생성됩니다. Donchian Channel의 중간 트랙으로 다시 상승할 때 우리는 하락장의 힘이 약해지고 있거나, 상승장의 힘이 강해지고 있으며, 매수-종료 신호가 생성됩니다.
거래 조건
다음으로, Inventor Quantitative Platform의 연구 환경에서 이 전략을 단계적으로 살펴보겠습니다.
Inventor Quantitative Platform의 연구 환경에 들어가려면 다음 그림을 참조하세요.

from fmz import *
task = VCtx('''backtest
start: 2019-08-01 09:00:00
end: 2019-10-10 15:00:00
period: 5m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
''')
# 创建回测环境
# 以上红色部分内容的关于回测信息的范例格式,可以在发明者量化平台的策略编写页面中点击“保存回测设置”获取# 首先,我们需要获取持仓信息,我们定义一个mp()函数用来干这件事
def mp():
positions = exchange.GetPosition() # 获取持仓数组
if len(positions) == 0: # 如果持仓数组的长度是0
return 0 # 证明是空仓,返回0
for i in range(len(positions)): # 遍历持仓数组
if (positions[i]['Type'] == PD_LONG) or (positions[i]['Type'] == PD_LONG_YD):
return 1 # 如果有多单,返回1
elif (positions[i]['Type'] == PD_SHORT) or (positions[i]['Type'] == PD_SHORT_YD):
return -1 # 如果有空单,返回-1
print(positions)
mp() # 接下来,我们执行一下这个获取持仓信息函数,可以看到,结果为0,也就是目前为空仓状态0
# 我们以当前螺纹钢主力合约为例子,开始测试这个策略
exchange.SetContractType("rb888") # 设置品种代码,主力合约为合约代码后加数字888{'CombinationType': 0,
'CreateDate': 0,
'DeliveryMonth': 9,
'DeliveryYear': 0,
'EndDelivDate': 0,
'ExchangeID': 'SHFE',
'ExchangeInstID': 'rb888',
'ExpireDate': 0,
'InstLifePhase': 49,
'InstrumentID': 'rb888',
'InstrumentName': 'rb连续',
'IsTrading': 1,
'LongMarginRatio': 0.06,
'MaxLimitOrderVolume': 500,
'MaxMarginSideAlgorithm': 49,
'MaxMarketOrderVolume': 30,
'MinLimitOrderVolume': 1,
'MinMarketOrderVolume': 1,
'OpenDate': 0,
'OptionsType': 48,
'PositionDateType': 49,
'PositionType': 50,
'PriceTick': 1,
'ProductClass': 49,
'ProductID': 'rb',
'ShortMarginRatio': 0.06,
'StartDelivDate': 0,
'StrikePrice': 0,
'UnderlyingInstrID': 'rb',
'UnderlyingMultiple': 1,
'VolumeMultiple': 10}接下来我们获取k线数组,因为根据策略逻辑,我们需要行情运行了一段时间,再进行逻辑判断,这样有便于我们的策略逻辑更好的适应行情,这里我们就暂且把50根K线作为起始要求吧。发明者量化的K线信息是以数组的形式储存的,数组里包含最高价,最低价,开盘价,收盘价和成交量等等信息,关于这部分的内容请查看发明者量化的官方API文档:https://www.fmz.com/api
# 接下来我们定义一个变量,让它来存储K线数组 records = exchange.GetRecords() # 获取K线数组
# 按照策略逻辑描述,我们用收盘价来作为开仓的价格,所以我们需要计算最新K线的收盘价 close = records[len(records) - 1].Close # 获取最新K线收盘价 close
3846.0
然后,我们需要以收盘价为标准计算50根k线中最高价的最大值和最低价的最小值
upper = TA.Highest(records, 50, 'High') # 获取50周期最高价的最大值 upper
3903.0
lower = TA.Lowest(records, 50, 'Low') # 获取50周期最低价的最小值 lower
3856.0
接着,我们需要计算这条通道的上轨和下轨的均值
middle = (upper + lower) / 2 # 计算上轨和下轨的均值 middle
3879.5
以上,关于此策略需要计算的部分我们已经全部完成,接下来,我们就要开始逻辑判断开仓条件,以及根据逻辑判断的结果进行实际的开仓操作。这里需要注意的是,我们需要用到发明者量化平台的国内商品期货模版,由于当下是研究环境,无法支持这个模版,我们暂且写出来,但是运行会报错,在发明者量化平台的策略编写页面进行实际编码时,导入此模版没有任何问题,模版地址为:https://www.fmz.com/strategy/24288 各位在发明者量化策略编写页面进行编码时,需要把此模版先复制到自己的策略库,然后在回测时勾选上,这里请各位读者注意
obj = ext.NewPositionManager() # 使用发明者量化交易类库,这里运行时会报错,不用理会,当下是研究环境,
# 实际编码过程中不会出现此问题,以下同此,不再注释。接下来是策略的判断逻辑,并且根据逻辑进行开仓与平仓操作
if positions > 0 and close < middle: # 如果持多单,并且收盘价跌破中轨
obj.CoverAll() # 平掉所有仓位
if positions < 0 and close > middle: # 如果持空单,并且收盘价升破中轨
obj.CoverAll() # 平掉所有仓位
if positions == 0: # 如果是空仓
if close > upper: # 如果收盘价升破上轨
obj.OpenLong("rb888", 1) # 买开
elif close < lower: # 如果收盘价跌破下轨
obj.OpenShort("rb888", 1) # 卖开# 完整的策略代码:
def mp():
positions = exchange.GetPosition() # 获取持仓数组
if len(positions) == 0: # 如果持仓数组的长度是0
return 0 # 证明是空仓,返回0
for i in range(len(positions)): # 遍历持仓数组
if (positions[i]['Type'] == PD_LONG) or (positions[i]['Type'] == PD_LONG_YD):
return 1 # 如果有多单,返回1
elif (positions[i]['Type'] == PD_SHORT) or (positions[i]['Type'] == PD_SHORT_YD):
return -1 # 如果有空单,返回-1
def main(): # 主函数
exchange.SetContractType("rb888") # 设置品种代码,主力合约为合约代码后加数字888
while True: # 进入循环
records = exchange.GetRecords() # 获取K线数组
if len(records) < 50: continue # 如果K线少于50根,就跳过本次循环
close = records[len(records) - 1].Close # 获取最新K线收盘价
positions = mp() # 获取持仓信息函数
upper = TA.Highest(records, 50, 'High') # 获取50周期最高价的最大值
lower = TA.Lowest(records, 50, 'Low') # 获取50周期最低价的最小值
middle = (upper + lower) / 2 # 计算上轨和下轨的均值
obj = ext.NewPositionManager() # 使用交易类库
if positions > 0 and close < middle: # 如果持多单,并且收盘价跌破中轨
obj.CoverAll() # 平掉所有仓位
if positions < 0 and close > middle: # 如果持空单,并且收盘价升破中轨
obj.CoverAll() # 平掉所有仓位
if positions == 0: # 如果是空仓
if close > upper: # 如果收盘价升破上轨
obj.OpenLong("rb888", 1) # 买开
elif close < lower: # 如果收盘价跌破下轨
obj.OpenShort("rb888", 1) # 卖开