양적 거래 정확한 롱 앤 숏 전략


생성 날짜: 2023-12-07 16:19:11 마지막으로 수정됨: 2023-12-07 16:19:11
복사: 0 클릭수: 938
avatar of ChaoZhang ChaoZhang
1
집중하다
1619
수행원

양적 거래 정확한 롱 앤 숏 전략

개요

이 글은 주로 부린 채널, ADX 지표와 결합한 K 선을 기반으로 다공평 판단을 하는 양적 거래 전략에 대해 소개한다. 이 전략은 부린 채널을 사용하여 시장 추세와 변동성을 판단하고, ADX 지표와 결합하여 시장 추세가 강하다는 것을 판단하고, 강한 추세 시장 방향에서 더 많은 공백을 하고, 변동적인 상황에서는 전체적인 시선을 바라보고, 최대한 위험을 회피한다.

전략 원칙

    1. 부린 통로의 상하 궤도를 기준으로 시장 추세 방향을 판단한다. 가격은 상하 궤도의 위쪽에 다면 행렬로, 하하 궤도의 아래쪽에 공수 행렬로 있다.
    1. 부린 통로의 대역폭은 시장의 변동성과 위험을 반영한다. 부린 대역폭이 넓으면 시장이 흔들릴수록 위험도가 커서 입장을 피해야 한다.
    1. ADX 지표는 시장 추세가 강하거나 약하다는 것을 판단한다. ADX 값이 25보다 크면 트렌드 상황을 나타냅니다. 이 때 부린 통로 방향이 포지션을 선택하는 방향을 판단한다. ADX 값이 25보다 작으면 흔들림 상황을 나타냅니다. 이 때 거래를 피해야합니다.
    1. 더 많은 상장 방향을 결정한 후, ATR 지표에 따라 중지 손실을 설정합니다. ATR은 시장의 변동성을 측정하는 데 사용되며, ATR 배수에 따라 중지 손실 거리를 설정합니다.
    1. 스톱은 브린 상하철에 따라 설정한다. 다중머리 스톱은 하하철, 빈머리 스톱은 상하철이다. 또는 ATR 지표의 ATR 배수에 따라 고정 스톱 거리를 설정한다.
    1. 스톱로스 위치와 스톱로스 위치 사이에 손익과 손실을 관리하고, 수익을 잠금하기 위해 이동 스톱을 설정한다.

전략적 이점

  1. 부린 통로와 ADX 지표 판단 방향과 결합하여, 과잉 공백을 명확하게 판단하고 선택적으로 입장을 수립하여, 변동적인 상황에서 무의미한 거래를 피한다.

  2. 부린 대역폭을 사용하여 변동률 위험을 판단합니다. 부린 대역폭이 좁아지면 기회가 높지만 위험도 적습니다. 부린 대역폭이 넓어지면 거래를 피하십시오.

  3. ATR 제약 설정은 위험을 통제할 수 있도록 하고, 제약이 쫓겨나지는 것을 최대한 방지한다.

  4. 부린 통로 설정에 따라 정지 포지션, 정지 포지션 추격 고 정지 포지션 추격 하위 위험이 없습니다.

  5. 모바일 스톱은 수익을 확보하고 트렌드를 계속 추적하는 데 도움이 됩니다.

전략적 위험

  1. 부린 통로와 ADX 지표는 모두 압력이 있을 가능성이 있다. 만약 이탈이 발생하면 잘못된 판단이 발생할 수 있다.

  2. ATR 지표는 단지 역사적 변동만을 반영하고 미래의 변동을 예측할 수 없습니다. 실제 정지 손실이 따라 잡힐 위험이 여전히 존재합니다.

  3. 부린 통로 지역 구분은 주관적이며, 기회를 놓칠 수 있는 상황이 발생할 수 있다.

  4. 이동 상쇄는 디스크에서만 가능하며, 간격 기간 동안 이동할 수 없는 위험이 있다.

  5. 재검토 데이터 적합성 위험. 실제 시장에서 테스트 보고서를 복제하기 어렵다.

전략 최적화

  1. 부린 채널과 ADX 지표의 잘못된 신호를 방지하기 위해 더 많은 지표를 통합하여 상호 신뢰하십시오.

  2. ATR 중지에는 점프 중지도 추가할 수 있다. 또는 딥러닝 알고리즘을 사용하여 시장 변동 설정을 중지할 수 있다.

  3. 부린 통로의 통로 매개 변수를 최적화하여 더 큰 시장 기회를 포용할 수 있도록 합니다.

  4. 더 효율적인 프로그램 거래 시스템을 사용하여 무인 무인 이동 중지.

  5. 더 긴 시간 주기 및 더 많은 품종 조합으로 재검토하여 전략의 안정성을 보장하십시오.

요약하다

