Skip to content

Latest commit

 

History

History
340 lines (262 loc) · 18.7 KB

MACD双向优化交易策略MACD-Double-Optimization-Trading-Strategy.md

File metadata and controls

340 lines (262 loc) · 18.7 KB

Name

MACD双向优化交易策略MACD-Double-Optimization-Trading-Strategy

Author

ChaoZhang

Strategy Description

IMG [trans]

二、策略概述

该策略运用MACD指标以及均线的交叉原理构建交易信号。其优势在于可以分别为做多和做空方向优化MACD的参数,从而使参数针对不同行情方向进行最优配置。

三、策略原理

  1. 分别计算做多和做空两个方向的MACD指标。做多采用一组参数,做空采用另一组参数,可以自由配置。
  2. 判断MACD线和Signal线的交叉产生交易信号。做多时看涨交叉,做空时看跌交叉。
  3. 可以配置Signal线是否也需要交叉才触发信号,从而避免假信号。
  4. 进入做多或做空仓位后,等待反向交叉时平仓。

四、策略优势

  1. 双向参数优化:可以自由优化做多和做空的参数,使其分别针对行情方向进行最优配置。
  2. 可配置信号平滑:Signal参数可以控制信号线的平滑程度,过滤假信号。
  3. 可配置信号过滤:可配置是否需要Signal线交叉才触发,避免假信号误导。
  4. 可细调仓位控制:可单独开启做多或做空,也可同时做多做空。

五、策略风险

  1. MACD滞后问题:MACD本身有一定滞后,可能错过快速反转。
  2. 多空切换风险:行情快速变化时,仓位切换可能过于频繁。
  3. 参数风险:不当的参数配置可能无法捕捉行情特征。
  4. 止损保护:应设置合理的止损来控制单笔损失。

管理风险的方法:

  1. 结合其他指标判断大格局,避免追高杀跌。
  2. 设置信号延迟和平滑参数来减少错误信号。
  3. 反复测试优化参数,使其匹配不同周期的行情节奏。
  4. 设定止损止盈机制,控制单笔损失。

六、优化方向

可以从以下几个方面来优化这个策略:

  1. 测试不同的快线和慢线长度参数组合,找出对不同周期行情最佳的参数。

  2. 测试不同的Signal线参数,Smoother信号线可以过滤掉更多噪音。

  3. 测试打开和关闭Signal线交叉过滤的差别,寻找最佳平衡。

  4. 根据回测情况设定最优止损止盈比例。

  5. 尝试只做多或只做空,看是否可以将策略效果最大化。

七、总结

该MACD双向优化交易策略通过分别配置做多和做空参数,实现了针对不同行情方向的最优化,可以自由调整参与的方向。同时加入了信号过滤机制来避免错误信号。通过参数优化和风险管理手段,可以进一步提高策略效果

||

II. Strategy Overview

This strategy uses the MACD indicator and moving average cross principles to construct trading signals. Its advantage is that it can optimize the parameters of MACD separately for long and short directions, so that the parameters can be optimally configured for different market directions.

III. Strategy Principle

  1. Calculate the MACD indicator separately for long and short directions. One set of parameters is used for long, and another set of parameters is used for short, which can be freely configured.

  2. Judge the trading signals generated by the crossover of the MACD line and the Signal line. Look for bullish crossover for long, and bearish crossover for short.

  3. You can configure whether the Signal line also needs to cross to trigger the signal, so as to avoid false signals.

  4. After entering long or short position, close the position when a reverse crossover occurs.

IV. Advantages of the Strategy

  1. Two-way parameter optimization: parameters for long and short can be freely optimized to be optimally configured for market directions separately.

  2. Configurable signal smoothing: The Signal parameter can control the smoothness of the signal line to filter out false signals.

  3. Configurable signal filtering: Can be configured whether the Signal line crossover is required to trigger to avoid false signals.

  4. Fine-tuned position control: Long or short alone can be enabled separately, or long and short can be done at the same time.

V. Risks of the Strategy

  1. MACD lag: MACD itself has some lag which may miss fast reversals.

  2. Risk of switching between long and short: Frequent position switching may occur when the market changes rapidly.

  3. Parameter risk: Improper parameter configurations may fail to capture market characteristics.

  4. Lack of stop loss protection: Reasonable stop loss should be set to control single loss.

Methods to manage risks:

  1. Combine with other indicators to judge the big picture and avoid chasing highs and selling lows.

  2. Set signal delay and smoothing parameters to reduce error signals.

  3. Repeatedly test and optimize parameters to match the rhythm of the market in different cycles.

  4. Set up stop loss and take profit mechanism to control single loss.

