윌리엄스 프랙탈 쌍방향 거래 전략

저자:차오장, 날짜: 2023-11-15 16:22:07
태그:

img

전반적인 설명

이 전략은 반전 신호를 식별하기 위해 윌리엄스의 새로운 최고와 최저 지표를 사용하고, 브레이크아웃 거래에 대한 여러 이동 평균과 RSI를 사용하여 잘못된 신호를 필터링하여 효율적인 이방향 거래를 가능하게합니다.

전략 논리

  1. 윌리엄스의 새로운 최고와 최저 지표는 주어진 기간 동안 가장 높고 가장 낮은 가격을 사용하여 전환점을 식별합니다. 구매 및 판매 신호를 생성합니다.

  2. 20, 50, 100일 이동 평균은 여러 이동 평균을 형성합니다. 거래 신호는 가격이 이동 평균 중 두 개를 통과 할 때 생성됩니다.

  3. RSI 지표는 불확실한 신호를 필터링하기 위해 과잉 구매 및 과잉 판매 구역을 식별합니다.

  4. 이 전략은 두 이동 평균이 깨지는 것을 결정하고, 신뢰할 수 있는 구매 및 판매 신호를 생성하기 위해 윌리엄스 지표 신호와 RSI 필터링을 결합합니다.

  5. 진입 규칙: 단기 MA가 중장기 MA를 넘어서 Williams의 새로운 낮은 신호와 RSI의 낮은 신호가 나타나면, 긴 이동. 단기 MA가 중장기 MA를 넘어서 Williams의 새로운 높은 신호와 RSI의 높은 신호가 나타나면, 짧은 이동.

  6. 스톱 로스 및 영업 수익: 고정 비율의 스톱 로스 및 영업 수익.

장점

  1. 윌리엄스 지표는 역전 신호에 대한 주요 지원과 저항을 정확하게 식별합니다.

  2. 여러 이동 평균 크로스오버는 단일 이동 평균 윙사에서 잘못된 신호를 피합니다.

  3. RSI 필터는 입력 시기를 더 정확하고 안정적으로 조절합니다.

  4. 일정한 스톱 로스 및 영업이익은 위험을 통제하고 P&L에 대한 명확성을 제공합니다.

  5. 역전 및 트렌드 지표를 결합하면 더 신뢰할 수 있는 신호를 제공합니다.

위험성

  1. 부적절한 기호 선택, 다른 기호에 대한 매개 변수가 조정되어야 합니다.

  2. 시간 프레임 선택이 비효율적이기 때문에 다른 시간 프레임에 맞춰야 합니다.

  3. 일정한 스톱 로스/프로프트 취득은 시장 변화에 적응할 수 없고, 일찍 중단하거나 수익을 취득할 수 있습니다.

  4. 이동평균이 변동할 때 휘프사우는 잘못된 신호를 생성할 수 있습니다.

  5. 신호가 뒤떨어지면 신호가 뒤떨어집니다

더 나은 기회

  1. 다른 거래 도구에 대한 매개 변수의 동적 최적화

  2. 적응적인 스톱 로스를 도입하고 더 나은 P&L를 위해 수익을 취합니다.

  3. MACD, 스토카스틱스 같은 필터를 더 추가해서 잘못된 신호를 줄일 수 있습니다.

  4. 기계 학습 알고리즘을 통합해서 자동으로 최적의 입력을 감지합니다.

  5. 트렌드 조건을 파악하기 위해 더 많은 트렌드 지표를 통합합니다.

요약

이 전략은 윌리엄스, 이동평균, RSI 및 기타 기술 분석 도구를 결합하여 잘못된 신호를 줄이고 반전을 효과적으로 포착하기 위해 이중 확인을 사용하여 위험을 제어하기 위해 고정 스톱 로스 / 영업 취득을 결합합니다. 전반적으로 신뢰할 수 있고 실용적인 이중 방향 거래 시스템입니다. 다음 단계는 매개 변수 최적화, 스톱 로스 / 영업 취득 향상 및 앙상블 모델링을 통해 성능을 더욱 향상시키는 것입니다.


