스토카스틱 및 MACD 지표에 기초한 역전 거래 전략

저자:차오장, 날짜: 2023-09-21 21:39:34
태그:

전반적인 설명

이 전략은 과도한 구매 및 과도한 판매 반전 지점을 결정하기 위한 스토카스틱 지표와 트렌드 반전을 식별하기 위한 MACD 지표를 결합하여, 반전 거래를 통해 낮은 가격으로 구매하고 높은 가격으로 판매하는 것을 목표로 합니다. 또한 수익을 확보하고 위험을 효과적으로 제어하기 위해 트레일링 스톱을 설정합니다.

전략 논리

  1. 스토카스틱 지표를 사용하여 과반 구매 및 과반 판매 상태를 식별합니다. 20 이하의 판독은 과반 판매 수준을 나타냅니다. 80 이상은 역전 신호를 형성하는 과반 구매 구역을 나타냅니다.

  2. MACD 황금 십자가에 장차하고 MACD 죽음의 십자가에 단차가 됩니다. 신호선 위의 MACD 교차는 이동 평균 반전을 나타내고 트렌드 반전을 암시합니다.

  3. 스토카스틱 반전이 MACD 반전 신호와 일치할 때 긴 또는 짧은 포지션을 취합니다.

  4. 트레일링 스톱 로스를 구현한다. 트렌드에 진입한 후, 가격이 특정 이익 퍼센트에 도달하면 트레일링 스톱이 트리거된다. 스톱 레벨은 상승 가격 채널을 추적한다.

  5. 기존 포지션은 새로운 반전 신호가 나타나면 폐쇄되고 스톱 로스가 재설정됩니다.

장점

  • 여러 표시기 확인은 신호 정확성을 향상시킵니다.

  • 스토카스틱은 과잉 구매/ 과잉 판매 구역을 효과적으로 식별합니다.

  • MACD는 이동평균 반전을 일찍 포착합니다.

  • 트레일링 스톱은 수익에 잘 잠금됩니다

  • 명확한 전략 신호와 충분한 백트테스팅 데이터

  • 쉽게 조정할 수 있는 최적화 가능한 매개 변수

위험성

  • 여러 지표를 최적화하는 데 어려움이 있습니다.

  • 반전 신호는 잘못 판단 될 수 있고 검증이 필요합니다.

  • 더 많은 데이터가 필요 후속 정지 테스트 및 최적화

  • 스토카스틱과 MACD의 지연성

  • 빈번 한 거래 는 더 높은 비용 으로 이어질 수 있다

개선

  • 강력한 거래 시스템을 구축하기 위해 더 많은 지표를 추가하십시오.

  • 최적의 조합을 찾기 위해 다른 매개 변수 기간을 테스트

  • 실시간으로 업데이트되는 적응적 매개 변수를 개발

  • 최대 유출을 제한하기 위해 유출 중지 손실을 설정

  • 부각에서 잘못된 신호를 피하기 위해 부피를 포함

  • 거래 비용의 영향을 고려하고 최소 수익 목표를 설정

결론

이 전략은 유리한 반전 거래점을 식별하는 데 스토카스틱과 MACD의 강점을 결합합니다. 후속 중지 메커니즘은 또한 수익을 효과적으로 잠금합니다. 그러나 반전 거래는 여전히 더 많은 지표로부터 검증과 추가 매개 변수 최적화가 필요한 고유한 위험을 지니고 있습니다. 안정적인 매개 변수와 적절한 자본 관리로이 전략은 매우 효율적인 단기 거래 시스템으로 변할 수 있습니다.


