研究環境における唐津通路戦略の分析

作者: リン・ハーン優しさ, 作成日:2019年10月11日 16:11:17, 更新日:2023年10月18日 19:57:41

img

戦略の概要

多くの取引戦略の中で,唐通路戦略は最も古典的な突破策の一つであるべきであり,1970年代には,外国企業が主流の程序化された取引戦略を専念してシミュレーションテストと研究を行ったとき,最も成功した戦略テストの結果を示した.

その後,アメリカでは,取引史上最も有名な海トレーダーの訓練が行われ,大きな成功を収めた.海の取引方法は秘密であったが,海の取引法が公表されてから10年以上経ってから,海の海が使用しているのが改良された唐通路戦略であることが明らかになった.

突破型取引戦略は,走勢が比較的流暢な取引種に適しています.最も一般的な突破型取引方法は,価格とサポートと抵抗の相対位置関係を利用して,特定の取引の買賣点を判断することです.このセクションの唐津通道戦略も,この原則に基づいています.

ドンチアン通りの戦略規則

ドンチアン通路は,傾向型指標であり,その表情と信号はブリンズ帯の指標と少し似ています.しかし,ドンチアン通路の価格は,一期間の最高価格と最低価格に基づいて構築されています.例えば,最近50のKラインの最高価格の最大値を計算すると,上向きになります.最近50のKラインの最低価格の最小値を計算すると,下向きになります.

img

上記の図のように,この指標は3つの異なる色の曲線で構成され,20サイクル間の最高価格と最低価格が市場価格の変動を示すためにデフォルトで設定されています. 狭い通路は市場変動が少ないことを示し,反対の通路の幅は市場変動が大きいことを示します.

価格が上線を突破すると買い信号であり,反逆的に下線を突破すると売る信号である. 上線と下線は最高値と最低値で計算されるため,通常,価格が上線と下線を突破して上昇することは稀である.ほとんどの場合,価格は上線または下線の一方的な動き,または上線と下線の間の動きに沿っている.

戦略的論理

ドンチアン通路の使い方はいくつかあり,単独でも使用し,他の指標と組み合わせても使用できます. 本課程では,最も簡単な使い方を採用します.すなわち,価格が下から上へと走行を突破し,上向きのプレッシャーラインを突破すると,多方勢力が強くなると考え,上向きの波動が形成され,買い出しの信号が発生します.価格が上から下向きに走行を突破し,支柱線を突破すると,上向きの力が強くなると考え,下向きの波動が形成され,売り出しの信号が発生します.

img

買い開け後,価格が再び唐通道の中央線に落ちると,多方力が弱くなっている,または空の力が強くなっていると考えて,平衡信号を生成する.

売買条件

  • 複数の取引を開設:持分がない場合,取引先の価格が上線値よりも大きい場合
  • 空き取引を開設:持分がない場合,閉店価格は下線以下である
  • 多頭平衡:多頭を保持し,中間線より低い価格で閉じる場合
  • 空の平行:空の注文を保持し,中途半端価格よりも高値で閉じる場合

戦略コードの実装

発明者による定量化プラットフォームの研究環境では,この戦略を徐々に理解しています.

発明者定量化プラットフォームの研究環境は,以下の図を参照してください.

img

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) # 卖开


関連性

もっと