세 개의 촛불 반전 트렌드 전략

저자:차오장, 날짜: 2024-02-18 09:48:28
태그:

img

전반적인 설명

세 촛불 반전 트렌드 전략 (Three Candle Reversal Trend Strategy) 은 세 개의 연속적인 상승 또는 하락 촛불이 뒤따라 반대 방향으로 휩쓸고 있는 촛불을 감지함으로써 단기 트렌드의 반전을 식별하는 단기 거래 전략으로, 입점 신호를 필터링하기 위해 여러 가지 기술 지표와 결합된다. 이 전략은 과도한 수익을 얻기 위해 1: 3 리스크-어워드 비율로 거래한다.

전략 논리

이 전략의 핵심 논리는 차트에서 세 개의 연속적인 상승 또는 하락 촛불의 패턴을 식별하는 것입니다. 이것은 일반적으로 단기 트렌드에서 임박한 반전을 암시합니다. 세 개의 하락 촛불이 검출되면 다음 휩쓸고 있는 상승 촛불이 길게 갈 때까지 기다립니다. 반대로 세 개의 상승 촛불이 검출되면 다음 휩쓸고 있는 하락 촛불이 짧게 갈 때까지 기다립니다. 이것은 단기 트렌드에서 역전 기회를 적시에 포착 할 수 있습니다.

또한, 여러 가지 기술 지표가 입력 신호를 필터링하기 위해 도입된다. 다른 매개 변수 설정을 가진 두 개의 SMA 라인이 채택되며, 빠른 SMA가 느린 라인을 넘을 때만 입력 위치가 고려된다. 또한, 선형 회귀 지표는 시장이 범위 또는 트렌드인지 판단하는 데 사용되며 트렌드 조건에서만 거래된다. 추가 입력 신호를 위해 SMA 금색 십자가와 촛불 패턴을 결합하는 옵션도 있다. 이러한 지표의 포괄적 인 판단을 통해 대부분의 소음을 필터링하고 입력 정확도를 향상시킬 수 있다.

스톱 로스 및 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업 영업

장점

세 개의 촛불 반전 트렌드 전략은 다음과 같은 장점을 가지고 있습니다:

  1. 적절한 기회에 대한 단기적 트렌드의 반전을 식별
  2. 여러 표시 필터를 통해 입력 정확도가 향상되었습니다.
  3. 적당한 스톱 로스와 수익을 취하는 적당한 리스크/이익 프로파일
  4. 이해와 동작을 위한 간단한 매개 변수

위험성

이 전략에는 몇 가지 위험 요소가 있습니다.

  1. 단기적 반전은 반드시 장기적 트렌드 반전을 의미하지는 않습니다. 더 높은 시간 프레임 트렌드를 모니터링해야합니다. 더 긴 기간 이동 평균을 필터로 추가 할 수 있습니다.
  2. 단일 촛불 패턴은 잘못된 신호를 일으킬 수 있습니다. 다른 보충 판단을 고려 할 수 있습니다.
  3. 스톱 로스 설정이 너무 공격적일 수도 있습니다. 스톱 로스 범위가 좁아질 수 있습니다.
  4. 백트테스트 데이터가 부족하면 실제 거래 성과에 불확실성이 발생합니다.

개선 방향

이 전략은 다음과 같은 측면에서 향상될 수 있습니다.

  1. 추세를 더 잘 파악하기 위해 이동 평균과 선형 회귀를 위한 매개 변수를 조정합니다.
  2. 추가 신호 확인을 위해 Stoch 같은 다른 지표를 추가합니다.
  3. ATR 매개 변수 및 스톱 로스 비율을 최적화하여 위험과 수익을 균형 잡습니다.
  4. 수익성 향상을 위해 트렌드 브레이크 추적 메커니즘을 도입합니다.
  5. 무역 위험을 통제하기 위한 강력한 자본 관리 시스템을 구축해야 합니다.

결론

결론적으로, 세 촛불 반전 트렌드 전략은 적절하게 균형 잡힌 위험 보상 프로파일에 기반하여 환전 기회를 포착하기 위해 가격 패턴과 여러 지표를 활용하는 간단한 단기 거래 전략입니다. 비교적 낮은 복잡성과 존경받는 결과를 제공하며 투자자의 관심과 테스트를 가치가 있습니다. 전략이 안정적인 고효율 알고 거래 시스템으로 성장하기 위해 매개 변수 조정 및 규칙 보충을 통해 개선할 여지가 있습니다.


