다중 요인 전략


생성 날짜: 2023-10-31 15:45:39 마지막으로 수정됨: 2023-10-31 15:45:39
복사: 0 클릭수: 709
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

다중 요인 전략

개요

다중 요소 전략은 충격형 전략, 트렌드 추적 전략 및 돌파형 전략의 세 가지 다른 유형의 전략을 결합하여 조합하여 더 나은 전략 효과를 얻습니다.

전략 원칙

다인자 전략은 주로 다음과 같은 요소에 기반하여 모델링됩니다.

  • 흔들림 전략은 구매와 판매의 타이밍을 판단하기 위해 무작위 지표를 사용합니다. 특히, 무작위 지표 %K 라인이 과매도 영역에서 %D 라인을 통과할 때 구매 신호를 생성합니다. %K 라인이 과매도 영역에서 %D 라인을 통과할 때 판매 신호를 생성합니다.

  • 트렌드 전략은 부분적으로 SMA 평균선의 황금 교차선을 사용하여 트렌드 방향을 판단한다. 빠른 선이 아래에서 느린 선을 통과하면 구매 신호가 발생하고 빠른 선이 위에서 아래로 느린 선을 통과하면 판매 신호가 발생한다.

  • 브레이크 전략은 가격이 지정된 주기 내의 최고 가격이나 최저 가격을 뚫었는지 모니터링합니다. 가격이 최고 가격을 초과했을 때 구매; 가격이 최저 가격보다 낮았을 때 판매합니다.

  • 트렌드 강도를 판단하기 위해 ADX 지표와 결합하여, 트렌드가 충분히 강할 때만 트렌드 거래에 참여하십시오.

  • 정지선과 정지선을 설정하고, 합리적인 정지 비율을 설정한다.

이 부분들을 종합하여, 다중 요소 전략은 다음과 같은 논리를 주로 따르고 있습니다:

  1. ADX가 설정된 지름값보다 크면, 트렌드가 충분히 강하다고 생각하면, 트렌드 전략을 실행하기 시작합니다. ADX가 지름값보다 작으면, 정리되어 있다고 생각하면, 오스트레일리아 전략만 실행합니다.

  2. 동향상태에서, SMA 빠른 느린 선 금이 교차할 때 입점을 구입하고, 사다리가 죽으면 평점을 입점한다.

  3. 동요의 상황에서는 무작위 지표의 거래 신호를 실행한다.

  4. 두 가지 시장 환경 모두에서 통로를 추적하는 데 사용된 돌파구 전략이다.

  5. 스톱로스 스톱을 설정하여 수익을 최적화하십시오.

우위 분석

다인자 전략의 가장 큰 장점은 서로 다른 유형의 전략을 결합하여 두 가지 시장 환경에서 더 나은 전략 효과를 얻을 수 있다는 것입니다. 구체적으로 다음과 같은 장점이 있습니다.

  1. 트렌드에 따라 움직일 수 있고, 트렌드 상황에서 더 높은 승률을 얻을 수 있다.

  2. 이 회사는 “이런 종류의 투자에 투자하는 것은 매우 효과적입니다.

  3. 높은 수익 인수, 합리적인 스톱 스톱 손실 설정.

  4. “이런 일이 벌어진다면, 우리는 더 큰 손실을 볼 수 있을 것이다.

  5. 여러 지표가 결합되어 강력한 거래 신호를 형성할 수 있습니다.

  6. 변수 최적화를 통해 더 좋은 변수 조합을 얻을 수 있다.

위험 분석

다중 요인 전략에는 다음과 같은 위험도 있습니다.

  1. 여러 요소의 부적절한 조합은 거래 신호 혼란을 초래할 수 있으며, 최적의 요소 조합을 찾기 위해 반복적으로 테스트가 필요합니다.

  2. 여러 파라미터를 최적화해야 하며, 최적화가 더 어렵고, 충분한 역사적 데이터의 지원이 필요합니다.

  3. 동향이 역전될 때, 적당한 시간 내에 상쇄하지 못하면 큰 손실이 발생할 수 있다.

  4. ADX 지표는 추세 전환점을 놓칠 수 있습니다.

  5. 은 거래는 쉽게 잡힐 수 있으며, 합리적인 스톱 손실 전략이 필요합니다.

