Loading ...

使用DMI辅助MACD策略

Author: Hukybo, Date: 2019-11-14 17:09:14
Tags:

摘要

“趋势是你的朋友”这是每一个交易者都耳熟能详的箴言。但做过交易的朋友可能会有体会,趋势总是在毫无预警地开始并突然结束。那么在CTA策略中,如何抓住趋势并过滤震荡行情,是许多主观和量化交易者孜孜不倦的追求。在本节课程中,我们将以平均趋向指数(ADX)为滤网,分析在它量化交易中的应用。

点击阅读更多内容


# 回测配置
'''backtest
start: 2015-02-22 00:00:00
end: 2019-10-17 00:00:00
period: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

# 导入库
import talib
import numpy as np


mp = 0  # 定义一个全局变量,用于控制虚拟持仓


# 把K线数组转换成最高价、最低价、收盘价数组,用于转换为numpy.array类型数据
def get_data(bars):
    arr = [[], [], []]
    for i in bars:
        arr[0].append(i['High'])
        arr[1].append(i['Low'])
        arr[2].append(i['Close'])
    return arr


# 判断两根两个数组是否金叉
def is_up_cross(arr1, arr2):
    if arr1[len(arr1) - 2] < arr2[len(arr2) - 2] and arr1[len(arr1) - 1] > arr2[len(arr2) - 1]:
        return True

# 判断两根两个数组是否死叉
def is_down_cross(arr1, arr2):
    if arr1[len(arr1) - 2] > arr2[len(arr2) - 2] and arr1[len(arr1) - 1] < arr2[len(arr2) - 1]:
        return True    

    
# 程序主函数
def onTick():
    exchange.SetContractType("rb000")  # 订阅期货品种
    bar_arr = exchange.GetRecords()  # 获取K线数组
    if len(bar_arr) < long + m + 1:  # 如果K线数组长度太小,就不能计算MACD,所以直接返回跳过
        return
    all_macd = TA.MACD(bar_arr, short, long, m)  # 计算MACD值,返回的是一个二维数组
    dif = all_macd[0]  # 获取DIF的值,返回一个数组
    dif.pop()  # 删除DIF数组最后一个元素
    dea = all_macd[1]  # 获取DEA的值,返回一个数组
    dea.pop()  # 删除DEA数组最后一个元素
    
    np_arr = np.array(get_data(bar_arr)) # 把列表转换为numpy.array类型数据,用于计算ADX的值
    adx_arr = talib.ADX(np_arr[0], np_arr[1], np_arr[2], 14);  # 计算ADX的值
    adx1 = adx_arr[len(adx_arr) - 2]  # 倒数第二根K线的ADX值
    adx2 = adx_arr[len(adx_arr) - 3]  # 倒数第三根K线的ADX值
    
    last_close = bar_arr[len(bar_arr) - 1]['Close']  # 获取最新价格(卖价),用于开平仓
    global mp  # 全局变量,用于控制虚拟持仓
    
    # 开多单
    if mp == 0 and dif[len(dif) - 1] > 0 and adx1 > 45:
        exchange.SetDirection("buy")  # 设置交易方向和类型
        exchange.Buy(last_close, 1)  # 开多单
        mp = 1  # 设置虚拟持仓的值,即有多单
    
    # 开空单
    if mp == 0 and dif[len(dif) - 1] < 0 and adx1 > 45:
        exchange.SetDirection("sell")  # 设置交易方向和类型
        exchange.Sell(last_close - 1, 1)  # 开空单
        mp = -1  # 设置虚拟持仓的值,即有空单
        
    # 平多单
    if mp == 1 and (is_down_cross(dif, dea) or adx1 < adx2):
        exchange.SetDirection("closebuy")  # 设置交易方向和类型
        exchange.Sell(last_close - 1, 1)  # 平多单
        mp = 0  # 设置虚拟持仓的值,即空仓
    
    # 平空单
    if mp == -1 and (is_up_cross(dif, dea) or adx1 < adx2):
        exchange.SetDirection("closesell")  # 设置交易方向和类型
        exchange.Buy(last_close, 1)  # 平空单
        mp = 0  # 设置虚拟持仓的值,即空仓

        
def main():
    while True:
        onTick()
        Sleep(1000)


More