/*backtest
start: 2022-09-14 00:00:00
end: 2023-06-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
////////////////////////////////////////////////////////////
// @CoinDigger
//
// Credits for the base strategy go to HPotter
//
// I've just added a trail stop, basic leverage simulation and stop loss
//
////////////////////////////////////////////////////////////
//  Copyright by HPotter v1.0 28/01/2021
// This is combo strategies for get a cumulative signal. 
//
// First strategy
// This System was created from the Book "How I Tripled My Money In The 
// Futures Market" by Ulf Jensen, Page 183. This is reverse type of strategies.
// The strategy buys at market, if close price is higher than the previous close 
// during 2 days and the meaning of 9-days Stochastic Slow Oscillator is lower than 50. 
// The strategy sells at market, if close price is lower than the previous close price 
// during 2 days and the meaning of 9-days Stochastic Fast Oscillator is higher than 50.
//
// Second strategy
// MACD – Moving Average Convergence Divergence. The MACD is calculated 
// by subtracting a 26-day moving average of a security's price from a 
// 12-day moving average of its price. The result is an indicator that 
// oscillates above and below zero. When the MACD is above zero, it means 
// the 12-day moving average is higher than the 26-day moving average. 
// This is bullish as it shows that current expectations (i.e., the 12-day 
// moving average) are more bullish than previous expectations (i.e., the 
// 26-day average). This implies a bullish, or upward, shift in the supply/demand 
// lines. When the MACD falls below zero, it means that the 12-day moving average 
// is less than the 26-day moving average, implying a bearish shift in the 
// supply/demand lines.
// A 9-day moving average of the MACD (not of the security's price) is usually 
// plotted on top of the MACD indicator. This line is referred to as the "signal" 
// line. The signal line anticipates the convergence of the two moving averages 
// (i.e., the movement of the MACD toward the zero line).
// Let's consider the rational behind this technique. The MACD is the difference 
// between two moving averages of price. When the shorter-term moving average rises 
// above the longer-term moving average (i.e., the MACD rises above zero), it means 
// that investor expectations are becoming more bullish (i.e., there has been an 
// upward shift in the supply/demand lines). By plotting a 9-day moving average of 
// the MACD, we can see the changing of expectations (i.e., the shifting of the 
// supply/demand lines) as they occur.
//
// WARNING:
// - For purpose educate only
// - This script to change bars colors.
////////////////////////////////////////////////////////////
Reversal123(Length, KSmoothing, DLength, Level) =>
    vFast = sma(stoch(close, high, low, Length), KSmoothing) 
    vSlow = sma(vFast, DLength)
    pos = 0.0
    pos := iff(close[2] < close[1] and close > close[1] and vFast < vSlow and vFast > Level, 1,
	         iff(close[2] > close[1] and close < close[1] and vFast > vSlow and vFast < Level, -1, nz(pos[1], 0))) 
	pos

MACD(fastLength,slowLength,signalLength) =>
    pos = 0.0
    fastMA = ema(close, fastLength)
    slowMA = ema(close, slowLength)
    macd = fastMA - slowMA
    signal = sma(macd, signalLength)
    pos:= iff(signal < macd , 1,
	       iff(signal > macd, -1, nz(pos[1], 0))) 
    pos
strategy(title="Combo Backtest 123 Reversal & MACD Crossover with Trail and Stop", shorttitle="ComboReversal123MACDWithStop", overlay = false, precision=8,default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=100, currency="USD", commission_type=strategy.commission.percent, commission_value=0.075)

leverage=input(2,"leverage",step=1)
percentOfEquity=input(100,"percentOfEquity",step=1)

sl_trigger = input(10, title='Stop Trail Trigger %', type=input.float)/100
sl_trail = input(5, title='Stop Trail %', type=input.float)/100
sl_inp = input(10, title='Stop Loss %', type=input.float)/100

Length = input(100, minval=1)
KSmoothing = input(1, minval=1)
DLength = input(2, minval=1)
Level = input(1, minval=1)
//-------------------------
fastLength = input(10, minval=1)
slowLength = input(19,minval=1)
signalLength=input(24,minval=1)
xSeria = input(title="Source", type=input.source, defval=close)
reverse = input(false, title="Trade reverse")


////////////////////////////////////////////////////////////////////////////////
// BACKTESTING RANGE
 
// From Date Inputs
fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear = input(defval = 2015, title = "From Year", minval = 1970)
 
// To Date Inputs
toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
toMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
toYear = input(defval = 2999, title = "To Year", minval = 1970)
 
// Calculate start/end date and time condition
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = time >= startDate and time <= finishDate
 
////////////////////////////////////////////////////////////////////////////////



////////////////////// STOP LOSS CALCULATIONS //////////////////////////////
///////////////////////////////////////////////////


cond() => barssince(strategy.position_size[1] == 0 and (strategy.position_size > 0 or strategy.position_size < 0)) > 0

lastStopLong = 0.0
lastStopLong := lastStopLong[1] != strategy.position_avg_price - (strategy.position_avg_price * (sl_inp)) and lastStopLong[1]  != 0.0 ? lastStopLong[1]  : strategy.position_size > 0 ? (cond() and close > strategy.position_avg_price + (strategy.position_avg_price * (sl_trigger)) ? strategy.position_avg_price + (strategy.position_avg_price * (sl_trail)) : strategy.position_avg_price - (strategy.position_avg_price * (sl_inp))) : 0
lastStopShort = 0.0
lastStopShort := lastStopShort[1] != strategy.position_avg_price + (strategy.position_avg_price * (sl_inp)) and lastStopShort[1]  != 9999999999.0 ? lastStopShort[1]  : strategy.position_size < 0 ? (cond() and close < strategy.position_avg_price - (strategy.position_avg_price * (sl_trigger)) ? strategy.position_avg_price - (strategy.position_avg_price * (sl_trail)) : strategy.position_avg_price + (strategy.position_avg_price * (sl_inp))) : 9999999999.0

longStopPrice = 0.0
longStopPrice2 = 0.0
longStopPrice3 = 0.0
shortStopPrice = 0.0
longStopPrice := if strategy.position_size > 0
    originalStop = strategy.position_avg_price - (strategy.position_avg_price * (sl_inp))
    trigger = strategy.position_avg_price + (strategy.position_avg_price * (sl_trigger))
    trail = strategy.position_avg_price + (strategy.position_avg_price * (sl_trail))
    stopValue = high > trigger ? trail : 0
    max(stopValue, originalStop, longStopPrice[1])
else
    0

longStopPrice2 := if strategy.position_size > 0
    originalStop = strategy.position_avg_price - (strategy.position_avg_price * (sl_inp))
    trigger = strategy.position_avg_price + (strategy.position_avg_price * (sl_trigger*2))
    trail = strategy.position_avg_price + (strategy.position_avg_price * (sl_trail*2))
    stopValue = high > trigger ? trail : 0
    max(stopValue, originalStop, longStopPrice2[1])
else
    0


longStopPrice3 := if strategy.position_size > 0
    originalStop = strategy.position_avg_price - (strategy.position_avg_price * (sl_inp))
    trigger = strategy.position_avg_price + (strategy.position_avg_price * (sl_trigger*4))
    trail = strategy.position_avg_price + (strategy.position_avg_price * (sl_trail*3))
    stopValue = high > trigger ? trail : 0
    max(stopValue, originalStop, longStopPrice3[1])
else
    0
    
shortStopPrice := if strategy.position_size < 0
    originalStop = strategy.position_avg_price + (strategy.position_avg_price * (sl_inp))
    trigger = strategy.position_avg_price - (strategy.position_avg_price * (sl_trigger))
    trail = strategy.position_avg_price - (strategy.position_avg_price * (sl_trail))
    stopValue = low < trigger ? trail : 999999
    min(stopValue, originalStop, shortStopPrice[1])
else
    999999
    
///////////////////////////////////////////////////
///////////////////////////////////////////////////


posReversal123 = Reversal123(Length, KSmoothing, DLength, Level)
posMACD = MACD(fastLength,slowLength, signalLength)
pos = iff(posReversal123 == 1 and posMACD == 1 , 1,
	   iff(posReversal123 == -1 and posMACD == -1, -1, 0)) 
	   
possig = pos

quantity = max(0.000001,min(((strategy.equity*(percentOfEquity/100))*leverage/open),100000000))

if (possig == 1 and time_cond)
    strategy.entry("Long", strategy.long, qty=quantity)
if (possig == -1 and time_cond)
    strategy.entry("Short", strategy.short, qty=quantity) 
if (strategy.position_size > 0 and possig == -1 and time_cond)   
    strategy.close_all()
if (strategy.position_size < 0 and possig == 1 and time_cond)   
    strategy.close_all()
if ((strategy.position_size < 0 or strategy.position_size > 0) and possig == 0)   
    strategy.close_all()

//EXIT TRADE @ TSL
if strategy.position_size > 0
    strategy.exit(id="Long", stop=longStopPrice)
if strategy.position_size < 0
    strategy.exit(id="Short", stop=shortStopPrice)



더 많은