Chiến lược giao dịch chứng khoán xoay động

Tác giả:ChaoZhang, Ngày: 2023-09-19 22:14:24
Tags:

Tổng quan

Chiến lược này áp dụng xoay động để xác định xu hướng thị trường dựa trên chỉ số Stoch RSI và thực hiện giao dịch xoay cổ phiếu. Nó đi ngắn khi chỉ số hiển thị mua quá nhiều và đi dài khi nó hiển thị bán quá nhiều. Đồng thời, kích thước vị trí được tăng theo hướng xu hướng bằng cách sử dụng giao dịch kim tự tháp.

Chiến lược logic

  1. Tính toán chỉ số RSI với thời gian 14 giai đoạn
  2. Tính toán Stoch RSI dựa trên RSI, với Stochastic Length 14, Smooth K 3 và Smooth D 1
  3. Đi dài khi Stoch RSI tăng từ bán quá mức vào mua quá mức
  4. Đi ngắn khi Stoch RSI giảm từ mua quá nhiều vào bán quá nhiều
  5. Sử dụng giao dịch kim tự tháp để tăng vị trí lên đến 5 lần
  6. Đặt dừng lỗ và dừng kéo theo sau mỗi thêm
  7. Giảm vị trí khi stop loss được kích hoạt
  8. Quản lý các vị trí dựa trên lệnh dừng lỗ và lệnh dừng kéo dài

Phân tích lợi thế

Những lợi thế của chiến lược này là:

  1. Dựa trên chỉ số động lực, nó có thể nắm bắt sự đảo ngược xu hướng kịp thời và điều chỉnh hướng vị trí phù hợp.
  2. Giao dịch kim tự tháp cho phép lấy vị trí đầu tiên với kích thước nhỏ và thêm vào khi xu hướng xác nhận, nắm bắt hoàn toàn lợi nhuận xu hướng.
  3. Dừng lỗ kiểm soát rủi ro. Dừng ban đầu lọc tiếng ồn và dừng lại khóa lợi nhuận.
  4. Không gian tối ưu hóa RSI là lớn, các thông số có thể được điều chỉnh cho các thị trường khác nhau.
  5. Thời gian thêm linh hoạt, kích thước và dừng thích nghi tốt với các điều kiện thị trường khác nhau.

Phân tích rủi ro

Một số rủi ro cần lưu ý:

  1. Chỉ dựa vào chỉ số RSI khiến nó dễ bị tổn thương bởi những sự kiện đột ngột.
  2. Chỉ áp dụng cho các sản phẩm có xu hướng mạnh.
  3. Tăng quá mức có thể dẫn đến tổn thất tăng cường.
  4. Thiết lập stop loss không chính xác có thể gây ra quá mức stop.
  5. Kiểm tra chi phí giao dịch, giao dịch tần suất cao tạo ra hoa hồng lớn.

Hướng dẫn tối ưu hóa

Một số cách để tối ưu hóa chiến lược:

  1. Tối ưu hóa tham số RSI Length để phù hợp nhất.
  2. Tối ưu hóa thời gian Stoch K và D cho các tín hiệu mượt mà hơn.
  3. Thêm các chỉ số khác để lọc tín hiệu và tránh giao dịch sai.
  4. Điều chỉnh động thêm thời gian dựa trên điều kiện thị trường.
  5. Tối ưu hóa logic dừng lỗ để giảm tỷ lệ dừng.
  6. Thêm mô-đun kích thước vị trí dựa trên quản lý tiền.
  7. Bao gồm kiểm soát hoa hồng để hạn chế giao dịch tần số cao.

Kết luận

Chiến lược này áp dụng một khái niệm xoay động mạnh mẽ, với Stoch RSI là chỉ số giao dịch cốt lõi, được bổ sung bằng giao dịch kim tự tháp và quản lý dừng để kiểm soát rủi ro. Đây là một xu hướng đáng tin cậy sau chiến lược. Việc tối ưu hóa thêm các thông số và mô-đun có thể tăng cường sự ổn định và khả năng thích nghi của nó.


/*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)


Thêm nữa