Chiến lược giao dịch định lượng đa yếu tố


Ngày tạo: 2024-01-25 13:04:16 sửa đổi lần cuối: 2024-01-25 13:04:16
sao chép: 0 Số nhấp chuột: 634
1
tập trung vào
1617
Người theo dõi

Chiến lược giao dịch định lượng đa yếu tố

Tổng quan

Chiến lược này là một chiến lược giao dịch định lượng đa yếu tố, kết hợp nhiều chỉ số kỹ thuật như RSI, MACD, OBV, CCI, CMF, MFI và VWMACD để thực hiện giao dịch định lượng cổ phiếu tự động. Chiến lược được gọi là Chiến lược khi chọn yếu tố không gian định lượng nhiều.

Nguyên tắc chiến lược

Lý luận cốt lõi của chiến lược này là phán đoán dựa trên hình thức của nhiều chỉ số kỹ thuật và thực hiện mua khi nhiều chỉ số phát ra tín hiệu mua cùng một lúc.

Cụ thể, các chỉ số RSI, MACD, OBV, CCI, CMF, MFI và VWMACD trong chiến lược sẽ phát hiện ra liệu chúng có đang có xu hướng giảm nhưng giá trị chỉ số không giảm, nếu xảy ra tình huống như vậy, nó có thể cho thấy sự đảo ngược sắp tới. Trong mã, chúng ta gọi dạng này là trục trục cố ý đầu trống, nếu nhiều chỉ số cùng lúc xuất hiện trục trục cố ý đầu trống, thì sẽ gửi tín hiệu mua cuối cùng.

Ngoài ra, chiến lược này cũng đưa ra logic phán đoán về khối lượng giao dịch bất thường. Khi giá dao động nhưng khối lượng giao dịch không tăng lên rõ rệt, thì rất có thể là đột phá giả, khi đó sẽ phát ra tín hiệu mua.

Tóm lại, chiến lược này cải thiện độ chính xác của quyết định bằng cách quan sát các tín hiệu đảo ngược của nhiều chỉ số kỹ thuật và kết hợp các phán đoán bất thường về khối lượng giao dịch, đây là chìa khóa cho sự thành công của chiến lược giao dịch định lượng.

Lợi thế chiến lược

Chiến lược này có một số lợi thế:

  1. Mô hình đa yếu tố, kết hợp các tín hiệu của 7 chỉ số kỹ thuật phổ biến, cải thiện độ chính xác của quyết định giao dịch.

  2. Thêm tín hiệu đảo ngược số lượng giao thông để tránh bị lừa bởi đột phá giả, lọc tín hiệu vô hiệu.

  3. Sử dụng phán đoán hình thức giảm, bắt kịp thời điểm cổ phiếu đảo ngược tăng.

  4. Tự động hóa giao dịch, không cần sự can thiệp của con người, giảm chi phí vận hành đáng kể.

  5. Chiến lược logic rõ ràng, đơn giản, dễ hiểu, sửa đổi và tối ưu hóa.

Rủi ro chiến lược

Chiến lược này cũng có một số rủi ro:

  1. Nhiều yếu tố kết hợp không đúng, có thể tạo ra tín hiệu giao dịch xung đột. Cần thử nghiệm điều chỉnh các tham số của từng yếu tố để tìm cấu hình tối ưu.

  2. Giao dịch đảo ngược có một số rủi ro, có khả năng bị đảo ngược một lần nữa. Bạn có thể thiết lập điểm dừng để kiểm soát rủi ro.

  3. Chỉ số VOLUME có thể không hiệu quả đối với một số cổ phiếu ít thanh khoản, trong đó có thể giảm trọng lượng VOLUME hoặc loại trừ các cổ phiếu này.

  4. Hiệu quả phù hợp với dữ liệu trong thời gian phản hồi tốt, hiệu suất thời gian thực có thể kém. Cần tích lũy thêm dữ liệu thực để thử nghiệm.

