Chiến lược cổ phiếu dựa trên sự luân chuyển động lượng


Ngày tạo: 2023-09-19 22:14:24 sửa đổi lần cuối: 2023-09-19 22:14:24
sao chép: 0 Số nhấp chuột: 729
1
tập trung vào
1617
Người theo dõi

Tổng quan

Chiến lược này sử dụng phương pháp chuyển động động lực, đánh giá xu hướng thị trường dựa trên chỉ số Stoch RSI, để thực hiện giao dịch chuyển động cổ phiếu. Khi chỉ số hiển thị mua quá mức, hãy giảm giá và khi bán quá mức, hãy làm nhiều hơn.

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

  1. Tính toán giá trị của chỉ số RSI với độ dài 14 chu kỳ
  2. Stochastic Length là 14, Smooth K là 3, Smooth D là 1
  3. Khi Stoch RSI tăng từ vùng bán tháo sang vùng mua tháo, hãy tham gia thêm
  4. Khi Stoch RSI giảm từ vùng mua quá mức sang vùng bán quá mức, thì lệnh nhượng quyền được thực hiện.
  5. Sử dụng phương pháp tăng khoan hình nón, tối đa 5 lần
  6. Thiết lập lệnh dừng lỗ và theo dõi lệnh dừng lỗ sau mỗi lần đặt cược
  7. Khi lệnh dừng lỗ được kích hoạt
  8. Quản lý vị trí theo điểm dừng lỗ và theo dõi điểm dừng lỗ

Phân tích lợi thế

Chiến lược này có những lợi thế sau:

  1. Dựa trên hoạt động của chỉ số động lực, nó có thể nắm bắt các điểm biến đổi của xu hướng thị trường và điều chỉnh vị trí của vị trí một cách kịp thời.
  2. Sử dụng nạp vị trí hình nón, có thể chiếm vị trí trong xu hướng ban đầu và tăng vị trí sau khi xác nhận xu hướng, để nắm bắt đầy đủ lợi nhuận xu hướng.
  3. Thiết lập điểm dừng để kiểm soát rủi ro, đặt Stop Loss ban đầu trong phạm vi hợp lý, theo dõi dừng để lợi nhuận hoạt động.
  4. Không gian tối ưu hóa tham số RSI rộng hơn, có thể điều chỉnh tham số cho các thị trường khác nhau để tìm kiếm sự kết hợp tốt nhất.
  5. Có thể điều chỉnh linh hoạt các tham số như lần gia tăng, độ sâu, điểm dừng lỗ, có khả năng thích ứng mạnh mẽ với thị trường.

Phân tích rủi ro

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

  1. Stoch RSI là chỉ số duy nhất có thể gây ra tín hiệu sai về sự kiện bất ngờ. Có thể được xác nhận bằng các chỉ số khác.
  2. Chỉ áp dụng cho các giống có xu hướng mạnh, không phù hợp với thị trường dao động ngang.
  3. Lưu trữ quá nhiều lần có thể dẫn đến tổn thất mở rộng. Cần kiểm soát độ sâu của việc đặt hàng.
  4. Thiết lập điểm dừng không hợp lý có thể dẫn đến dừng quá mức. Cần điều chỉnh tham số dừng theo thị trường.
  5. Cần chú ý đến việc kiểm soát chi phí giao dịch.

Hướng tối ưu hóa

Chiến lược này cũng có thể được tối ưu hóa theo các hướng sau:

  1. Tối ưu hóa tham số RSI, tìm ra Length tối ưu.
  2. Tối ưu hóa tham số Stoch để tìm kết hợp chu kỳ K, D tối ưu nhất.
  3. Thêm các chỉ số khác để lọc tín hiệu và tránh giao dịch sai.
  4. Đổi đổi số lần đặt cược theo thị trường.
  5. Tối ưu hóa logic thiết lập điểm dừng để giảm tỷ lệ dừng.
  6. Thêm mô-đun quản lý vị trí, kiểm soát vị trí theo nguyên tắc quản lý tiền.
  7. Thêm mô-đun kiểm soát phí, kiểm soát tần suất giao dịch quá cao.

Tóm tắt

Chiến lược này sử dụng tư duy chuyển động động lực khá thành thạo, sử dụng Stoch RSI làm chỉ số giao dịch cốt lõi, hỗ trợ việc quản lý rủi ro bằng cách tăng cường và dừng lỗ, là một chiến lược theo dõi xu hướng đáng tin cậy. Bằng cách tối ưu hóa tham số và mở rộng mô-đun, bạn có thể tăng thêm sự ổn định và thích ứng của chiến lược.

Mã nguồn chiến lược
/*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)