/*backtest
start: 2023-11-07 00:00:00
end: 2023-11-14 00:00:00
period: 1h
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/
// © B_L_A_C_K_S_C_O_R_P_I_O_N
// v 1.1

//@version=4
strategy("Williams Fractals Strategy by ȼhąţhµяąɲǥą", overlay=true, default_qty_type=strategy.cash, default_qty_value=1000, currency='USD')

// *************Appearance*************
theme = input(type=input.string, defval="dark", options=["light","dark"], group="Appearance")
show_fractals = input(false, "Show Fractals", group="Appearance")
show_ema = input(false, "Show EMAs", group="Appearance")

// *************colors*************
color_green = color.green
color_red = color.red
color_yellow = color.yellow
color_orange = color.orange
color_blue = color.blue
color_white = color.white

// *************WF*************
// Define "n" as the number of periods and keep a minimum value of 2 for error handling.
n = input(title="Fractal Periods", defval=2, minval=2, type=input.integer, group="Williams Fractals")

// UpFractal
bool upflagDownFrontier = true
bool upflagUpFrontier0 = true
bool upflagUpFrontier1 = true
bool upflagUpFrontier2 = true
bool upflagUpFrontier3 = true
bool upflagUpFrontier4 = true

for i = 1 to n
    upflagDownFrontier := upflagDownFrontier and (high[n-i] < high[n])
    upflagUpFrontier0 := upflagUpFrontier0 and (high[n+i] < high[n])
    upflagUpFrontier1 := upflagUpFrontier1 and (high[n+1] <= high[n] and high[n+i + 1] < high[n])
    upflagUpFrontier2 := upflagUpFrontier2 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+i + 2] < high[n])
    upflagUpFrontier3 := upflagUpFrontier3 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+i + 3] < high[n])
    upflagUpFrontier4 := upflagUpFrontier4 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+4] <= high[n] and high[n+i + 4] < high[n])
flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4

upFractal = (upflagDownFrontier and flagUpFrontier)

// downFractal
bool downflagDownFrontier = true
bool downflagUpFrontier0 = true
bool downflagUpFrontier1 = true
bool downflagUpFrontier2 = true
bool downflagUpFrontier3 = true
bool downflagUpFrontier4 = true

for i = 1 to n
    downflagDownFrontier := downflagDownFrontier and (low[n-i] > low[n])
    downflagUpFrontier0 := downflagUpFrontier0 and (low[n+i] > low[n])
    downflagUpFrontier1 := downflagUpFrontier1 and (low[n+1] >= low[n] and low[n+i + 1] > low[n])
    downflagUpFrontier2 := downflagUpFrontier2 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+i + 2] > low[n])
    downflagUpFrontier3 := downflagUpFrontier3 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+i + 3] > low[n])
    downflagUpFrontier4 := downflagUpFrontier4 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+4] >= low[n] and low[n+i + 4] > low[n])
flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4

downFractal = (downflagDownFrontier and flagDownFrontier)

plotshape(downFractal and show_fractals, style=shape.triangleup, location=location.belowbar, offset=-n, color=color_green)
plotshape(upFractal and show_fractals, style=shape.triangledown, location=location.abovebar, offset=-n, color=color_red)

// *************EMA*************
len_a = input(20, minval=1, title="EMA Length A", group="EMA")
src_a = input(close, title="EMA Source A", group="EMA")
offset_a = input(title="EMA Offset A", type=input.integer, defval=0, minval=-500, maxval=500, group="EMA")
out_a = ema(src_a, len_a)
plot(show_ema ? out_a : na, title="EMA A", color=color_green, offset=offset_a)

len_b = input(50, minval=1, title="EMA Length B", group="EMA")
src_b = input(close, title="EMA Source B", group="EMA")
offset_b = input(title="EMA Offset B", type=input.integer, defval=0, minval=-500, maxval=500, group="EMA")
out_b = ema(src_b, len_b)
ema_b_color = (theme == "dark") ? color_yellow : color_orange
plot(show_ema ? out_b : na, title="EMA B", color=ema_b_color, offset=offset_b)

len_c = input(100, minval=1, title="EMA Length C", group="EMA")
src_c = input(close, title="EMA Source C", group="EMA")
offset_c = input(title="EMA Offset C", type=input.integer, defval=0, minval=-500, maxval=500, group="EMA")
out_c = ema(src_c, len_c)
ema_c_color = (theme == "dark") ? color_white : color_blue
plot(show_ema ? out_c : na, title="EMA C", color=ema_c_color, offset=offset_c)

// *************RSI*************
rsi_len = input(14, minval=1, title="RSI Length", group="RSI")
rsi_src = input(close, "RSI Source", type = input.source, group="RSI")
up = rma(max(change(rsi_src), 0), rsi_len)
down = rma(-min(change(rsi_src), 0), rsi_len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

// *************Calculation*************
long = (out_a > out_b) and (out_a > out_c) and downFractal and low[2] > out_c and rsi[2] < rsi
short = (out_a < out_b) and (out_a < out_c) and upFractal and high[2] < out_c and rsi[2] > rsi

plotshape(long, style=shape.labelup, color=color_green, location=location.belowbar, title="long label", text= "L", textcolor=color_white)
plotshape(short, style=shape.labeldown, color=color_red, location=location.abovebar, title="short label", text= "S", textcolor=color_white)

// *************End of Signals calculation*************

// Make input options that configure backtest date range
startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31, group="Orders")
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12, group="Orders")
startYear = input(title="Start Year", type=input.integer,
     defval=2018, minval=1800, maxval=2100, group="Orders")

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

// Look if the close time of the current bar
// falls inside the date range
inDateRange =  true

// Make inputs that set the take profit % (optional)
longProfitPerc = input(title="Long Take Profit (%)",
     type=input.float, minval=0.0, step=0.1, defval=0.5, group="Orders") * 0.01

shortProfitPerc = input(title="Short Take Profit (%)",
     type=input.float, minval=0.0, step=0.1, defval=0.5, group="Orders") * 0.01

// Figure out take profit price
longExitPrice  = strategy.position_avg_price * (1 + longProfitPerc)
shortExitPrice = strategy.position_avg_price * (1 - shortProfitPerc)

// Plot take profit values for confirmation
plot(series=(strategy.position_size > 0) ? longExitPrice : na,
     color=color_green, style=plot.style_circles,
     linewidth=1, title="Long Take Profit")
plot(series=(strategy.position_size < 0) ? shortExitPrice : na,
     color=color_green, style=plot.style_circles,
     linewidth=1, title="Short Take Profit")

// Submit entry orders
if (inDateRange and long and strategy.opentrades == 0)
    strategy.entry(id="Long", long=true)

if (inDateRange and short and strategy.opentrades == 0)
    strategy.entry(id="Short", long=false)

// Submit exit orders based on take profit price
// if (strategy.position_size > 0)
//     strategy.exit(id="LTP", limit=longExitPrice)

// if (strategy.position_size < 0)
//     strategy.exit(id="STP", limit=shortExitPrice)
    
// Set stop loss level with input options (optional)
longLossPerc = input(title="Long Stop Loss (%)",
     type=input.float, minval=0.0, step=0.1, defval=3.1, group="Orders") * 0.01

shortLossPerc = input(title="Short Stop Loss (%)",
     type=input.float, minval=0.0, step=0.1, defval=3.1, group="Orders") * 0.01

// Determine stop loss price
longStopPrice  = strategy.position_avg_price * (1 - longLossPerc)
shortStopPrice = strategy.position_avg_price * (1 + shortLossPerc)

// Plot stop loss values for confirmation
plot(series=(strategy.position_size > 0) ? longStopPrice : na,
     color=color_red, style=plot.style_cross,
     linewidth=1, title="Long Stop Loss")
plot(series=(strategy.position_size < 0) ? shortStopPrice : na,
     color=color_red, style=plot.style_cross,
     linewidth=1, title="Short Stop Loss")

// Submit exit orders based on calculated stop loss price
if (strategy.position_size > 0)
    strategy.exit(id="ExL",limit=longExitPrice, stop=longStopPrice)

if (strategy.position_size < 0)
    strategy.exit(id="ExS", limit=shortExitPrice, stop=shortStopPrice)

// Exit open market position when date range ends
if (not inDateRange)
    strategy.close_all()

더 많은