위와 같은 위험들을 고려하여, 다음의 몇 가지 측면에서 최적화할 수 있습니다.

  1. 역사 데이터에서 다른 요소의 안정성을 테스트하고 안정성을 선택한다.

  2. 유전적 알고리즘과 같은 지능적 최적화 방법을 사용하여 최적의 변수를 찾습니다.

  3. 최대 회수량을 제어하기 위해 합리적인 스톱 라인을 설정하십시오.

  4. 추세 전환을 판단하는 부가적인 지표와 함께.

  5. 거래의 손실을 방지하기 위한 최적화된 전략.

최적화 방향

다중 요소 전략은 더 많은 최적화를 할 수 있습니다.

  1. 더 많은 유형의 요소를 테스트하여 더 나은 조합을 찾습니다. 변동률, 교류량과 같은 다른 요소를 고려할 수 있습니다.

  2. 최적의 전략의 무게를 찾아내기 위한 기계학습 방법

  3. 매개 변수 최적화는 지능형 알고리즘을 사용하여 빠르게 최적화를 찾을 수 있다.

  4. 다른 기간 동안의 수익을 테스트할 수 있다.

  5. 동적으로 스톱 라인을 조정하는 것을 고려할 수 있다.

  6. 더 많은 필터링 조건을 도입할 수 있습니다. 예를 들어, 트래픽 급증과 같은 신호 품질을 향상시킬 수 있습니다.

  7. ADX 지표는 최적화 매개 변수를 고려하거나 더 고급 트렌드 판단 지표로 대체할 수 있다.

요약하다

다인자 전략은 종합적으로 트렌드, 흔들림, 돌파 등 여러 가지 거래 논리를 고려하여 두 가지 시장 환경에서 우수한 효과를 얻을 수 있습니다. 단일 전략에 비해 다인자 전략은 더 높은 안정적인 수익을 얻을 수 있으며, 좋은 업그레이드 확장 공간을 가지고 있습니다. 그러나 매개 변수 최적화가 더 어렵고, 최적화 과정을 지원하는 충분한 역사적 데이터가 필요합니다.

