麦金非动态均线交易策略


创建日期: 2023-11-14 15:48:46 最后修改: 2023-11-14 15:48:46
复制: 0 点击次数: 656
avatar of ChaoZhang ChaoZhang
1
关注
1300
关注者

麦金非动态均线交易策略

概述

本策略是基于麦金非动态均线指标的交易策略。麦金非动态均线指标是一种改进版的移动平均线指标,可以更好地捕捉市场趋势的变化。该策略利用麦金非动态均线指标的信号,结合价格突破均线的信号,制定买入和卖出规则,以达到获利的目的。

策略原理

该策略主要使用两个均线,分别是21日指数移动均线和42日指数移动均线。当短期均线上穿长期均线时,视为买入信号;当短期均线下穿长期均线时,视为卖出信号。

此外,该策略还同时需要满足价格高于麦金非动态均线、价格突破短期均线的条件,才会产生买入信号。对于卖出信号也同样需要满足价格低于麦金非均线、价格跌破短期均线的条件。

具体来说,买入信号的触发条件是:短均线上穿长均线、收盘价高于麦金非均线、收盘价突破向下短均线。卖出信号的触发条件是:短均线下穿长均线、收盘价低于麦金非均线、收盘价突破向上短均线。

麦金非动态均线的计算公式为:MDIt = MDIt-1 + (Close - MDIt-1) / Max(k * Period * (Close / MDIt-1)^4, 1)。其中,MDIt表示当前值,MDIt-1表示前一日的值,Close表示当日收盘价,k表示平滑常数,Period表示计算周期。该公式使得均线能够实时跟踪价格变化。

策略优势

  1. 麦金非均线指标改进了传统均线的滞后性,可以更快捕捉价格趋势的变化。

  2. 结合双均线形成交易信号,可以有效过滤假突破。

  3. 添加价格高于/低于麦金非均线的条件,避免在震荡区间频繁交易。

  4. 采用指数移动均线,使得均线对最近价格变化更敏感。

策略风险

  1. 在横盘震荡市场中,可能产生虚假信号,从而亏损。可以适当调整参数,过滤信号。

  2. 大幅度跳空的突破可能导致无法及时建仓,应适当放宽入场条件。

  3. 参数设置不当也会影响策略效果,应对参数进行优化测试。

  4. 长期持有带来的系统性风险需要注意,可以设置止损点。

策略优化

  1. 可以测试不同长度的均线参数,找到更合适的组合。

  2. 可以添加其他技术指标,如KD,MACD等,优化买卖点选择。

  3. 可以根据不同品种、市场调整参数k的数值,优化麦金非均线的计算。

  4. 可以结合波动率指标实现 dynamical position sizing,控制单笔风险。

  5. 可以设置止损点以控制亏损风险,也可以试验移动止损来锁定利润。

总结

本策略利用麦金非均线指标的快速跟踪能力,配合价格突破均线形成的交易信号,可以有效跟踪趋势,在趋势发生转折时及时切换仓位。相比传统双均线策略,本策略可以更快速地捕捉价格趋势变化。但该策略也存在一定的风险,需要进行优化测试以determinate合适的参数组合,控制风险。

策略源码
/*backtest
start: 2022-11-07 00:00:00
end: 2023-11-13 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LucasZancheta

//@version=4
strategy(shorttitle="Maguila", title="McGinley Dynamic Indicator", overlay=true)

//Médias móveis
MA1Period=input(21, title="MA1")
MA2Period=input(42, title="MA2")

MA1 = ema(close, MA1Period)
MA2 = ema(close, MA2Period)

aboveAverage = MA1 >= MA2
hunderAverage = MA2 >= MA1

//Período do backtest
startDate = input(title="Start Date", type=input.integer, defval=28, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer, defval=5, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer, defval=2019, minval=1800, maxval=2100)

endDate = input(title="End Date", type=input.integer, defval=28, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer, defval=5, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer, defval=2030, minval=1800, maxval=2100)

//Verifica se o candle está dentro do período do backtest
inDateRange = (time >= timestamp(syminfo.timezone, startYear, startMonth, startDate, 0, 0)) and (time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))

//Número de periodos da média móvel
period  = input(title="Períodos", type=input.integer, defval=20)
//Constante K (0.6)
k = input(title="Constante K", type=input.float, defval=0.6)
//Preço de fechamento 
closePrice = input(title="Preço", type=input.source, defval=close)

mdi = 0.0

//Fórmula de McGinley
mdi := na(mdi[1]) ? closePrice : mdi[1] + (closePrice - mdi[1]) / max((k * period * pow(closePrice / mdi[1], 4)), 1)

//Regra de coloração 
mdiColor = closePrice > mdi ? color.green : closePrice < mdi ? color.red : color.black

//Inserindo as informações no gráfico    
plot(MA1, color=color.blue, linewidth=2)
plot(MA2, color=color.purple, linewidth=2)

barcolor(mdiColor)

//Estratégia
buySignal = aboveAverage and closePrice > mdi and crossunder(low, MA1) and close > MA1  
buyLoss = closePrice < mdi and close < MA1 and close < MA2

if (inDateRange)
    strategy.entry("Compra", strategy.long, qty=1, when= buySignal)
    strategy.exit("Gain da compra", "Compra", qty=1, profit=20)
    strategy.close("Compra", qty=1, when= buyLoss, comment="Loss na operação")

sellSignal = hunderAverage and closePrice < mdi and crossover(high, MA1) and close < MA1
sellLoss = closePrice > mdi and close > MA1 and close > MA2

if (inDateRange)
    strategy.entry("Venda", strategy.short, qty=1, when= sellSignal)
    strategy.exit("Gain da venda", "Venda", qty=1, profit=20)
    strategy.close("Venda", qty=1, when= sellLoss, comment="Loss na operação")

if (not inDateRange)
    strategy.close_all()