모멘텀 로테이션 주식 거래 전략

저자:차오장, 날짜: 2023-09-19 22:14:24
태그:

전반적인 설명

이 전략은 스톡 RSI 지표를 기반으로 시장 트렌드를 결정하고 주식 회전 거래를 구현하기 위해 모멘텀 회전을 채택합니다. 지표가 과소매를 표시할 때 짧고 과소매를 표시할 때 길어집니다. 동시에 피라미드 거래를 사용하여 트렌드 방향으로 포지션 크기가 증가합니다.

전략 논리

  1. RSI를 14주기 길이로 계산합니다.
  2. 스톡스틱 길이가 14, 매끄러운 K 3, 매끄러운 D 1과 함께 스톡스틱 RSI를 기반으로 스톡스틱 RSI를 계산합니다.
  3. 주식 RSI가 과판에서 과구로 올라갈 때 길게 가십시오.
  4. 주식 RSI가 과잉 매입에서 과잉 판매로 떨어지면 단축
  5. 피라미드 트레이딩을 사용하여 5배까지 포지션을 추가합니다.
  6. 각 추가 후 손실 중지 및 후속 중지 설정
  7. 스톱 손실이 트리거되면 위치를 줄여
  8. 스톱 로스 및 트레일링 스톱을 기반으로 포지션을 관리합니다.

이점 분석

이 전략의 장점은 다음과 같습니다.

  1. 동력 지표에 기초하여 트렌드 반전을 적시에 파악하고 그에 따라 위치 방향을 조정할 수 있습니다.
  2. 피라미드 거래는 작은 규모의 초기 포지션을 취하고 트렌드가 확인되면 추가하여 트렌드 수익을 완전히 캡처 할 수 있습니다.
  3. 스톱 손실은 위험을 조절합니다. 초기 스톱은 잡음을 필터하고 후속 스톱은 이익을 잠금합니다.
  4. RSI 최적화 공간은 넓고, 매개 변수를 다른 시장에 맞게 조정할 수 있습니다.
  5. 유연한 추가 시간, 크기 및 정지, 다른 시장 조건에 잘 적응합니다.

위험 분석

주의해야 할 몇 가지 위험 요소:

  1. 스톡 RSI에만 의존하면 갑작스러운 사건에 취약해집니다. 다른 지표로 확인하세요.
  2. 트렌드가 강한 상품에만 적용됩니다. 부진한 시장을 피하십시오.
  3. 과도한 부수는 손실을 증폭시킬 수 있습니다.
  4. 잘못된 스톱 손실 설정은 오버 스톱을 일으킬 수 있습니다. 시장에 따라 스톱을 조정하십시오.
  5. 거래 비용을 모니터링합니다. 높은 주파수 거래는 높은 수수료를 발생시킵니다.

최적화 방향

전략을 최적화하는 몇 가지 방법:

  1. 가장 잘 맞는 RSI 길이 매개 변수를 최적화합니다.
  2. 더 부드러운 신호를 위해 Stoch K와 D 기간을 최적화하십시오.
  3. 신호를 필터하는 다른 지표를 추가하고 잘못된 거래를 피하십시오.
  4. 시장 조건에 따라 추가 시간을 동적으로 조정합니다.
  5. 스톱 로스 로직을 최적화하여 스톱 레이트를 낮추는 것
  6. 돈 관리에 기반한 위치 크기 모듈을 추가합니다.
  7. 고주파 거래를 제한하기 위해 수수료 통제를 포함합니다.

결론

이 전략은 성숙한 모멘텀 로테이션 개념을 채택하고 있으며, 주력 거래 지표로 스톡 RSI가 있으며, 피라미드 거래와 위험 통제를 위한 스톱 관리로 보완됩니다. 전략에 따른 신뢰할 수있는 추세입니다. 매개 변수 및 모듈에 대한 추가 최적화는 안정성과 적응력을 향상시킬 수 있습니다. 그러나 전반적으로 이미 강력한 실제 거래 능력을 가지고 있습니다.