Hướng tối ưu hóa chiến lược

Chiến lược này có thể được tối ưu hóa hơn nữa ở những khía cạnh sau:

  1. Tăng hoặc giảm một số chỉ số kỹ thuật để tìm mô hình đa yếu tố có cấu hình tối ưu.

  2. Cài đặt các tham số hoặc trọng lượng khác nhau cho các loại cổ phiếu khác nhau, để chiến lược có thể được nhắm mục tiêu hơn.

  3. Thiết lập dừng động, di chuyển stop-loss để khóa lợi nhuận và kiểm soát rủi ro.

  4. Kết hợp các thông tin như ngành, khái niệm, chọn giao dịch cổ phiếu trong một lĩnh vực cụ thể.

  5. Tham gia thuật toán học máy để tự động tối ưu hóa các tham số của chiến lược.

Tóm tắt

Chiến lược này nói chung là một chiến lược giao dịch định lượng rất tiềm năng. Nó kết hợp nhiều tín hiệu chỉ số kỹ thuật, hỗ trợ định lượng để đưa ra phán đoán, có thể phát hiện hiệu quả cơ hội đảo ngược cổ phiếu, tự động hóa giao dịch.

Mã nguồn chiến lược
/*backtest
start: 2023-01-18 00:00:00
end: 2024-01-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © mkose81

//@version=5
strategy("MK future stopsuz 40 alım (Sadece Long)", overlay=true, max_bars_back=4000,use_bar_magnifier= true,pyramiding=40)


// RSI Hesaplama
rsi = ta.rsi(close, 14)
float botRSI = na
botRSI := ta.pivotlow(5, 5)
botcRSI = 0
botcRSI := botRSI ? 5 : nz(botcRSI[1]) + 1

newbotRSI = ta.pivotlow(5, 0)
emptylRSI = true
if not na(newbotRSI) and newbotRSI < low[botcRSI]
    diffRSI = (newbotRSI - low[botcRSI]) / botcRSI
    llineRSI = newbotRSI - diffRSI
    for x = 1 to botcRSI - 1 by 1
        if close[x] < llineRSI
            emptylRSI := false
            break
        llineRSI -= diffRSI
    emptylRSI

// Pozitif Uyumsuzluk Alım Sinyali - RSI
alRSI = 0
if emptylRSI and not na(newbotRSI)
    if rsi[botcRSI] < rsi
        alRSI := 1

// MACD Hesaplama
[macd, signal, _] = ta.macd(close, 21, 55, 8)
float botMACD = na
botMACD := ta.pivotlow(5, 5)
botcMACD = 0
botcMACD := botMACD ? 5 : nz(botcMACD[1]) + 1

newbotMACD = ta.pivotlow(5, 0)
emptylMACD = true
if not na(newbotMACD) and newbotMACD < low[botcMACD]
    diffMACD = (newbotMACD - low[botcMACD]) / botcMACD
    llineMACD = newbotMACD - diffMACD
    for x = 1 to botcMACD - 1 by 1
        if close[x] < llineMACD
            emptylMACD := false
            break
        llineMACD -= diffMACD
    emptylMACD

// Pozitif Uyumsuzluk Alım Sinyali - MACD
alMACD = 0
if emptylMACD and not na(newbotMACD)
    if macd[botcMACD] < macd
        alMACD := 1
// OBV Hesaplama ve Uyumsuzluk Tespiti
obv = ta.cum(ta.change(close) > 0 ? volume : ta.change(close) < 0 ? -volume : 0)
float botOBV = na
botOBV := ta.pivotlow(5, 5)
botcOBV = 0
botcOBV := botOBV ? 5 : nz(botcOBV[1]) + 1

newbotOBV = ta.pivotlow(5, 0)
emptylOBV = true
if not na(newbotOBV) and newbotOBV < obv[botcOBV]
    diffOBV = (newbotOBV - obv[botcOBV]) / botcOBV
    llineOBV = newbotOBV - diffOBV
    for x = 1 to botcOBV - 1 by 1
        if obv[x] < llineOBV
            emptylOBV := false
            break
        llineOBV -= diffOBV
    emptylOBV

// Pozitif Uyumsuzluk Alım Sinyali - OBV
alOBV = 0
if emptylOBV and not na(newbotOBV)
    if obv[botcOBV] < obv
        alOBV := 1

// CCI Hesaplama ve Uyumsuzluk Tespiti
cci = ta.cci(close, 20)
float botCCI = na
botCCI := ta.pivotlow(5, 5)
botcCCI = 0
botcCCI := botCCI ? 5 : nz(botcCCI[1]) + 1

newbotCCI = ta.pivotlow(5, 0)
emptylCCI = true
if not na(newbotCCI) and newbotCCI < cci[botcCCI]
    diffCCI = (newbotCCI - cci[botcCCI]) / botcCCI
    llineCCI = newbotCCI - diffCCI
    for x = 1 to botcCCI - 1 by 1
        if cci[x] < llineCCI
            emptylCCI := false
            break
        llineCCI -= diffCCI
    emptylCCI

// Pozitif Uyumsuzluk Alım Sinyali - CCI
alCCI = 0
if emptylCCI and not na(newbotCCI)
    if cci[botcCCI] < cci
        alCCI := 1

// CMF Hesaplama
length = 20
mfm = ((close - low) - (high - close)) / (high - low)
mfv = mfm * volume
cmf = ta.sma(mfv, length) / ta.sma(volume, length)

float botCMF = na
botCMF := ta.pivotlow(5, 5)
botcCMF = 0
botcCMF := botCMF ? 5 : nz(botcCMF[1]) + 1

newbotCMF = ta.pivotlow(5, 0)
emptylCMF = true
if not na(newbotCMF) and newbotCMF < cmf[botcCMF]
    diffCMF = (newbotCMF - cmf[botcCMF]) / botcCMF
    llineCMF = newbotCMF - diffCMF
    for x = 1 to botcCMF - 1 by 1
        if cmf[x] < llineCMF
            emptylCMF := false
            break
        llineCMF -= diffCMF
    emptylCMF

// Pozitif Uyumsuzluk Alım Sinyali - CMF
alCMF = 0
if emptylCMF and not na(newbotCMF)
    if cmf[botcCMF] < cmf
        alCMF := 1

// MFI Hesaplama
lengthMFI = 14
mfi = ta.mfi(close, lengthMFI)

float botMFI = na
botMFI := ta.pivotlow(mfi, 5, 5)
botcMFI = 0
botcMFI := botMFI ? 5 : nz(botcMFI[1]) + 1

newbotMFI = ta.pivotlow(mfi, 5, 0)
emptylMFI = true
if not na(newbotMFI) and newbotMFI < mfi[botcMFI]
    diffMFI = (newbotMFI - mfi[botcMFI]) / botcMFI
    llineMFI = newbotMFI - diffMFI
    for x = 1 to botcMFI - 1 by 1
        if mfi[x] < llineMFI
            emptylMFI := false
            break
        llineMFI -= diffMFI
    emptylMFI

// Pozitif Uyumsuzluk Alım Sinyali - MFI
alMFI = 0
if emptylMFI and not na(newbotMFI)
    if mfi[botcMFI] < mfi
        alMFI := 1

// VWMACD Hesaplama
fastLength = 12
slowLength = 26
signalSmoothing = 9
vwmacd = ta.ema(close, fastLength) - ta.ema(close, slowLength)
signalLine = ta.ema(vwmacd, signalSmoothing)
histogram = vwmacd - signalLine
// VWMACD Uyumsuzluk Tespiti
float botVWMACD = na
botVWMACD := ta.pivotlow(histogram, 5, 5)
botcVWMACD = 0
botcVWMACD := botVWMACD ? 5 : nz(botcVWMACD[1]) + 1

newbotVWMACD = ta.pivotlow(histogram, 5, 0)
emptylVWMACD = true
if not na(newbotVWMACD) and newbotVWMACD < histogram[botcVWMACD]
    diffVWMACD = (newbotVWMACD - histogram[botcVWMACD]) / botcVWMACD
    llineVWMACD = newbotVWMACD - diffVWMACD
    for x = 1 to botcVWMACD - 1 by 1
        if histogram[x] < llineVWMACD
            emptylVWMACD := false
            break
        llineVWMACD -= diffVWMACD
    emptylVWMACD

// Pozitif Uyumsuzluk Alım Sinyali - VWMACD
alVWMACD = 0
if emptylVWMACD and not na(newbotVWMACD)
    if histogram[botcVWMACD] < histogram
        alVWMACD := 1
//Dipci indikator
lengthd= 130
coef = 0.2
vcoef = 2.5
signalLength = 5
smoothVFI = false

ma(x, y) =>
    smoothVFI ? ta.sma(x, y) : x

typical = hlc3
inter = math.log(typical) - math.log(typical[1])
vinter = ta.stdev(inter, 30)
cutoff = coef * vinter * close
vave = ta.sma(volume, lengthd)[1]
vmax = vave * vcoef
vc = volume < vmax ? volume : vmax  //min( volume, vmax )
mf = typical - typical[1]
iff_4 = mf < -cutoff ? -vc : 0
vcp = mf > cutoff ? vc : iff_4

vfi = ma(math.sum(vcp, lengthd) / vave, 3)
vfima = ta.ema(vfi, signalLength)
d = vfi - vfima

// Kullanıcı girdileri
volatilityThreshold = input.float(1.005, title="Volume Percentage Threshold")
pinThreshold = input.float(1.005, title="Deep Percentage Threshold")
// Hesaplamalar
volatilityPercentage = (high - low) / open
pinPercentage = close > open ? (high - close) / open : (close - low) / open
// Volatilite koşulu ve VFI ile filtreleme
voldip = volatilityPercentage >= volatilityThreshold or pinPercentage >= pinThreshold
volCondition = voldip and vfi< 0  // VFI değeri 0'dan küçükse volCondition aktif olacak





threeCommasEntryComment = input.string(title="3Commas Entry Comment", defval="")
threeCommasExitComment = input.string(title="3Commas Exit Comment", defval="")


takeProfitPerc = input.float(1, title="Take Profit Percentage (%)") / 100
fallPerc = input.float(5, title="Percentage for Additional Buy (%)") / 100
// Değişkenlerin tanımlanması
var float lastBuyPrice = na
var float tpPrice = na
var int lastTpBar = na

// Alım koşulları
longCondition = alRSI or alMACD or alOBV or alCCI or alCMF or alMFI or alVWMACD or volCondition
// Son alım fiyatını saklamak için değişken


// İlk alım stratejisi
if (longCondition and strategy.position_size == 0)
    strategy.entry("Long", strategy.long, comment=threeCommasEntryComment)
    lastBuyPrice := open

// İkinci ve sonraki alım koşulları (son alım fiyatının belirlenen yüzde altında)
if (open < lastBuyPrice * (1 - fallPerc) and strategy.position_size > 0)
    strategy.entry("Long Add", strategy.long, comment=threeCommasEntryComment)
    lastBuyPrice := open

// Kar alma fiyatını hesaplama ve strateji çıkışı
tp_price = strategy.position_avg_price * (1 + takeProfitPerc)
if strategy.position_size > 0
    strategy.exit("Exit Long", "Long", limit=tp_price, comment=threeCommasExitComment)
    strategy.exit("Exit Long Add", "Long Add", limit=tp_price, comment=threeCommasExitComment)
    tpPrice := na // Pozisyon kapandığında TP çizgisini sıfırla

// Kar alma seviyesi çizgisi çizme
plot(strategy.position_size > 0 ? tp_price : na, color=color.green, title="Take Profit Line")