다중 요인 회귀 및 동적 가격대 전략에 기반한 양적 거래 시스템

RSI ATR BETA SMA
생성 날짜: 2025-01-17 15:57:53 마지막으로 수정됨: 2025-01-17 15:57:53
복사: 0 클릭수: 373
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

다중 요인 회귀 및 동적 가격대 전략에 기반한 양적 거래 시스템

개요

이 전략은 다중 요인 회귀와 역동적인 가격 범위를 기반으로 하는 양적 거래 시스템입니다. 핵심 논리는 다중 요인 회귀 모델을 통해 가격 추세를 예측하고 BTC 지배력, 거래량, 지연된 가격 등 여러 시장 요인을 결합하여 신호 생성을 위한 상한 및 하한 가격 대역을 구성하는 것입니다. 이 전략은 이상치 필터링, 동적 포지션 관리, 이동식 손절매와 같은 여러 위험 관리 모듈을 통합합니다. 포괄적이고 강력한 거래 시스템입니다.

전략 원칙

이 전략에는 주로 다음과 같은 핵심 구성 요소가 포함됩니다.

  1. 회귀 예측 모듈: 다중 요인 선형 회귀 모델을 사용하여 가격을 예측합니다. 요인에는 BTC 지배력, 거래량, 가격 지연 조건, 상호 작용 조건 등이 있습니다. 각 요인의 베타 계수는 가격에 미치는 영향을 측정하기 위해 계산됩니다.
  2. 동적 가격 대역: 예측 가격과 잔여 표준 편차를 기반으로 상한 및 하한 가격 대역을 구성하여 매수 과다 및 매도 과다 가격을 파악합니다.
  3. 신호 생성: 롱 신호는 가격이 하단 밴드를 돌파하고 RSI가 매도 과다일 때 생성됩니다. 숏 신호는 가격이 상단 밴드를 돌파하고 RSI가 매수 과다일 때 생성됩니다.
  4. 위험 관리: 이상치 필터링(Z 점수 방법), 손절매 및 이익 실현, ATR 이동 손절매 및 기타 여러 보호 메커니즘을 포함합니다.
  5. 동적 포지션: ATR과 사전 설정된 위험 비율에 따라 오픈 포지션 크기를 동적으로 조정합니다.

전략적 이점

  1. 다중 요소 통합: 포괄적인 시장 관점을 제공하기 위해 여러 시장 요소를 종합적으로 고려합니다.
  2. 강력한 적응성: 가격대는 다양한 시장 환경에 적응하기 위해 시장 변동에 따라 동적으로 조정됩니다.
  3. 완벽한 위험 관리: 다단계 위험 관리를 통해 자금의 안전을 보장합니다.
  4. 유연하고 구성 가능: 많은 매개변수를 조정할 수 있어 다양한 시장 특성에 따라 쉽게 최적화할 수 있습니다.
  5. 높은 신호 안정성: 다양한 필터링 메커니즘으로 신호 품질이 향상됩니다.

전략적 위험

  1. 모델 위험: 회귀 모델은 과거 데이터에 의존하기 때문에 시장이 급격하게 변화하면 실패할 수 있습니다.
  2. 매개변수 민감도: 많은 매개변수를 신중하게 조정해야 하며, 부적절한 매개변수 설정은 전략 성과에 영향을 미칩니다.
  3. 계산 복잡성: 다중 요소 계산은 더 복잡하며 실시간 성능에 영향을 미칠 수 있습니다.
  4. 시장 환경 의존성: 추세 시장보다 변동성이 큰 시장에서 더 나은 성과를 거둘 수 있습니다.