VI. Directions for Optimization

Some ways this strategy can be further optimized:

  1. Test different combinations of fast line and slow line length parameters to find the optimal parameters for market conditions in different cycles.

  2. Test different Signal line parameters. Smoother signal lines can filter out more noise.

  3. Test the difference between turning on and off the Signal line crossover filter to find the optimal balance.

  4. Set the optimal stop loss and take profit ratio based on backtest results.

  5. Try only long or only short to see if the strategy effect can be maximized.

VII. Summary

By configuring long and short parameters separately, this MACD Double Optimization Trading Strategy realizes optimization tailored to different market directions, and allows free adjustment of the participation direction. At the same time, signal filtering mechanisms are introduced to avoid erroneous signals. Through parameter optimization and risk management measures, the strategy effect can be further improved.

[/trans]

Strategy Arguments

Argument Default Description
v_input_bool_1 true (?inputs long)Allow Long
v_input_int_1 13 Fast Length Long
v_input_int_2 19 Slow Length Long
v_input_source_1_close 0 Source Long: close
v_input_int_3 9 Signal Smoothing Long
v_input_string_1 0 Oscillator MA Type Long: EMA
v_input_string_2 0 Signal Line MA Type Long: EMA
v_input_int_4 false Cross Point Long
v_input_int_5 false MacD Cross Delay Long
v_input_bool_2 false Signal Must Also Cross Long
v_input_int_6 false Signal Cross Delay Long
v_input_bool_3 true (?inputs short)Allow Short
v_input_int_7 11 Fast Length Short
v_input_int_8 20 Slow Length Short
v_input_source_2_close 0 Source Short: close
v_input_int_9 9 Signal Smoothing Short
v_input_string_3 0 Oscillator MA Type Short: EMA
v_input_string_4 0 Signal Line MA Type Short: EMA
v_input_int_10 false Cross Point Short
v_input_int_11 true MacD Cross Delay Short
v_input_bool_4 false Signal Must Also Cross Short
v_input_int_12 false Signal Cross Delay Short
v_input_bool_5 false (?Stop/Profit Long)Use Stop Loss Long
v_input_float_1 true Stop Loss % Long
v_input_bool_6 false Use Take Profit Long
v_input_float_2 true Take Profit % Long
v_input_bool_7 true (?Stop/Profit Short)Use Stop Loss Short
v_input_float_3 21 Stop Loss % Short
v_input_bool_8 true Use Take Profit Short
v_input_float_4 20 Take Profit % Short
v_input_color_1 #2962FF (?Color Settings)MACD Line Long
v_input_color_2 #FF6D00 Signal Line Long
v_input_color_7 #B03DFF MACD Line Short
v_input_color_8 #00FFE8 Signal Line Short
v_input_color_3 #26A69A (?Histogram Color Settings)Grow Above Long
v_input_color_4 #B2DFDB Fall Above Long
v_input_color_5 #FFCDD2 Grow Below Long
v_input_color_6 #FF5252 Fall Below Long
v_input_color_9 #D95965 Grow Above Short
v_input_color_10 #4D2024 Fall Above Short
v_input_color_11 #00322D Grow Below Short
v_input_color_12 #00ADAD Fall Below Short

Source (PineScript)