이 전략은 부린 채널, ADX 지표와 같은 여러 지표 신호를 통합하고, 명확한 트렌드 방향을 판단한 후 선택적 입장을 취하고, ATR 지표를 사용하여 손실 중지 설정을 최적화하고, 위험과 수익률을 최대한 제어하는 것이 권장되는 양적 거래 전략입니다. 우리는 이 전략에 대해 많은 최적화 할 수있는 공간이 있으며, 향후 버전의 출력을 기대합니다.

전략 소스 코드
/*backtest
start: 2022-11-30 00:00:00
end: 2023-12-06 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// © Fibonacci Zone DCA Strategy - R3c0nTrader ver 2022-06-12
// For backtesting with 3Commas DCA Bot settings
// Thank you "eykpunter" for granting me permission to use "Fibonacci Zones" to create this strategy
// Thank you "junyou0424" for granting me permission to use "DCA Bot with SuperTrend Emulator" which I used for adding bot inputs, calculations, and strategy
//@version=5
strategy('Fibonacci Zone DCA Strategy - R3c0nTrader', shorttitle='Fibonacci Zone DCA Strategy', overlay=true )

// Strategy Inputs
// Start and End Dates
i_startTime = input(defval=timestamp('01 Jan 2015 00:00 +0000'), title='Start Time', group="Date Range")
i_endTime = input(defval=timestamp('31 Dec 2050 23:59 +0000'), title='End Time', group="Date Range")
inDateRange = true

// Fibonacci Settings
sourceInput = input.source(close, "Source", group="Trade Entry Settings")
per = input(14, title='Fibonacci length', tooltip='Number of bars to look back. Recommended for beginners to set ADX Smoothing and DI Length to the same value as this.', group="Trade Entry Settings")
hl = ta.highest(high, per)  //High Line (Border)
ll = ta.lowest(low, per)  //Low Line  (Border)
dist = hl - ll  //range of the channel    
hf = hl - dist * 0.236  //Highest Fibonacci line
cfh = hl - dist * 0.382  //Center High Fibonacci line
cfl = hl - dist * 0.618  //Center Low Fibonacci line
lf = hl - dist * 0.764  //Lowest Fibonacci line

// ADX Settings
lensig = input.int(14, title="ADX Smoothing", tooltip='Fibonacci signals work best when market is trending. ADX is used to measure trend strength. Default value is 14. Recommend for beginners to match this with Fibonacci length and DI Length',minval=1, maxval=50, group="Trade Entry Settings")
len = input.int(14, minval=1, title="DI Length", tooltip='Fibonacci signals work best when market is trending. DI Length is used to calculate ADX to measure trend strength. Default value is 14. Recommend for beginners to match this with Fibonacci length and ADX Smoothing.', group="Trade Entry Settings")
adx_min = input.int(25, title='Min ADX value to open trade', tooltip='Use this to set the minium ADX value (trend strength) to open trade. 25 or higher is recommended for beginners. 0 to 20 is a weak trend. 25 to 35 is a strong trend. 35 to 45 is a very strong trend. 45 to 100 is an extremely strong trend.', group="Trade Entry Settings")
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = ta.rma(ta.tr, len)
di_plus = fixnan(100 * ta.rma(plusDM, len) / trur)
di_minus = fixnan(100 * ta.rma(minusDM, len) / trur)
sum = di_plus + di_minus
adx = 100 * ta.rma(math.abs(di_plus - di_minus) / (sum == 0 ? 1 : sum), lensig)
fib_choice = input.string("2-Higher than the top of the Downtrend Fib zone", title="Open a trade when the price moves:", options=["1-To the bottom of Downtrend Fib zone", "2-Higher than the top of the Downtrend Fib zone", "3-Higher than the bottom of Ranging Fib Zone", "4-Higher than the top of Ranging Fib Zone", "5-Higher than the bottom of Uptrend Fib Zone", "6-To the top of Uptrend Fib Zone"],
   tooltip='There are three fib zones. The options are listed from the bottom zone to the top zone. The bottom zone is the Downtrend zone; the middle zone is the Ranging zone; The top fib zone is the Uptrend zone;',
   group="Trade Entry Settings")
di_choice = input.bool(false, title="Only open trades on bullish +DI (Positive Directional Index)? (off for contrarian traders)", tooltip=
   'Default is disabled. If you want to be more selective (you want a bullish confirmation), enable this and it will only open trades when the +DI (Positive Directional Index) is higher than the -DI (Negative Directional Index). Contrarian traders (buy the dip) should leave this disabled', 
   group="Trade Entry Settings")
di_min = input.int(0, title='Min +DI value to open trade', 
   tooltip='Default is zero. Use this to set the minium +DI value to open the trade. Try incrementing this value if you want to be more selective and filter for more bullish moves (e.g. 20-25). For Contrarian traders, uncheck "Only open trades on bullish DI" option and set Min +DI to zero', 
   group="Trade Entry Settings")
di_max = input.int(100, title='Max +DI value to open trade', tooltip='Default is 100. Use this to set the maxium +DI value to open trade. For Contrarian traders, uncheck "Only open trades on bullish DI" option and try a Max +DI value no higher than 20 or 25', group="Trade Entry Settings")
di_inrange = di_plus >= di_min and di_plus <= di_max

// Truncate function
truncate(number, decimals) =>
    factor = math.pow(10, decimals)
    int(number * factor) / factor

//Declare take_profit
take_profit = float(0.22)

// Take Profit Drop-down menu option
tp_choice = input.string("Target Take Profit (%)", title="Take profit using:", options=["Target Take Profit (%)", "High Fibonacci Border-1", "High Fibonacci Border-2"], tooltip=
   'Select how to exit your trade and take profit. Then specify below this option the condition to exit. "High Fibonacci Border-1" is the top-most Fibonacci line in the green uptrend zone. "High Fibonacci Border-2" is the bottom Fibonacci line in the green uptrend zone. You can find these lines on the "Style" tab and toggle them off/on to locate these lines for more clarity', 
   group="Trade Exit Settings")
if tp_choice == "Target Take Profit (%)"
    take_profit := input.float(22.0, title='Target Take Profit (%)', step=0.5, minval=0.0, tooltip='Only used if "Target Take Profit (%)" is selected above.', group="Trade Exit Settings") / 100
    take_profit
else if tp_choice == "High Fibonacci Border-1"
    take_profit := float(hl)
    take_profit
else if tp_choice == "High Fibonacci Border-2"
    take_profit := float(hf)
    take_profit

trailing = input.float(0.0, title='Trailing deviation. Default= 0.0 (%)', step=0.5, minval=0.0, group="Trade Exit Settings") / 100
base_order = input(100.0, title='Base order', group="Trade Entry Settings")
safe_order = input(200.0, title='Safety order', group="Trade Entry Settings")
price_deviation = input.float(6.0, title='Price deviation to open safety orders (%)', step=0.25, minval=0.0, group="Trade Entry Settings") / 100
safe_order_volume_scale = input.float(2.0, step=0.5, title='Safety order volume scale', group="Trade Entry Settings")
safe_order_step_scale = input.float(1.4, step=0.1, title='Safety order step scale', group="Trade Entry Settings")
max_safe_order = input(5, title='Max safety orders', group="Trade Entry Settings")

var current_so = 0
var initial_order = 0.0
var previous_high_value = 0.0
var original_ttp_value = 0.0

// Calculate our key levels
take_profit_level = strategy.position_avg_price * (1 + take_profit)

if tp_choice == "Target Take Profit (%)"
    take_profit_level := strategy.position_avg_price * (1 + take_profit)
else
    take_profit_level := take_profit

fib_trigger = bool(false)
if fib_choice == "2-Higher than the top of the Downtrend Fib zone"
    fib_trigger := ta.crossover(sourceInput, lf)
else if fib_choice == "1-To the bottom of Downtrend Fib zone"
    fib_trigger := sourceInput <= ll
else if fib_choice == "3-Higher than the bottom of Ranging Fib Zone"
    fib_trigger := ta.crossover(sourceInput, cfl)
else if fib_choice == "4-Higher than the top of Ranging Fib Zone"
    fib_trigger := ta.crossover(sourceInput, cfh)
else if fib_choice == "5-Higher than the bottom of Uptrend Fib Zone"
    fib_trigger := ta.crossover(sourceInput, hf)
else if fib_choice == "6-To the top of Uptrend Fib Zone"
    fib_trigger := sourceInput >= hl


// If option enabled for enter trades only when DI is positive, then open trade based on user settings
if di_choice == true and strategy.position_size == 0 and sourceInput > 0 and inDateRange and fib_trigger and adx >= adx_min and di_plus > di_minus and di_inrange
    strategy.entry('Long @' + str.tostring(sourceInput)+'💎✋🤚', strategy.long, qty=base_order / sourceInput)
    initial_order := sourceInput
    current_so := 1
    previous_high_value := 0.0
    fib_trigger := false
    original_ttp_value := 0
    original_ttp_value
    
// Open First Position when candle source value crosses above the 'Low Fibonacci Border-1'
else if di_choice == false and strategy.position_size == 0 and sourceInput > 0 and inDateRange and fib_trigger and adx >= adx_min and di_inrange
    strategy.entry('Long @' + str.tostring(sourceInput)+'💎✋🤚', strategy.long, qty=base_order / sourceInput)
    initial_order := sourceInput
    current_so := 1
    previous_high_value := 0.0
    fib_trigger := false
    original_ttp_value := 0
    original_ttp_value
    
threshold = 0.0
    
if safe_order_step_scale == 1.0
    threshold := initial_order - initial_order * price_deviation * safe_order_step_scale * current_so
    threshold

else if current_so <= max_safe_order
    threshold := initial_order - initial_order * ((price_deviation * math.pow(safe_order_step_scale, current_so) - price_deviation) / (safe_order_step_scale - 1))
    threshold

else if current_so > max_safe_order
    threshold := initial_order - initial_order * ((price_deviation * math.pow(safe_order_step_scale, max_safe_order) - price_deviation) / (safe_order_step_scale - 1))
    threshold
    
// Average down when lowest candle value crosses below threshold
if current_so > 0 and low <= threshold and current_so <= max_safe_order and previous_high_value == 0.0
    // Trigger a safety order at the Safety Order "threshold" price
    strategy.entry('😨🙏 SO ' + str.tostring(current_so) + '@' + str.tostring(threshold), direction=strategy.long, qty=safe_order * math.pow(safe_order_volume_scale, current_so - 1) / threshold)
    current_so += 1
    current_so

// Take Profit!
// Take profit when take profit level is equal to or higher than the high of the candle
if take_profit_level <= high and strategy.position_size > 0 or previous_high_value > 0.0
    if trailing > 0.0
        if previous_high_value > 0.0
            if high >= previous_high_value
                previous_high_value := sourceInput
                previous_high_value
            else
                previous_high_percent = (previous_high_value - original_ttp_value) * 1.0 / original_ttp_value
                current_high_percent = (high - original_ttp_value) * 1.0 / original_ttp_value
                if previous_high_percent - current_high_percent >= trailing
                    strategy.close_all(comment='Close (trailing) @' + str.tostring(truncate(current_high_percent * 100, 3)) + '%')
                    current_so := 0
                    previous_high_value := 0
                    original_ttp_value := 0
                    original_ttp_value
        else
            previous_high_value := high
            original_ttp_value := high
            original_ttp_value
    else
        strategy.close_all(comment='💰 Close @' + str.tostring(high))
        current_so := 0
        previous_high_value := 0
        original_ttp_value := 0
        original_ttp_value

// Plot Fibonacci Areas
fill(plot(hl, title='High Fibonacci Border-1', color=color.new(#53ed0f, 50), linewidth=3), plot(hf, title='High Fibonacci Border-2', color=color.new(#38761d, 50), linewidth=3), color=color.new(#00FFFF, 80), title='Uptrend Fibonacci Zone @ 23.6%')  //uptrend zone
fill(plot(cfh, title='Center Low Fibonacci Border-1', color=color.new(#0589f4, 50), linewidth=3), plot(cfl, title='Center Low Fibonacci Border-2', color=color.new(#2018ff, 50), linewidth=3), color=color.new(color.blue, 80), title='Ranging Fibonacci Zone @ 61.8%')  // ranging zone
fill(plot(lf, title='Low Fibonacci Border-1', color=color.new(color.yellow, 50), linewidth=3), plot(ll, title='Low Fibonacci Border-2', color=color.new(color.red, 50), linewidth=3), color=color.new(color.orange, 80), title='Downtrend Fibonacci Zone @ 76.4%')  //down trend zone

// Plot TP
plot(strategy.position_size > 0 ? take_profit_level : na, style=plot.style_linebr, color=color.green, linewidth=2, title="Take Profit")

// Plot All Safety Order lines except for last one as bright blue
plot(strategy.position_size > 0 and current_so <= max_safe_order and current_so > 0 ? threshold : na, style=plot.style_linebr, color=color.new(#00ffff,0), linewidth=2, title="Safety Order")

// Plot Last Safety Order Line as Red
plot(strategy.position_size > 0 and current_so > max_safe_order ? threshold : na, style=plot.style_linebr, color=color.red, linewidth=2, title="No Safety Orders Left")

// Plot Average Position Price Line as Orange
plot(strategy.position_size > 0 ? strategy.position_avg_price : na, style=plot.style_linebr, color=color.orange, linewidth=2, title="Avg Position Price")

// Fill TP Area and SO Area
h1 = plot(strategy.position_avg_price, color=color.new(#000000,100), title="Avg Price Plot Area", display=display.none, editable=false)
h2 = plot(take_profit_level, color=color.new(#000000,100), title="Take Profit Plot Area", display=display.none, editable=false)
h3 = plot(threshold, color=color.new(#000000,100), title="SO Plot Area", display=display.none, editable=false)

// Fill TP Area and SO Area
fill(h1,h2,color=color.new(#38761d,80), title="Take Profit Plot Area")
// Current SO Area
fill(h1,h3,color=color.new(#3d85c6,80), title="SO Plot Area")