/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 3h
basePeriod: 15m
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/
// © platsn
//
// Mainly developed for SPY trading on 1 min chart. But feel free to try on other tickers.

// Basic idea of this strategy is to look for 3 candle reversal pattern within trending market structure. The 3 candle reversal pattern consist of 3 consecutive bullish or bearish candles, 
// followed by an engulfing candle in the opposite direction. This pattern usually signals a reversal of short term trend. This strategy also uses multiple moving averages to filter long or short
// entries. ie. if the 21 smoothed moving average is above the 50, only look for long (bullish) entries, and vise versa. There is option change these moving average periods to suit your needs. 
// I also choose to use Linear Regression to determine whether the market is ranging or trending. It seems the 3 candle pattern is more successful under trending market. Hence I use it as a filter.

// There is also an option to combine this strategy with moving average crossovers. The idea is to look for 3 canddle pattern right after a fast moving average crosses over a slow moving average.
// By default , 21 and 50 smoothed moving averages are used. This gives additional entry opportunites and also provides better results. 

// This strategy aims for 1:3 risk to reward ratio. Stop losses are calculated using the closest low or high values for long or short entries, respectively, with an offset using a percentage of
// the daily ATR value. This allows some price flucuation without being stopped out prematurely. Price target is calculated by multiplying the difference between the entry price and the stop loss
// by a factor of 3. When price target is reach, this strategy will set stop loss at the price target and wait for exit considion to maximize potential profit. 

// This strategy will exit an order if an opposing 3 candle pattern is detected, this could happend before stop loss or price target is reached, and may also happen after price target is reached.

// *Note that this strategy is designed for same day SPY option scalping. I haven't determined an easy way to calculate the # of contracts to represent the equivalent option values. Plus the option
// prices varies greatly depending on which strike and expiry that may suits your trading style. Therefore, please be mindful of the net profit shown. By default, each entry is approxiately equal 
// to buying 10 of same day or 1 day expiry call or puts at strike $1 - $2 OTM. This strategy will close all open trades at 3:45pm EST on Mon, Wed, and Fri. 

// **Note that this strategy also takes into account of extended market data.

// ***Note pyramiding is set to 2 by default, so it allows for multiple entries on the way towards price target. 

// Remember that market conditions are always changing. This strategy was only able to be backtested using 1 month of data. This strategy may not work the next month. Please keep that in mind. 

// *****************************************************************************************************************************************************************************************************

//@version=5
strategy("3 Candle Strike Stretegy", overlay=true, pyramiding=2, initial_capital=5000, commission_type=strategy.commission.cash_per_contract, commission_value = 0.01) 

// ******************** Period **************************************
startY = input(title='Start Year', defval=2011, group = "Trading window")
startM = input.int(title='Start Month', defval=1, minval=1, maxval=12, group = "Trading window")
startD = input.int(title='Start Day', defval=1, minval=1, maxval=31, group = "Trading window")
finishY = input(title='Finish Year', defval=2050, group = "Trading window")
finishM = input.int(title='Finish Month', defval=12, minval=1, maxval=12, group = "Trading window")
finishD = input.int(title='Finish Day', defval=31, minval=1, maxval=31, group = "Trading window")
timestart = timestamp(startY, startM, startD, 00, 00)
timefinish = timestamp(finishY, finishM, finishD, 23, 59)
t1 = time(timeframe.period, "0930-1545:23456")
window = true

// *****************************************************

isSPY = input.bool(defval=true,title="SPY trading only", group = "Trading Options")
SPY_option = input.int(defval=10,title="# of SPY options per trade", group = "Trading Options")
reinvest = input.bool(defval=false,title="reinvest profit?", group = "Trading Options")
src = close

// ***************************************************************************************************** Daily ATR *****************************************************
// Inputs
atrlen = input.int(14, minval=1, title="ATR period", group = "Daily ATR")
iPercent = input.float(5, minval=1, maxval=100, step=0.1, title="% ATR to use for SL / PT", group = "Daily ATR")
// PTPercent = input.int(100, minval=1, title="% ATR for PT")