전략 최적화 방향

  1. 요인 선택 최적화: 시장 감정 지표, 온체인 데이터 등 더 많은 시장 요인을 도입할 수 있습니다.
  2. 동적 매개변수 조정: 전략 적응성을 개선하기 위해 적응형 매개변수 조정 메커니즘을 개발합니다.
  3. 머신 러닝 강화: 예측 모델을 최적화하기 위한 머신 러닝 방법을 소개합니다.
  4. 신호 필터링 강화: 정확도를 높이기 위해 더 많은 신호 필터링 조건을 개발했습니다.
  5. 조합 전략 통합: 다른 전략과 함께 사용하여 안정성을 향상시킵니다.

요약하다

이 전략은 견고한 이론과 완벽한 설계를 갖춘 양적 거래 시스템입니다. 다중 요인 회귀 모델을 통해 가격을 예측하고, 역동적인 가격 대역을 기반으로 거래 신호를 생성하며, 포괄적인 위험 관리 메커니즘을 갖추세요. 이 전략은 매우 적응성과 구성성이 뛰어나 다양한 시장 환경에 적합합니다. 이 전략은 지속적인 최적화와 개선을 통해 실제 거래에서 안정적인 수익을 달성할 것으로 기대됩니다.

전략 소스 코드
/*backtest
start: 2024-12-17 00:00:00
end: 2025-01-16 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":49999}]
*/

//@version=5
strategy(  title           = "CorrAlgoX", overlay         = true,pyramiding      = 1, initial_capital = 10000, default_qty_type= strategy.percent_of_equity, default_qty_value=200)

//====================================================================
//=========================== GİRİŞLER ================================
//====================================================================

// --- (1) REGRESYON VE OUTLIER AYARLARI
int   lengthReg         = input.int(300, "Regression Window",   minval=50)
bool  useOutlierFilter  = input.bool(false, "Z-skoru ile Outlier Filtrele")

// --- (2) FİYAT GECİKMELERİ
bool  usePriceLag2      = input.bool(false, "2 Bar Gecikmeli Fiyatı Kullan")

// --- (3) STOP-LOSS & TAKE-PROFIT
float stopLossPerc      = input.float(3.0,  "Stop Loss (%)",   step=0.1)
float takeProfitPerc    = input.float(5.0,  "Take Profit (%)", step=0.1)

// --- (4) REZİDÜEL STD BANTI
int   lengthForStd      = input.int(50, "StdDev Length (residual)", minval=2)
float stdevFactor       = input.float(2.0, "Stdev Factor", step=0.1)

// --- (5) RSI FİLTRESİ
bool  useRsiFilter      = input.bool(true, "RSI Filtresi Kullan")
int   rsiLen            = input.int(14, "RSI Length",   minval=1)
float rsiOB             = input.float(70, "RSI Overbought", step=1)
float rsiOS             = input.float(30, "RSI Oversold",   step=1)

// --- (6) TRAILING STOP
bool  useTrailingStop   = input.bool(false, "ATR Tabanlı Trailing Stop")
int   atrLen            = input.int(14, "ATR Length",   minval=1)
float trailMult         = input.float(1.0, "ATR multiplier", step=0.1)

// --- (7) DİNAMİK POZİSYON BÜYÜKLÜĞÜ (ATR tabanlı)
bool  useDynamicPos     = input.bool(false, "Dinamik Pozisyon Büyüklüğü Kullan")
float capitalRiskedPerc = input.float(1.0, "Sermaye Risk Yüzdesi", step=0.1, tooltip="Her işlemde risk alınacak sermaye yüzdesi")

// --- (8) ETKİLEŞİM VE LOG(HACİM) KULLANIMI
bool  useSynergyTerm    = input.bool(true, "BTC.D * Hacim Etkileşim Terimi")
bool  useLogVolume      = input.bool(true, "Hacmi Logaritmik Kullan")

//====================================================================
//======================= VERİLERİ AL & HAZIRLA =======================
//====================================================================

// Mevcut enstrüman fiyatı
float realClose = close

// BTC Dominance (aynı TF)
float btcDom    = request.security("SWAP", timeframe.period, close)

// Hacim
float vol       = volume