전략 소스 코드
/*backtest
start: 2023-09-30 00:00:00
end: 2023-10-30 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

// strategy("Strategy_1", shorttitle="Strategy1",overlay=true ,pyramiding = 12, initial_capital=25000, currency='EUR', commission_type = strategy.commission.cash_per_order, commission_value = 3, default_qty_type = strategy.percent_of_equity, default_qty_value = 20)
	
// Revision:        1
// Author:          Jonas

// === INPUT ===
    //   > BACKTEST RANGE <
FromMonth = input(defval=1, title="From Month", minval=1, maxval=12)
FromDay = input(defval=1, title="From Day", minval=1, maxval=31)
FromYear = input(defval=2017, title="From Year", minval=2010)
ToMonth = input(defval=1, title="To Month", minval=1, maxval=12)
ToDay = input(defval=1, title="To Day", minval=1, maxval=31)
ToYear = input(defval=9999, title="To Year", minval=2010)

    //   > STRATEGY SETTINGS <
bolOS = input(defval = false, type=input.bool, title="Oscillating Strategy")
bolTS = input(defval = true, type=input.bool, title="Trend Strategy")
bolBO = input(defval = false, type=input.bool, title="Breakout Strategy")

strStrategy = input(defval = "Long", type=input.string, title="Trade Strategy",options = ["Long", "Short","Long & Short"])

flStopLoss = input(defval = 2.0, title="Stop Loss %", type=input.float)/100
flTakeProfit = input(defval = 4.0, title="Take Profit %", type=input.float)/100

    //   > SMA <

fastMA = input(defval=8, type=input.integer, title="FastMA length", minval=1, step=1)
slowMA = input(defval=21, type=input.integer, title="SlowMA length", minval=1, step=1)

    //  > ADX <
adx_len = input(defval=10, type=input.integer, title="ADX length", minval=1, step=1)
adx_trend = input(defval=30, type=input.integer, title="ADX Tr", minval=1, step=1)
adx_choppy = adx_trend
adx_limit = adx_trend

    //  > TRENDSCORE <
ts_fromIndex = input(title="From", type=input.integer, minval=1, defval=10)
ts_toIndex = input(title="To", type=input.integer, minval=1, defval=14)
ts_src = input(title="Source", type=input.source, defval=close)

    // > Oscillator <
stoch_length = 14
stoch_OverBought = 75
stoch_OverSold = 25
stoch_smoothK = 3
stoch_smoothD = 3

// === BACK TEST RANGE FUNCTION ===
window_start = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
window_finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)  // backtest finish window
window() =>  // create function "within window of time"
    time >= window_start and time <= window_finish ? true : false

//plot(stop_level_Long, title="TEST",color=color.red, style=plot.style_linebr, linewidth=2)
//plot(take_level_Long, color=color.green, style=plot.style_linebr, linewidth=2)

// === ADX ===
adx_up = change(high)
adx_down = -change(low)
adx_trur = rma(tr, adx_len)
adx_plus = fixnan(100 * rma(adx_up > adx_down and adx_up > 0 ? adx_up : 0, adx_len) / adx_trur)
adx_minus = fixnan(100 * rma(adx_down > adx_up and adx_down > 0 ? adx_down : 0, adx_len) / adx_trur)
adx_sum = adx_plus + adx_minus

ADX = 100 * rma(abs(adx_plus - adx_minus) / (adx_sum == 0 ? 1 : adx_sum), adx_len)

//=== TRENDSCORE ===
trendscore(ts_src, ts_fromIndex, ts_toIndex) =>
	ts_sum = 0.0
	for i = ts_fromIndex to ts_toIndex
        ts_sum := ts_sum + (ts_src >= nz(ts_src[i]) ? 1 : -1)
    ts_sum

intTS = trendscore(ts_src, ts_fromIndex, ts_toIndex)
// Long if  TrendDirection = 1, Short if TrendDirection = -1; Indifferent if TrendDirection = 0
intTrendDirection = (intTS > (ts_toIndex-ts_fromIndex)) ? 1 : (intTS < (ts_fromIndex-ts_toIndex)) ? -1 : 0

    //  > TREND CONDITION <
adx_growing = ADX > highest(ADX[1],3)
intTrend = ((ADX >= adx_limit) and (ADX[1] >= adx_limit) and adx_growing) ? intTrendDirection : 0

// === ATR ===
ATR = sma(tr,10)
ATR_100 = ATR /abs(high - low)


// === STOCHASTICS ===

stoch_k = sma(stoch(close, high, low, stoch_length), stoch_smoothK)
stoch_d = sma(stoch_k, stoch_smoothD)

// === FILTER & CONDITIONS ===
    //  > STOCHASTICS <
bolFilter_OS1 = close[1] > hl2[1]



bolSigOsc_long_1 = (na(stoch_k) or na(stoch_d)) ? false : (crossover(stoch_d,stoch_OverSold) and stoch_k > stoch_d) ? true:false
bolSigOsc_short_1 = (na(stoch_k) or na(stoch_d)) ? false : (crossunder(stoch_d,stoch_OverBought) and stoch_k < stoch_d) ? true:false

bolLongOpenOS = bolSigOsc_long_1 and bolFilter_OS1
bolLongCloseOS = bolSigOsc_short_1

bolShortOpenOS = bolSigOsc_short_1 and bolFilter_OS1
bolShortCloseOS = bolSigOsc_long_1

    //  > TREND <

bolFilter_TS1 = close[1] > hl2[1] and open[1] < hl2[1]
bolFilter_TS2 = sma(close,50)>sma(close,50)[10]
bolFilter_TS3 = close[1] < hl2[1] and open[1] > hl2[1]

bolSigTrendLO1 = sma(close, fastMA) > sma(close, slowMA)
bolSigTrendLO2 = close > sma(close,fastMA)
bolSigTrendLO3 = bolSigTrendLO1 and bolSigTrendLO2

bolSigTrendLC1 = sma(close, fastMA) < sma(close, slowMA)
bolSigTrendLC2 = close < sma(close, fastMA)
bolSigTrendLC3 = bolSigTrendLC1 and bolSigTrendLC2

bolSigTrendSO1 = bolSigTrendLC3
bolSigTrendSC1 = bolSigTrendLO1

bolLongOpenTS = bolSigTrendLO3 and bolFilter_TS1
bolLongCloseTS = bolSigTrendLC3 and bolFilter_TS3

bolShortOpenTS = bolSigTrendSO1 and bolFilter_TS3
bolShortCloseTS = bolLongOpenTS and bolFilter_TS1

plot(sma(close, fastMA), title='FastMA', color=color.green, linewidth=2, style=plot.style_line)  // plot FastMA
plot(sma(close, slowMA), title='SlowMA', color=color.red, linewidth=2, style=plot.style_line)  // plot SlowMA



    //  > BREAKOUT <
flFilter_BS1 = 0.5 * stdev(close,slowMA)[1]
bolFilter_BS2 = volume > sma(volume,slowMA)*1.25

bolSigBreakoutLO1 = close > (highestbars(high,slowMA)[1] + flFilter_BS1)
bolSigBreakoutLC1 = barssince(bolSigBreakoutLO1)==5

bolSigBreakoutSO1 = close < lowestbars(low,slowMA)[1] - flFilter_BS1
bolSigBreakoutSC1 = barssince(bolSigBreakoutSO1)==5


bolLongOpenBO = bolSigBreakoutLO1 and bolFilter_BS2
bolLongCloseBO = bolSigBreakoutLC1

bolShortOpenBO = bolSigBreakoutSO1 and bolFilter_BS2
bolShortCloseBO = bolSigBreakoutSC1

//=== STRATEGIES ENTRIES & EXITS ===
    //  > STOPS & LIMITS <
stop_level_Long = strategy.position_avg_price * (1 - flStopLoss)
take_level_Long = strategy.position_avg_price * (1 + flTakeProfit)
stop_level_Short = strategy.position_avg_price * (1 + flStopLoss)
take_level_Short = strategy.position_avg_price * (1 - flTakeProfit)

    //  > ENTRIES / CLOSES / EXITS <
if window() //only in backtest-window
    if (bolOS == true)
        if (intTrend == 0)
            if(strStrategy == "Long" or strStrategy == "Long & Short")
                strategy.entry("Lng Osc", strategy.long, when=bolLongOpenOS)  // buy long when "within window of time" AND crossover
            if(strStrategy == "Short" or strStrategy == "Long & Short")
                strategy.entry("Short Osc", strategy.short, when=bolShortOpenOS)
        strategy.close("Lng Osc", when=(bolLongCloseOS))
        //strategy.exit("Exit L OS/STD", "Lng Osc", stop = strategy.position_avg_price - 2*stdev(close,10))
        strategy.exit("Exit L OS/%", "Lng Osc", stop=stop_level_Long)
        strategy.close("Short Osc", when=(bolShortCloseOS))
        //strategy.exit("Exit S OS/STD", "Short Osc", stop = strategy.position_avg_price + 2*stdev(strategy.position_avg_price,10))
        strategy.exit("Exit S OS/%", "Short Osc", stop=stop_level_Short)
    if (bolTS == true)
        if (not(intTrend == 0))
            if((strStrategy == "Long") or (strStrategy == "Long & Short"))
                strategy.entry("Lng TD", strategy.long, when=bolLongOpenTS)  // buy long when "within window of time" AND crossover
            if((strStrategy == "Short") or (strStrategy == "Long & Short"))
                strategy.entry("Short TD", strategy.short, when=(bolShortOpenTS and bolTS))  // buy long when "within window of time" AND crossover
        strategy.exit("Exit L TD", "Lng TD", stop=stop_level_Long)
        strategy.close("Lng TD", when=bolLongCloseTS)
        strategy.exit("Exit S TD", "Short TD", stop=stop_level_Short)
        strategy.close("Short TD", when=bolShortCloseTS)
    if (bolBO == true)
        if((strStrategy == "Long") or (strStrategy == "Long & Short"))
            strategy.entry("Lng BO", strategy.long, when=bolLongOpenBO)  // buy long when "within window of time" AND crossover
            strategy.close("Lng BO", when=bolLongCloseBO)
            //strategy.exit("Exit L BO/STD", "Lng BO", stop = strategy.position_avg_price - 2*stdev(strategy.position_avg_price,10))
            strategy.exit("Exit L BO/2.5%", "Lng BO", stop=stop_level_Long)
        if((strStrategy == "Short") or (strStrategy == "Long & Short"))
            strategy.entry("Short BO", strategy.short, when=bolShortOpenBO)  // buy long when "within window of time" AND crossover
            strategy.close("Short BO", when=bolShortCloseBO)
            //strategy.exit("Exit S BO/STD", "Short BO", stop = strategy.position_avg_price - 2*stdev(strategy.position_avg_price,10))
            strategy.exit("Exit S BO/%", "Short BO", stop=stop_level_Short)