// Logic
percentage = iPercent * 0.01
datr = request.security(syminfo.tickerid, "1D", ta.rma(ta.tr, atrlen))
datrp = datr * percentage
// datrPT = datr * PTPercent * 0.01

plot(datr,"Daily ATR")
plot(datrp, "Daily % ATR")

// ***************************************************************************************************************** Moving Averages ************************

len0 = input.int(8, minval=1, title='Fast EMA', group= "Moving Averages")
ema1 = ta.ema(src, len0)

len1 = input.int(21, minval=1, title='Fast SMMA', group= "Moving Averages")
smma1 = 0.0
sma_1 = ta.sma(src, len1)
smma1 := na(smma1[1]) ? sma_1 : (smma1[1] * (len1 - 1) + src) / len1

len2 = input.int(50, minval=1, title='Slow SMMA', group= "Moving Averages")
smma2 = 0.0
sma_2 = ta.sma(src, len2)
smma2 := na(smma2[1]) ? sma_2 : (smma2[1] * (len2 - 1) + src) / len2

len3 = input.int(200, minval=1, title='Slow SMMA', group= "Moving Averages")
smma3 = 0.0
sma_3 = ta.sma(src, len3)
smma3 := na(smma3[1]) ? sma_3 : (smma3[1] * (len3 - 1) + src) / len3

ma_bull = smma1 > smma2 and smma1 > smma1[1]
ma_bear = smma1 < smma2 and smma1 < smma1[1]

ma_bull_macro = smma1 > smma3 and smma2 > smma3
ma_bear_macro = smma1 < smma3 and smma2 < smma3

// plot(ma_bull? 1 : 0, "MA bull")
// plot(ma_bear? 1 : 0 , "MA bear")

// **************************************************************************************************************** Linear Regression *************************

//Input
clen = input.int(defval = 50, minval = 1, title = "Linear Regression Period", group = "Linear Regression")
slen = input.int(defval=50, minval=1, title="LR Slope Period" , group = "Linear Regression")
glen = input.int(defval=14, minval=1, title="LR Signal Period", group = "Linear Regression")
LR_thres = input.float(0.03, minval=0, step=0.001, title="LR Threshold for Ranging vs Trending" , group = "Linear Regression")
 
//Linear Regression Curve
lrc = ta.linreg(src, clen, 0)
//Linear Regression Slope
lrs = (lrc-lrc[1])/1
//Smooth Linear Regression Slope
slrs = ta.ema(lrs, slen)
//Signal Linear Regression Slope
alrs = ta.sma(slrs, glen)

up_accel = lrs > alrs and lrs > 0 
down_accel = lrs < alrs and lrs < 0 

LR_ranging  = math.abs(slrs) <= LR_thres
LR_trending = math.abs(slrs) > LR_thres

plot(slrs, "LR slope")
plot(LR_trending?1:0, "LR Trending")

// *********************************************************************************************************************************** Candle conditions **************************

bull_3s = close[3] <= open[3] and close[2] <= open[2] and close[1] <= open[1] and close > open[1]
bear_3s = close[3] >= open[3] and close[2] >= open[2] and close[1] >= open[1] and close < open[1]

plotshape(bull_3s, style=shape.triangleup, color=color.new(color.green, 0), location=location.belowbar, size=size.small, text='3s-Bull', title='3 Line Strike Up')
plotshape(bear_3s, style=shape.triangledown, color=color.new(color.red, 0), location=location.abovebar, size=size.small, text='3s-Bear', title='3 Line Strike Down')

// ***************************************************************************************************************************************** SL & PT ***********************************
RR = input.float(3.0, minval = 1, step = 0.1, title="Reward to Risk Ratio", group = "Trading Options")

barsSinceLastEntry()=>
    strategy.opentrades > 0 ? (bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades-1)) : na

last_high = math.max(high, high[1], high[2], high[3])
last_low = math.min(low, low[1], low[2], low[3])

long_SL = last_low - datrp
short_SL = last_high + datrp

long_PT = last_high
short_PT = last_low

last_entry = strategy.opentrades.entry_price(strategy.opentrades-1)
risk = last_entry - long_SL