// Gecikmeli fiyatlar
float priceLag1 = close[1]
float priceLag2 = close[2]  // (isteğe bağlı)

//----------------- Outlier Filtrelemesi (Z-Skoru) ------------------//
float priceMean  = ta.sma(realClose, lengthReg)
float priceStdev = ta.stdev(realClose, lengthReg)

float zScore     = (priceStdev != 0) ? (realClose - priceMean) / priceStdev : 0
bool  isOutlier  = math.abs(zScore) > 3.0

float filteredClose = (useOutlierFilter and isOutlier) ? na : realClose

// Fiyatın stdev'i (filtrelenmiş)
float fCloseStdev = ta.stdev(filteredClose, lengthReg)

//====================================================================
//=============== ORTALAMA, STDEV, KORELASYON HESAPLARI ==============
//====================================================================

// BTC.D
float btcDomMean    = ta.sma(btcDom, lengthReg)
float btcDomStdev   = ta.stdev(btcDom, lengthReg)
float corrBtcDom    = ta.correlation(btcDom, filteredClose, lengthReg)

// Hacim
float volMean       = ta.sma(vol, lengthReg)
float volStdev      = ta.stdev(vol, lengthReg)
float corrVol       = ta.correlation(vol, filteredClose, lengthReg)

// Fiyat Lag1
float plag1Mean     = ta.sma(priceLag1, lengthReg)
float plag1Stdev    = ta.stdev(priceLag1, lengthReg)
float corrPLag1     = ta.correlation(priceLag1, filteredClose, lengthReg)

// Fiyat Lag2 (isteğe bağlı)
float plag2Mean     = ta.sma(priceLag2, lengthReg)
float plag2Stdev    = ta.stdev(priceLag2, lengthReg)
float corrPLag2     = ta.correlation(priceLag2, filteredClose, lengthReg)

// BTC.D * Hacim (synergyTerm)
float synergyTerm   = btcDom * vol
float synergyMean   = ta.sma(synergyTerm, lengthReg)
float synergyStdev  = ta.stdev(synergyTerm, lengthReg)
float corrSynergy   = ta.correlation(synergyTerm, filteredClose, lengthReg)

// Log(Hacim)
float logVolume     = math.log(vol + 1.0)
float logVolMean    = ta.sma(logVolume, lengthReg)
float logVolStdev   = ta.stdev(logVolume, lengthReg)
float corrLogVol    = ta.correlation(logVolume, filteredClose, lengthReg)

//====================================================================
//===================== FONKSIYON: BETA HESAPLAMA =====================
//====================================================================
// Pine Script'te fonksiyonlar şöyle tanımlanır (tip bildirmeyiz):
getBeta(corrVal, stdevX) =>
    (stdevX != 0 and not na(corrVal) and fCloseStdev != 0)? corrVal * (fCloseStdev / stdevX)  : 0.0

//====================================================================
//======================== BETA KATSAYILARI ===========================
//====================================================================

// BTC Dominance
float betaBtcDom  = getBeta(corrBtcDom,  btcDomStdev)
// Hacim
float betaVol     = getBeta(corrVol,     volStdev)
// Fiyat Lag1
float betaPLag1   = getBeta(corrPLag1,   plag1Stdev)
// Fiyat Lag2
float betaPLag2   = getBeta(corrPLag2,   plag2Stdev)
// synergy
float betaSynergy = getBeta(corrSynergy, synergyStdev)
// logVol
float betaLogVol  = getBeta(corrLogVol,  logVolStdev)

//====================================================================
//===================== TAHMİNİ FİYAT OLUŞTURMA ======================
//====================================================================

float alpha  = priceMean
bool canCalc = not na(filteredClose) and not na(priceMean)

