모멘텀 로테이션을 기반으로 한 주식 전략


생성 날짜: 2023-09-19 22:14:24 마지막으로 수정됨: 2023-09-19 22:14:24
복사: 0 클릭수: 729
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

개요

이 전략은 동력 회전 방식을 채택하고, 스토흐 RSI 지표에 따라 시장 추세를 판단하여 주식 회전 거래를 실현한다. 지표가 과매매 할 때 적자를 표시하고, 과매매 할 때 더 많이 표시한다. 동시에 형 가장 포지션을 적용하여 추세 방향으로 포지션을 확대한다.

전략 원칙

  1. RSI를 계산하는 방법
  2. RSI를 기준으로 계산한 스토흐 RSI 지표는 스토카스틱 랭트는 14이고, 스무스 K는 3이고, 스무스 D는 1이다.
  3. 스토치 RSI가 초과 판매에서 초과 구매로 올라갈 때, 추가로 입점합니다.
  4. 스토치 RSI가 초고가에서 초고가로 내려오면, 코스피가 부실합니다.
  5. 형으로 최대 5번까지 매장합니다.
  6. 매번 상장 후 스톱로스를 설정하고 스톱로스를 추적합니다.
  7. 정지 손실이 발생했을 때 지분을 감축합니다.
  8. 스톱로스 및 트래킹 스톱로스에 따라 포지션을 관리합니다.

우위 분석

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

  1. 동력 지표 조작에 기반하여 시장 추세의 전환점을 포착하고 포지션 방향을 적시에 조정할 수 있다.
  2. 形加仓 (形加仓) 은 트렌드 초기에 포지션을 차지하고, 트렌드 확인 후 포지션을 확대하여 트렌드 수익을 충분히 포착할 수 있다.
  3. 위험을 조절하기 위해 스톱포드를 설정하고, 이니셜 스톱로스는 합리적인 범위 내에서 설정하고, 스톱로스는 수익을 유지하기 위해 추적한다.
  4. RSI 매개 변수 최적화 공간은 넓고, 다른 시장에 맞는 매개 변수를 조정하여 최적의 조합을 찾을 수 있다.
  5. 유연하게 매장 수, 깊이, 중지점 등의 파라미터를 조정할 수 있으며, 시장에 대한 강한 적응력을 가지고 있다.

위험 분석

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

  1. Stoch RSI는 유일한 지표로서, 급격한 사건에 대해 잘못된 신호를 유발할 수 있다. 다른 지표로도 확인 가능하다.
  2. 트렌드성이 강한 품종에만 적용되며, 가로판 흔들림 시장에는 적합하지 않다.
  3. 너무 많은 입금은 손실을 확대할 수 있다. 입금 깊이를 조절해야 한다.
  4. 정지점 설정이 불합리한 경우 과도한 정지가 발생할 수 있다. 시장에 따라 정지 파라미터를 조정해야 한다.
  5. 거래 비용 통제에 주의해야 한다. 너무 자주 거래하면 많은 수수료가 발생한다.

최적화 방향

이 전략은 다음과 같은 방향으로 최적화될 수 있습니다.

  1. RSI 파라미터를 최적화하여 최적의 Length를 찾습니다.
  2. K, D 사이클의 최적의 조합을 찾기 위해 스토흐 변수를 최적화한다.
  3. 다른 지표의 필터 신호를 추가하여 잘못된 거래를 피하십시오.
  4. 동적으로 매장 수를 조정하고, 시장에 따라 매장 깊이를 조정한다.
  5. 스톱포트 설정 논리를 최적화하여 스톱포트 비율을 낮추십시오.
  6. 포지션 관리 모듈을 추가하여 재원 관리 원칙에 따라 포지션을 제어합니다.
  7. 수수료 제어 모듈을 추가하여 과도한 거래 빈도를 제어합니다.

요약하다

이 전략은 전체적으로 성숙한 동력 회전 사고방식을 채택하고, Stoch 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)