이 전략의 핵심 아이디어는 슈퍼트렌드 지표를 주식 곡선 거래와 결합하는 것입니다. 슈퍼트렌드 지표가 구매 또는 판매 신호를 생성 할 때 우리는 거래를 직접 실행하지 않습니다. 대신 현재 주식 곡선이 이동 평균 이하인지 확인합니다. 주식 곡선이 이동 평균 이상일 때만 포지션을 열 것입니다. 주식 곡선이 이동 평균 이하일 때 우리는 현재 전략에 대한 거래를 일시 중단합니다. 이것은 손실의 확장을 효과적으로 막을 수 있습니다.
이 전략은 크게 두 부분으로 구성됩니다.
슈퍼트렌드 지표의 계산 공식은 다음과 같습니다.
상단 대역 = 원천 가격 - ATR 곱기 * ATR 하위 대역 = 원천 가격 + ATR 곱기 * ATR
여기서 ATR는 평균 진범을 나타냅니다. 슈퍼트렌드 지표는 ATR를 사용하여 상부 및 하부 대역을 설정합니다. 상부 대역 위의 브레이크오웃은 판매 신호를 나타냅니다. 하부 대역 아래에 있는 브레이크오웃은 구매 신호를 나타냅니다.
주식 곡선 거래의 아이디어는 전략의 주식 곡선의 이동 평균을 취하는 것입니다. 주식 곡선이 이동 평균 이하로 떨어지면 현재 전략의 거래를 일시 중단하고 주식 곡선이 이동 평균보다 다시 상승할 때까지 기다립니다.
이 전략은 두 기법을 결합하여 슈퍼트렌드 지표가 거래 신호를 생성 한 후에 우리는 직접 거래를하지 않습니다. 대신 현재 주식 곡선이 이동 평균보다 높는지 확인합니다. 두 조건이 충족 될 때만 우리는 포지션을 열 것입니다. 이것은 슈퍼트렌드 지표 자체에 내재한 위험을 효과적으로 완화하고 과도한 손실을 방지 할 수 있습니다.
이 전략의 주요 장점은 다음과 같습니다.
이 지표는 슈퍼트렌드 지표의 위험을 효과적으로 예방할 수 있습니다. 슈퍼트렌드 지표 자체는 손실을 효과적으로 억제 할 수 없습니다. 주식 곡선 거래는이 단점을 보완합니다.
거래가 불리해지면 과도한 손실을 피하기 위해 거래를 중단합니다. 시장이 회복되면 거래를 재개할 수 있습니다.
수동 개입 없이 자동으로 포지션을 관리할 수 있습니다. 주식 곡선이 이동 평균 이하로 떨어지면 자동으로 중단되고 주식 곡선이 그 위에 다시 반등하면 재개됩니다.
이 전략에는 몇 가지 위험도 있습니다.
잘못된 매개 변수 설정은 주식 곡선 거래가 효과적이지 않을 수 있습니다. 적절한 이동 평균 기간을 선택해야합니다.
시장 동향이 변할 때 지위를 즉시 조정하지 못할 수도 있습니다. 이것은 특정 손실로 이어질 수 있습니다.
주식 곡선이 회복되기를 기다리는 동안 좋은 거래 기회를 놓칠 수도 있습니다.
대책:
매개 변수를 최적화하고 가장 좋은 이동 평균 기간을 선택합니다.
추세를 판단하고 그에 따라 포지션을 조정하기 위해 다른 지표를 포함합니다.
중단된 거래 기간을 단축하여 놓친 기회의 가능성을 줄이십시오.
우리는 다음과 같은 측면에서 전략을 최적화 할 수 있습니다:
최적의 ATR 기간과 곱기를 찾기 위해 다른 매개 변수 조합을 테스트합니다.
다른 종류의 이동 평균을 시도해보세요. 기하급수적인 이동 평균, 헐 이동 평균 등
다른 지표를 추가하여 시장 트렌드를 결정하고, 트렌드가 변할 때 포지션을 조정합니다.
가장 좋은 균형 을 찾기 위해 이동 평균 기간 을 최적화 한다. 너무 긴 기간 은 기회 를 놓칠 수 있고, 너무 짧은 기간 은 너무 자주 중단 될 수 있다.
거래 중단을 위한 조건을 최적화하세요. 예를 들어 중단 전에 스톱 로스 임계치를 설정하는 것 처럼요.
이 전략은 슈퍼트렌드 지표를 주식 곡선 거래와巧妙하게 결합하여 두 기법의 장점을 활용합니다. 테스트 결과는 대부분의 경우 주식 곡선 거래를 적용하면 실제로 수익성이 감소한다는 것을 보여줍니다. 따라서이 전략은 방어 트레이더에게 더 적합합니다. 매개 변수 및 논리 최적화로 매우 실용적인 양적 거래 전략이 될 수 있습니다.
/*backtest start: 2023-01-14 00:00:00 end: 2024-01-14 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000) eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings") shEQandMA = input.bool(true, "Show Original Equity Curve and MA") shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA") Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings") src = input(hl2, title='Source', group = "SuperTrend Settings") Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings") changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings") //SuperTrend Code atr2 = ta.sma(ta.tr, Periods) atr = changeATR ? ta.atr(Periods) : atr2 up = src - Multiplier * atr up1 = nz(up[1], up) up := close[1] > up1 ? math.max(up, up1) : up dn = src + Multiplier * atr dn1 = nz(dn[1], dn) dn := close[1] < dn1 ? math.min(dn, dn1) : dn trend = 1 trend := nz(trend[1], trend) trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend // Strategy main code buySignal = trend == 1 and trend[1] == -1 sellSignal = trend == -1 and trend[1] == 1 if buySignal strategy.entry('Long', strategy.long) if sellSignal strategy.entry('Short', strategy.short) //Equity Curve calcs eq = strategy.netprofit ch = ta.change(eq) neq = ch != 0 ? eq : na mova = ta.ema(neq,eqlen) // New Equity Curve var float neweq = 0 var int ttrades = 0 var int wintrades = 0 var int losetrades = 0 switch strategy.netprofit == strategy.netprofit[1] => na strategy.netprofit < mova and strategy.netprofit[1] > mova => neweq := neweq + ch strategy.netprofit < mova and strategy.netprofit[1] < mova => na strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch newch = ta.change(neweq) switch newch == 0 => na newch > 0 => wintrades := wintrades +1 ttrades := ttrades +1 newch < 0 => losetrades := losetrades +1 ttrades := ttrades +1 //plot(eq, linewidth = 2) //plot(mova, color=color.red) //plot(neweq, color= color.green, linewidth = 3) //Table var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1) table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white) table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white) table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white) table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white) table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white) table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white) table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white) table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white) //Equity Curve EMA stat table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white) table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white) table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white) table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white) table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white) //Original Strategy stat // table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white) // table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white) // table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white) // table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white) // table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white) //New Equity curve var newcurve = array.new_float(0) var int ida = 0 var bool printEQ = false if newch !=0 array.push(newcurve, neweq) if bar_index > last_bar_index - array.size(newcurve) - 1 - 20 and array.size(newcurve) > 20 printEQ := true else printEQ := false plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2) if printEQ ida := ida + 1 if ida >= array.size(newcurve) and printEQ ida := array.size(newcurve) -1 //Original Equity curve var newcurve2 = array.new_float(0) var int ida2 = 0 var bool printEQ2 = false if ch !=0 array.push(newcurve2, eq) if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20 and array.size(newcurve2) > 20 printEQ2 := true else printEQ2 := false plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2) if printEQ2 ida2 := ida2 + 1 if ida2 >= array.size(newcurve2) and printEQ2 ida2 := array.size(newcurve2) -1 //Moving Average Array var marray = array.new_float(0) if ch array.push(marray, mova) plot(printEQ2 and array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1) hline(0,"0 line", color=color.black, linestyle = hline.style_dotted) if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20 l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left) label.delete(l[1]) f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left) label.delete(f[1])