float predictedPrice = na
if canCalc
    // Farklar
    float dBtcDom   = (btcDom - btcDomMean)
    float dVol      = (vol    - volMean)
    float dPLag1    = (priceLag1 - plag1Mean)
    float dPLag2    = (priceLag2 - plag2Mean)
    float dSynergy  = (synergyTerm - synergyMean)
    float dLogVol   = (logVolume   - logVolMean)

    float sumBeta   = 0.0
    sumBeta += betaBtcDom  * dBtcDom
    sumBeta += betaVol     * dVol
    sumBeta += betaPLag1   * dPLag1

    if usePriceLag2
        sumBeta += betaPLag2 * dPLag2

    if useSynergyTerm
        sumBeta += betaSynergy * dSynergy

    if useLogVolume
        sumBeta += betaLogVol * dLogVol

    predictedPrice := alpha + sumBeta

//====================================================================
//======================= REZİDÜEL & BANT ============================
//====================================================================

float residual   = filteredClose - predictedPrice
float residStdev = ta.stdev(residual, lengthForStd)

float upperBand  = predictedPrice + stdevFactor * residStdev
float lowerBand  = predictedPrice - stdevFactor * residStdev

//====================================================================
//========================= SİNYAL ÜRETİMİ ===========================
//====================================================================

bool longSignal  = (realClose < lowerBand)
bool shortSignal = (realClose > upperBand)

//------------------ RSI Filtresi (opsiyonel) -----------------------//
float rsiVal       = ta.rsi(realClose, rsiLen)
bool rsiOversold   = (rsiVal < rsiOS)
bool rsiOverbought = (rsiVal > rsiOB)

if useRsiFilter
    longSignal  := longSignal  and rsiOversold
    shortSignal := shortSignal and rsiOverbought

//====================================================================
//=============== DİNAMİK POZİSYON & GİRİŞ/ÇIKIŞ EMİRLERİ ============
//====================================================================

float myAtr      = ta.atr(atrLen)
float positionSize = na

if useDynamicPos
    float capitalRisked   = strategy.equity * (capitalRiskedPerc / 100.0)
    float riskPerUnit     = (stopLossPerc/100.0) * myAtr
    positionSize          := (riskPerUnit != 0.0) ? (capitalRisked / riskPerUnit) : na

// Long
if longSignal
    if useDynamicPos and not na(positionSize)
        strategy.entry("Long", strategy.long, qty=positionSize)
    else
        strategy.entry("Long", strategy.long)

// Short
if shortSignal
    if useDynamicPos and not na(positionSize)
        strategy.entry("Short", strategy.short, qty=positionSize)
    else
        strategy.entry("Short", strategy.short)

// Stop-Loss & Take-Profit
if strategy.position_size > 0
    strategy.exit( "Long Exit", "Long",stop  = strategy.position_avg_price * (1 - stopLossPerc/100),  limit = strategy.position_avg_price * (1 + takeProfitPerc/100))

if strategy.position_size < 0
    strategy.exit("Short Exit", "Short", stop  = strategy.position_avg_price * (1 + stopLossPerc/100),limit = strategy.position_avg_price * (1 - takeProfitPerc/100))

//------------------ TRAILING STOP (opsiyonel) ----------------------//
if useTrailingStop
    if strategy.position_size > 0
        strategy.exit(  "Long Exit TS", "Long",  trail_points = myAtr * trailMult,  trail_offset = myAtr * trailMult )
    if strategy.position_size < 0
        strategy.exit( "Short Exit TS", "Short", trail_points = myAtr * trailMult, trail_offset = myAtr * trailMult)

//====================================================================
//======================== GRAFİK ÇİZİMLER ===========================
//====================================================================
plot(realClose,      color=color.white,  linewidth=1, title="Fiyat")
plot(predictedPrice, color=color.yellow, linewidth=2, title="PredictedPrice")
plot(upperBand,      color=color.red,    linewidth=1, title="Üst Band")
plot(lowerBand,      color=color.lime,   linewidth=1, title="Alt Band")

plotshape( useOutlierFilter and isOutlier, style=shape.circle, color=color.red, size=size.tiny, location=location.abovebar, title="Outlier", text="Outlier")