/*backtest
start: 2023-09-11 00:00:00
end: 2023-09-13 13:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This script was created for educational purposes only.
// © mcristianrios

// FEEL FREE TO DROP A COMMENT AND A LIKE IF YOU USE IT OR IT SERVES YOU WELL

//@version=4
//strategy(title="Pyramiding Strategy To Study [mcristianrios]", commission_type=strategy.commission.cash_per_contract, commission_value=0.0002, overlay=true, default_qty_value=1000, initial_capital=100, calc_on_order_fills=false, currency="USD", overlay=true, pyramiding=5)
// study(title="Pyramiding Strategy To Study [mcristianrios]", overlay=true)

int pyramiding            = input(1,  'Pyramiding', minval=1, maxval=5)
int slPips                = input(80, 'SL Pips')
int ttPips                = input(60, 'Trail Trig')
int trailOffset           = input(60, 'Trail Offset')

// === PYRAMIDING DECLARATION === {
var int   longPyramiding  = 0
var int   shortPyramiding = 0

// To save init of operation price
var float close1          = na
var float close2          = na
var float close3          = na
var float close4          = na
var float close5          = na

// How far did the Trailing Stop Get?
var float far1            = na
var float far2            = na
var float far3            = na
var float far4            = na
var float far5            = na
// }

// === STOCHASTIC RSI === {
smoothK                   = input(3, minval=1)
smoothD                   = input(1, minval=1)
lengthRSI                 = input(14, minval=1)
lengthStoch               = input(14, minval=1)
src                       = input(close, title="RSI Source")

rsi1                      = rsi(src, lengthRSI)
k                         = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d                         = sma(k, smoothD)
// }

// === SOME CONDITION TO TAKE A POSITION === {
goLong  = k[1] < 80 and k >= 80 and longPyramiding  < pyramiding
goShort = k[1] > 20 and k <= 20 and shortPyramiding < pyramiding
// }

// === PYRAMIDING SIMULATION === {
var string lastOperation = ''
if (goLong  and lastOperation != 'LONG') or (goShort and lastOperation != 'SHORT')
    // RESET
    longPyramiding           := 0
    shortPyramiding          := 0
    far1                     := na
    far2                     := na
    far3                     := na
    far4                     := na
    far5                     := na
    close1                   := na
    close2                   := na
    close3                   := na
    close4                   := na
    close5                   := na

// === SUM ONE INTO 'LONG' OR 'SHORT' PYRAMIDING AND REMEMBER LAST OPERATION TYPE === {
isCallOrShort = if goLong and longPyramiding < pyramiding
    lastOperation := 'LONG'
    longPyramiding := longPyramiding + 1

    true
else
    isShort = if goShort and shortPyramiding < pyramiding
        lastOperation := 'SHORT'
        shortPyramiding := shortPyramiding + 1

        true
    else
        false

    isShort
// }

// === SAVE CURRENT PRICE === {
if isCallOrShort
    if na(close1)
        close1 := close
    else
        if na(close2)
            close2 := close
        else
            if na(close3)
                close3 := close
            else
                if na(close4)
                    close4 := close
                else
                    if na(close5)
                        close5 := close
// }

if longPyramiding > 0
    // If Trail Stop was not triggered and distance is achieved saved it
    if na(far1) and high > close1 + syminfo.mintick * 10 * ttPips
        far1 := high
    if na(far2) and high > close2 + syminfo.mintick * 10 * ttPips
        far2 := high
    if na(far3) and high > close3 + syminfo.mintick * 10 * ttPips
        far3 := high
    if na(far4) and high > close4 + syminfo.mintick * 10 * ttPips
        far4 := high
    if na(far5) and high > close5 + syminfo.mintick * 10 * ttPips
        far5 := high
    
    // Update how far our position went
    if not na(far1) and high > far1
        far1 := high
    if not na(far2) and high > far2
        far2 := high
    if not na(far3) and high > far3
        far3 := high
    if not na(far4) and high > far4
        far4 := high
    if not na(far5) and high > far5
        far5 := high
        
    /// === SL not na(trailing stop) ? Use Trailing Stop : Use Default Stop Loss === {
    if not na(close1) and (not na(far1) ? low <= far1 - syminfo.mintick * 10 * trailOffset : low <= close1 - syminfo.mintick * 10 * slPips)
        longPyramiding := longPyramiding - 1
        close1         := na
        far1           := na
    if not na(close2) and (not na(far2) ? low <= far2 - syminfo.mintick * 10 * trailOffset : low <= close2 - syminfo.mintick * 10 * slPips)
        longPyramiding := longPyramiding - 1
        close2         := na
        far2           := na
    if not na(close3) and (not na(far3) ? low <= far3 - syminfo.mintick * 10 * trailOffset : low <= close3 - syminfo.mintick * 10 * slPips)
        longPyramiding := longPyramiding - 1
        close3         := na
        far3           := na
    if not na(close4) and (not na(far4) ? low <= far4 - syminfo.mintick * 10 * trailOffset : low <= close4 - syminfo.mintick * 10 * slPips)
        longPyramiding := longPyramiding - 1
        close4         := na
        far4           := na
    if not na(close5) and (not na(far5) ? low <= far5 - syminfo.mintick * 10 * trailOffset : low <= close5 - syminfo.mintick * 10 * slPips)
        longPyramiding := longPyramiding - 1
        close5         := na
        far5           := na
    // }

// Log when long pyramiding changed
if longPyramiding[1] != longPyramiding[2]
    label.new(bar_index, high, tostring(longPyramiding[1]), xloc.bar_index, yloc.price, size = size.normal, color=color.blue, textcolor=color.white)

if shortPyramiding > 0
    // If Trail Stop was not triggered and distance is achieved saved it
    if na(far1) and low < close1 - syminfo.mintick * 10 * ttPips
        far1 := low
    if na(far2) and low < close2 - syminfo.mintick * 10 * ttPips
        far2 := low
    if na(far3) and low < close3 - syminfo.mintick * 10 * ttPips
        far3 := low
    if na(far4) and low < close4 - syminfo.mintick * 10 * ttPips
        far4 := low
    if na(far5) and low < close5 - syminfo.mintick * 10 * ttPips
        far5 := low
    
    // Update how far our position went
    if not na(far1) and low < far1
        far1 := low
    if not na(far2) and low < far2
        far2 := low
    if not na(far3) and low < far3
        far3 := low
    if not na(far4) and low < far4
        far4 := low
    if not na(far5) and low < far5
        far5 := low
        
    /// === SL not na(trailing stop) ? Use Trailing Stop : Use Default Stop Loss === {
    if not na(close1) and (not na(far1) ? high >= far1 + syminfo.mintick * 10 * trailOffset : high >= close1 + syminfo.mintick * 10 * slPips)
        shortPyramiding := shortPyramiding - 1
        close1          := na
        far1            := na
    if not na(close2) and (not na(far2) ? high >= far2 + syminfo.mintick * 10 * trailOffset : high >= close2 + syminfo.mintick * 10 * slPips)
        shortPyramiding := shortPyramiding - 1
        close2          := na
        far2            := na
    if not na(close3) and (not na(far3) ? high >= far3 + syminfo.mintick * 10 * trailOffset : high >= close3 + syminfo.mintick * 10 * slPips)
        shortPyramiding := shortPyramiding - 1
        close3          := na
        far3            := na
    if not na(close4) and (not na(far4) ? high >= far4 + syminfo.mintick * 10 * trailOffset : high >= close4 + syminfo.mintick * 10 * slPips)
        shortPyramiding := shortPyramiding - 1
        close4          := na
        far4            := na
    if not na(close5) and (not na(far5) ? high >= far5 + syminfo.mintick * 10 * trailOffset : high >= close5 + syminfo.mintick * 10 * slPips)
        shortPyramiding := shortPyramiding - 1
        close5          := na
        far5            := na
    // }

// Log when long pyramiding changed
if shortPyramiding[1] != shortPyramiding[2]
    label.new(bar_index, high + syminfo.mintick * 10 * 22, tostring(shortPyramiding[1]), xloc.bar_index, yloc.price, size = size.normal, color=color.red, textcolor=color.white)
// }

// === COMMENT IF STUDY === {
strategy.entry("Long",  strategy.long,  when = goLong  and longPyramiding  <= pyramiding)
strategy.entry("Short", strategy.short, when = goShort and shortPyramiding <= pyramiding)

strategy.exit("Exit Long",  "Long",  loss=slPips * 10, trail_points=ttPips * 10, trail_offset=trailOffset * 10)
strategy.exit("Exit Short", "Short", loss=slPips * 10, trail_points=ttPips * 10, trail_offset=trailOffset * 10)
// }

// === UNCOMMENT IF STUDY === {
// plot(ttPips,      title='TrailTrig',   color=na, display=display.none)
// plot(trailOffset, title='TrailOffset', color=na, display=display.none)
// plot(slPips,      title='LossPips',    color=na, display=display.none)

// string longTradeId     = 'tradeid=long{{ticker}}_PYRAMIDING_[MCRISTIANRIOS]'
// string shortTradeId    = 'tradeid=short{{ticker}}_PYRAMIDING_[MCRISTIANRIOS]'
// string basicTrade      = 'tradesymbol={{ticker}} sl={{plot("LossPips")}} trailtrig={{plot("TrailTrig")}} traildist={{plot("TrailOffset")}}'

// alertcondition(goLong  and longPyramiding  <= pyramiding, title='Long',   message='long '  + basicTrade + ' ' + longTradeId)
// alertcondition(goShort and shortPyramiding <= pyramiding, title='Short',  message='short ' + basicTrade + ' ' + shortTradeId)

// alertcondition(goLong  and longPyramiding  <= pyramiding, title='XShort', message='closepart part=1 ' + shortTradeId)
// alertcondition(goShort and shortPyramiding <= pyramiding, title='XLong',  message='closepart part=1 ' + longTradeId)
// }

// Background color for backtest
bgcolor(goLong[1] ? color.lime : goShort[1] ? color.red : na, transp=70)


더 많은