/*backtest
start: 2023-01-15 00:00:00
end: 2024-01-21 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Gentleman-Goat & TradingTools.Software/Optimizer
strategy(title="MACD Short/Long Strategy for TradingView Input Optimizer", shorttitle="MACD Short/Long TVIO", initial_capital=1000, default_qty_value=100, default_qty_type=strategy.percent_of_equity)

// Get Inputs Long
allow_long                  = input.bool(title="Allow Long", defval=true, group="inputs long")
fast_length_long            = input.int(title="Fast Length Long", defval=13, group="inputs long")
slow_length_long            = input.int(title="Slow Length Long", defval=19, group="inputs long")
src_long                    = input.source(title="Source Long", defval=close, group="inputs long")
signal_length_long          = input.int(title="Signal Smoothing Long", minval = 1, maxval = 50, defval = 9, group="inputs long")
sma_source_long             = input.string(title="Oscillator MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long")
sma_signal_long             = input.string(title="Signal Line MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long")
cross_point_long            = input.int(title="Cross Point Long", defval=0, group="inputs long")
cross_delay_macd_long       = input.int(title="MacD Cross Delay Long", defval=0, group="inputs long")
signal_must_cross_long      = input.bool(title="Signal Must Also Cross Long", defval=false, group="inputs long")
cross_delay_signal_long     = input.int(title="Signal Cross Delay Long", defval=0, group="inputs long")

//Get Inputs Short
allow_short                 = input.bool(title="Allow Short", defval=true, group="inputs short")
fast_length_short           = input.int(title="Fast Length Short", defval=11, group="inputs short")
slow_length_short           = input.int(title="Slow Length Short", defval=20, group="inputs short")
src_short                   = input.source(title="Source Short", defval=close, group="inputs short")
signal_length_short         = input.int(title="Signal Smoothing Short", minval = 1, maxval = 50, defval = 9, group="inputs short")
sma_source_short            = input.string(title="Oscillator MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short")
sma_signal_short            = input.string(title="Signal Line MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short")
cross_point_short           = input.int(title="Cross Point Short", defval=0, group="inputs short")
cross_delay_macd_short      = input.int(title="MacD Cross Delay Short", defval=1, group="inputs short")
signal_must_cross_short     = input.bool(title="Signal Must Also Cross Short", defval=false, group="inputs short")
cross_delay_signal_short    = input.int(title="Signal Cross Delay Short", defval=0, group="inputs short")

use_stop_loss_long          = input.bool(defval=false,title="Use Stop Loss Long", group="Stop/Profit Long")
stop_loss_long_percentage   = input.float(defval=1,title="Stop Loss % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01
use_take_profit_long        = input.bool(defval=false,title="Use Take Profit Long", group="Stop/Profit Long")
take_profit_long_percentage = input.float(defval=1,title="Take Profit % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01
use_stop_loss_short         = input.bool(defval=true,title="Use Stop Loss Short", group="Stop/Profit Short")
stop_loss_short_percentage  = input.float(defval=21,title="Stop Loss % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01
use_take_profit_short       = input.bool(defval=true,title="Use Take Profit Short", group="Stop/Profit Short")
take_profit_short_percentage= input.float(defval=20,title="Take Profit % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01
//------------------------------------------------------------------------------

// Plot colors Long
col_macd_long        = input.color(#2962FF, "MACD Line Long", group="Color Settings", inline="MACD")
col_signal_long      = input.color(#FF6D00, "Signal Line Long", group="Color Settings", inline="Signal")
col_grow_above_long  = input.color(#26A69A, "Grow Above Long", group="Histogram Color Settings", inline="Above Long")
col_fall_above_long  = input.color(#B2DFDB, "Fall Above Long", group="Histogram Color Settings", inline="Above Long")
col_grow_below_long  = input.color(#FFCDD2, "Grow Below Long", group="Histogram Color Settings", inline="Below Long")
col_fall_below_long  = input.color(#FF5252, "Fall Below Long", group="Histogram Color Settings", inline="Below Long")

// Plot colors Short
col_macd_short        = input.color(#B03DFF, "MACD Line Short", group="Color Settings", inline="MACD")
col_signal_short      = input.color(#00FFE8, "Signal Line Short", group="Color Settings", inline="Signal")
col_grow_above_short  = input.color(#D95965, "Grow Above Short", group="Histogram Color Settings", inline="Above Short")
col_fall_above_short  = input.color(#4D2024, "Fall Above Short", group="Histogram Color Settings", inline="Above Short")
col_grow_below_short  = input.color(#00322D, "Grow Below Short", group="Histogram Color Settings", inline="Below Short")
col_fall_below_short  = input.color(#00ADAD, "Fall Below Short", group="Histogram Color Settings", inline="Below Short")

// Calculate Long
fast_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, fast_length_long) : ta.ema(src_long, fast_length_long)
slow_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, slow_length_long) : ta.ema(src_long, slow_length_long)
macd_long    = fast_ma_long - slow_ma_long
signal_long  = sma_signal_long == "SMA" ? ta.sma(macd_long, signal_length_long) : ta.ema(macd_long, signal_length_long)
hist_long    = macd_long - signal_long

// Calculate Short
fast_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, fast_length_short) : ta.ema(src_short, fast_length_short)
slow_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, slow_length_short) : ta.ema(src_short, slow_length_short)
macd_short    = fast_ma_short - slow_ma_short
signal_short  = sma_signal_short == "SMA" ? ta.sma(macd_short, signal_length_short) : ta.ema(macd_short, signal_length_short)
hist_short    = macd_short - signal_short

//Plot Long
plot(hist_long, title="Histogram Long", style=plot.style_columns, color=(hist_long>=0 ? (hist_long[1] < hist_long ? col_grow_above_long : col_fall_above_long) : (hist_long[1] < hist_long ? col_grow_below_long : col_fall_below_long)))
plot(macd_long, title="MACD Long", color=col_macd_long)
plot(signal_long, title="Signal Long", color=col_signal_long)

//Plot Short
plot(hist_short, title="Histogram Short", style=plot.style_columns, color=(hist_short>=0 ? (hist_short[1] < hist_short ? col_grow_above_short : col_fall_above_short) : (hist_short[1] < hist_short ? col_grow_below_short : col_fall_below_short)))
plot(macd_short, title="MACD Short", color=col_macd_short)
plot(signal_short, title="Signal Short", color=col_signal_short)

var detectedLongCrossOver = false
var detectedShortCrossUnder = false

if(ta.crossunder(macd_short,cross_point_short))
    detectedShortCrossUnder := true
if(ta.crossover(macd_short,cross_point_short))
    detectedShortCrossUnder := false
                
if(ta.crossover(macd_long,cross_point_long))
    detectedLongCrossOver := true
if(ta.crossunder(macd_long,cross_point_long))
    detectedLongCrossOver := false

crossover_signal_long = ta.crossover(signal_long,cross_point_long)
crossunder_signal_long = ta.crossunder(signal_long,cross_point_long)

crossunder_signal_short = ta.crossunder(signal_short,cross_point_short)
crossover_signal_short = ta.crossover(signal_short,cross_point_short)

crossover_macd_long = ta.crossover(macd_long,cross_point_long)
crossunder_macd_long = ta.crossunder(macd_long,cross_point_long)

crossunder_macd_short = ta.crossunder(macd_short,cross_point_short)
crossover_macd_short = ta.crossover(macd_short,cross_point_short)

inEntry = false
//Strategy Entries
if (strategy.equity > 0) //This is required for the input optimizer to work since it will fail if the strategy fails to succeed by not having enough equity.
    
    if (strategy.position_size <= 0 and allow_long==true and inEntry==false)
        if(signal_must_cross_long==true)
            longSignalCondition = detectedLongCrossOver==true and crossover_signal_long[cross_delay_signal_long]
            strategy.entry(id="long", direction=strategy.long, when=longSignalCondition)
            if(longSignalCondition)
                inEntry:=true
        else
            longMacDCondition = crossover_macd_long[cross_delay_macd_long]
            strategy.entry(id="long", direction=strategy.long, when=longMacDCondition)
            if(longMacDCondition)
                inEntry:=true
    if (strategy.position_size >= 0 and allow_short==true and inEntry==false)
        if(signal_must_cross_short==true)
            shortSignalCondition = detectedShortCrossUnder and crossunder_signal_short[cross_delay_signal_short]
            strategy.entry(id="short", direction=strategy.short, when=shortSignalCondition)
            if(shortSignalCondition)
                inEntry:=true
        else
            shortMacDCondition = crossunder_macd_short[cross_delay_macd_short]
            strategy.entry(id="short", direction=strategy.short, when=shortMacDCondition)
            if(shortMacDCondition)
                inEntry:=true
    if(strategy.position_size > 0 and allow_long==true and allow_short==false)
        if(signal_must_cross_long==true)
            strategy.close(id="long", when=detectedLongCrossOver==false and crossunder_signal_long)
        else
            strategy.close(id="long", when=crossunder_macd_long)
    if(strategy.position_size < 0 and allow_short==true and allow_long==false)
        if(signal_must_cross_short==true)
            strategy.close(id="short", when=detectedShortCrossUnder==false and crossover_signal_short)
        else
            strategy.close(id="short", when=crossover_macd_short)

stop_loss_value_long    = strategy.position_avg_price*(1 - stop_loss_long_percentage)
take_profit_value_long  = strategy.position_avg_price*(1 + take_profit_long_percentage)
stop_loss_value_short   = strategy.position_avg_price*(1 + stop_loss_short_percentage)
take_profit_value_short = strategy.position_avg_price*(1 - take_profit_short_percentage)

if(strategy.position_size>0) //Long positions only
    strategy.exit(id="TP/SL Long",from_entry="long", limit=use_take_profit_long ? take_profit_value_long : na, stop=use_stop_loss_long ? stop_loss_value_long : na)
if(strategy.position_size<0) //Short positions only
    strategy.exit(id="TP/SL Short",from_entry="short", limit=use_take_profit_short ? take_profit_value_short : na, stop=use_stop_loss_short ? stop_loss_value_short : na)

Detail

https://www.fmz.com/strategy/439613

Last Modified

2024-01-22 11:10:10