if strategy.opentrades > 0
    long_SL := math.min(long_SL[barsSinceLastEntry()], last_low)
    short_SL := math.max(short_SL[barsSinceLastEntry()], last_high)
    risk := last_entry - long_SL
    long_PT := last_entry + (last_entry - long_SL) * RR
    short_PT := last_entry - (short_SL - last_entry) * RR
else
    long_PT := open + (open - long_SL) * RR
    short_PT := open - (short_SL - open) * RR

// plot(short_SL,title = "Short SL", color=color.new(color.purple,30))
// plot(long_SL,title = "Long SL", color=color.new(color.purple,30))
// plot(long_PT,title = "Long PT", color=color.new(color.white,50))
// plot(short_PT,title = "Short PT", color=color.new(color.white,50))
// plot(last_entry, title = "Last entry")
// plot(risk, title = "Risk")

// **************************************************************************************************************************************** Trade Pauses ****************************************
bool trade_pause = false
bool trade_pause2 = false

if high - low > datr*0.3
    trade_pause := true
else
    trade_pause := false

no_longat10 = input.bool(true, title="No long entry between 10 - 10:30 (Avoid 10 am dump)", group = "Trading Options")

// ************************************************************************************************************************************ Entry conditions **************************

trade_3s = input.bool(title='Trade 3s candle pattern', defval=true, group = "Trading Options")
L_entry1 = bull_3s and ma_bull and LR_trending 
S_entry1 = bear_3s and ma_bear and LR_trending

trade_ma_reversal = input.bool(title='Trade MA Cross Reversal Signal', defval=true, group = "Trading Options")
L_entry2 = ma_bear_macro and ema1 > smma1 and bull_3s and ta.barssince(ta.cross(ema1,smma1)) < 10
S_entry2 = ma_bull_macro and ema1 < smma1 and bear_3s and ta.barssince(ta.cross(ema1,smma1)) < 10

// ************************************************************************************************************************************** Exit Conditions ********************************

// bsle_thres = input.int(0, "Bar since entry threshold")

// exit0 = barsSinceLastEntry() >= bsle_thres
exit0 = true

L_exit1 = bear_3s
S_exit1 = bull_3s

// ************************************************************************************************************************************ Entry and Exit orders *****************************
strategy.initial_capital = 50000
trade_amount = math.floor(strategy.initial_capital / close)

if isSPY 
    if strategy.netprofit > 0 and reinvest
        trade_amount := math.floor((strategy.initial_capital + strategy.netprofit) * 0.2 / 600) * 10 * SPY_option
    else
        trade_amount := math.floor(strategy.initial_capital * 0.2 / 600) * 10 * SPY_option


if not(trade_pause) and not(trade_pause2) and time(timeframe.period, "0930-1540:23456")
    if trade_3s
        if not(time(timeframe.period, "1000-1030:23456")) and no_longat10
            strategy.entry("Long", strategy.long, 1, when = L_entry1 and window, comment="Long 3s" + " SL=" + str.tostring(math.round(long_SL,2)) + " PT=" + str.tostring(math.round(long_PT,2)))
        strategy.entry("Short", strategy.short, 1, when = S_entry1 and window, comment = "Short 3s" + " SL=" + str.tostring(math.round(short_SL,2)) + " PT=" + str.tostring(math.round(short_PT,2)))
    if trade_ma_reversal
        strategy.entry("Long", strategy.long, 1, when = L_entry2 and window, comment="Long MA cross" + " SL=" + str.tostring(math.round(long_SL,2)) + " PT=" + str.tostring(math.round(long_PT,2)))
        strategy.entry("Short", strategy.short, 1, when = S_entry2 and window, comment = "Short MA corss" + " SL=" + str.tostring(math.round(short_SL,2)) + " PT=" + str.tostring(math.round(short_PT,2)))

if high > long_PT
    long_SL := low[1]
    strategy.exit("Exit", "Long", when = exit0 and low < long_PT, stop= long_SL, comment = "Exit Long SL/PT hit")
strategy.close("Long", when = L_exit1, comment = "Exit on Bear Signal")

if low < short_PT
    short_SL := high[1]
    strategy.exit("Exit", "Short", when= exit0 and high > short_PT, stop= short_SL, comment = "Exit Short SL/PT hit")
strategy.close("Short", when = S_exit1, comment = "Exit on Bull Signal")

if time(timeframe.period, "1545-1600:246")
    strategy.close_all()


더 많은