Chiến lược Sizeblock

Tác giả:ChaoZhang, Ngày: 2023-11-06 09:20:34
Tags:

img

Tổng quan

Chiến lược Sizeblock là một chiến lược giao dịch dựa trên tỷ lệ phần trăm hoặc độ lệch của sự thay đổi giá được hiển thị trong các hàng chéo. Nó có thể hiển thị rõ ràng xu hướng địa phương và điểm đảo ngược trên biểu đồ. Đây là một công cụ rất hữu ích để theo dõi hướng giá.

Nguyên tắc

Việc tính toán dựa trên tỷ lệ phần trăm hoặc lệch điểm của sự biến động giá (được chỉ định trong tham số Deviation), được hiển thị trên biểu đồ dưới dạng hàng.

Dòng bao gồm đường giữa cơ sở, giới hạn trên và dưới:

  • Đường trung bình cơ bản bằng giới hạn trên hoặc dưới của hàng trước (nếu giá thay đổi nhanh trong một khoảng thời gian, thì đường trung bình cơ bản của hàng hiện tại lớn hơn giới hạn trên của hàng trước hoặc nhỏ hơn giới hạn dưới của hàng trước bằng một số độ lệch tương đương tùy thuộc vào hướng chuyển động giá).

  • Các thông số Quantity xác định độ lệch đối với các giới hạn trên hoặc dưới tùy thuộc vào hướng chuyển động giá, và các thông số U-turn xác định độ lệch để thay đổi hướng chuyển động giá.

Quy tắc xây dựng một hàng mới:

  • Nếu đóng ≥ giới hạn trên và đóng > mở, giới hạn trên sẽ dần dần di chuyển lên, và giới hạn dưới cũng sẽ di chuyển lên nhưng ít hơn.

  • Nếu mức thấp ≤ giới hạn dưới và đóng < mở, giới hạn dưới sẽ dần dần di chuyển xuống, và giới hạn trên cũng sẽ di chuyển xuống nhưng ít hơn.

Bằng cách điều chỉnh một số độ lệch nhất định, bạn có thể thấy rõ xu hướng địa phương và điểm đảo ngược trên biểu đồ.

Ưu điểm

  • Hiển thị xu hướng thay đổi giá và xác định rõ ràng mức hỗ trợ và kháng cự.

  • Các đường chéo cho thấy rõ sức mạnh của sự đột phá và phạm vi rút lui.

  • Độ nghiêng của các đường chéo có thể được điều chỉnh khi cần thiết để xác định xu hướng của sức mạnh khác nhau.

  • Có thể tìm thấy sự hỗ trợ và kháng cự tương đối lớn cho các vụ đột phá.

  • Dễ dàng để nhìn thấy những thay đổi trong nhịp giá và điều chỉnh kích thước vị trí phù hợp.

Rủi ro

  • Các đường chéo không thể dự đoán hoàn toàn chính xác các chuyển động giá tiếp theo.

  • Cần phải theo dõi sự khác biệt trong xu hướng khi đường chéo có thể khác với giá thực tế.

  • Không thể được sử dụng như một chiến lược cô lập, cần phải kết hợp các chỉ số khác để xác định xu hướng chính.

  • Điều chỉnh tham số không đúng có thể dẫn đến giao dịch quá thường xuyên.

  • Cần phải cảnh giác với những sự đảo ngược tiềm năng trong thời gian rút lui thay vì mù quáng theo đuổi xu hướng một cách cơ học.

Có thể giảm đáng kể kích thước vị trí và tham khảo các chỉ số khác như là phán đoán phụ trong các xu hướng chính.

Tối ưu hóa

  • Có thể thêm các mô-đun quản lý vị trí để điều chỉnh động các vị trí trong các giai đoạn xu hướng khác nhau.

  • Có thể kết hợp các chỉ số biến động để giảm các vị trí khi biến động tăng lên.

  • Có thể thiết lập stop loss dựa trên tỷ lệ phần trăm rút tiền để kiểm soát lỗ đơn.

  • Có thể thêm các bộ lọc để tạm dừng giao dịch khi sự khác biệt giá xảy ra.

  • Có thể chia các độ dốc chéo thành nhiều cấp để xác định những thay đổi xu hướng có cường độ khác nhau.

Bằng cách điều chỉnh vị trí năng động, đặt dừng và bộ lọc, có thể theo dõi xu hướng giá ổn định hơn.

Tóm lại

Chiến lược Sizeblock sử dụng đường chéo để trực quan hiển thị thay đổi xu hướng giá và xác định rõ mức hỗ trợ, kháng cự và phá vỡ. Nhưng không thể chỉ dựa vào đường chéo để phán đoán, cần kết hợp phân tích từ các chỉ số khác và quản lý rủi ro. Đây là một công cụ phụ trợ rất có giá trị để giúp các nhà giao dịch nắm bắt nhịp thị trường tốt hơn. Tối ưu hóa có thể làm cho chiến lược mạnh mẽ hơn và hiệu quả hơn với tiềm năng ứng dụng lớn.


/*backtest
start: 2023-10-06 00:00:00
end: 2023-11-05 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// **********************************************************************************
// This code is invented and written by @StCogitans.
// The idea presented in this code and the rights to this code belong to @StCogitans.
// © https://www.tradingview.com/u/StCogitans
//
// Description.
// Sizeblock - a price change strategy in the form of diagonal rows.
// **********************************************************************************

// STRATEGY
string NAME        = 'Sizeblock'
string ACRONYM     = 'SB'
bool OVERLAY       = true
int PYRAMIDING     = 0
string QTY_TYPE    = strategy.percent_of_equity
float QTY_VALUE    = 100
float CAPITAL      = 100
string COM_TYPE    = strategy.commission.percent
float COM_VALUE    = 0.1
bool ON_CLOSE      = false
bool BAR_MAGNIFIER = false
bool OHLC          = true
strategy(NAME, ACRONYM, OVERLAY, pyramiding=PYRAMIDING, default_qty_type=QTY_TYPE, default_qty_value=QTY_VALUE, initial_capital=CAPITAL, commission_type=COM_TYPE, commission_value=COM_VALUE, process_orders_on_close=ON_CLOSE, use_bar_magnifier=BAR_MAGNIFIER, fill_orders_on_standard_ohlc=OHLC)

// ARGUMENTS
// Datetime
DTstart  = input(timestamp("01 Jan 2000 00:00 +0000"), 'Start time', group='Datetime')
DTfinish = input(timestamp("01 Jan 2080 23:59 +0000"), 'Finish time', group='Datetime')
DTperiod = true

// Main
dev_source = input.string('Close', title='Source', options=["Close", "HighLow"], tooltip='Price data for settlement.', group='Main')
dev_type   = input.string('Percentage', title='Deviation', options=['Percentage', 'Ticks'], tooltip='The type of deviation to calculate.', group='Main')
dev_value  = input.float(1, title='Quantity', minval=0.001, step=0.01, tooltip='Quantity to be calculated.', group='Main')
dev_back   = input.float(2, title='U-turn', minval=0.001, step=0.01, tooltip='Quantity for reversal.', group='Main')
mode       = input.string('Limit', title='Positions', options=['Limit', 'Market'], tooltip='Limit or market orders.', group='Main')
direct     = input.string('All', title='Direction', options=['All', 'Buy', 'Sell'], tooltip='The type of positions to be opened.', group='Main')
swapping   = input.bool(false, title='Swapping', tooltip='Swap points to open a new position.', group='Main')

// CALCULATION SYSTEM
Assembling(s, t, v, vb) =>

    float a = open
    float b = close
    float c = s == "HighLow" ? math.round_to_mintick(high) : math.round_to_mintick(b)
    float d = s == "HighLow" ? math.round_to_mintick(low) : math.round_to_mintick(b)

    float x = math.round_to_mintick(a)
    x := nz(x[1], x)

    float _v = t == "Ticks" ? syminfo.mintick * v : v
    float _vb = t == "Ticks" ? syminfo.mintick * vb : vb

    float h = t == "Ticks" ? math.round_to_mintick(x + _v) : math.round_to_mintick(x * (1 + _v / 100))
    float l = t == "Ticks" ? math.round_to_mintick(x - _v) : math.round_to_mintick(x * (1 - _v / 100))
    h := nz(h[1], h)
    l := nz(l[1], l)

    if t == "Ticks"
    
        if c >= h and b > a
            while c >= h
            
                x := h
                h := math.round_to_mintick(h + _v)
                l := math.round_to_mintick(x - _vb)
        
        if d <= l and b < a
            while d <= l
            
                x := l
                l := math.round_to_mintick(l - _v)
                h := math.round_to_mintick(x + _vb)

    else if t == "Percentage"
    
        if c >= h and b > a
            while c >= h
        
                x := h
                h := math.round_to_mintick(h * (1 + _v / 100))
                l := math.round_to_mintick(x * (1 - _vb / 100))

        if d <= l and b < a
            while d <= l
        
                x := l
                l := math.round_to_mintick(l * (1 - _v / 100))
                h := math.round_to_mintick(x * (1 + _vb / 100))

    [x, h, l]

[lx, lh, ll] = Assembling(dev_source, dev_type, dev_value, dev_back)

// PLOT
// Lines
plot_up   = plot(lh, color=color.new(color.green, 50), style=plot.style_line, linewidth=1)
plot_main = plot(lx, color=color.new(color.silver, 50), style=plot.style_line, linewidth=1)
plot_down = plot(ll, color=color.new(color.red, 50), style=plot.style_line, linewidth=1)

// Areas
fill(plot_up, plot_main, lh, lx, color.new(color.teal, 80), color.new(color.teal, 80))
fill(plot_main, plot_down, lx, ll, color.new(color.maroon, 80), color.new(color.maroon, 80))

// TRADING
// Alert variables
int Action = -1
int PosType = -1
int OrderType = -1
float Price = -1.0

// Direction variables
bool ifBuy = direct == "All" or direct == "Buy" ? true : false
bool ifSell = direct == "All" or direct == "Sell" ? true : false

// Market entries
if (strategy.closedtrades + strategy.opentrades == 0 or mode == "Market") and DTperiod
    if ((swapping and lx < nz(lx[1], lx)) or (not swapping and lx > nz(lx[1], lx))) and ifBuy
        Action := 1
        PosType := 1
        OrderType := 1
        Price := math.round_to_mintick(close)
        strategy.entry('Long', strategy.long)
    if ((swapping and lx > nz(lx[1], lx)) or (not swapping and lx < nz(lx[1], lx))) and ifSell
        Action := 2
        PosType := 2
        OrderType := 1
        Price := math.round_to_mintick(close)
        strategy.entry('Short', strategy.short)

// Closing positions by market
if DTperiod and mode == "Market"
    if direct == "Buy" and strategy.position_size > 0
        if swapping and lx > nz(lx[1], lx)
            Action := 2
            PosType := 3
            OrderType := 1
            Price := math.round_to_mintick(close)
            strategy.close('Long', comment='Close')
        if not swapping and lx < nz(lx[1], lx)
            Action := 2
            PosType := 3
            OrderType := 1
            Price := math.round_to_mintick(close)
            strategy.close('Long', comment='Close')
    if direct == "Sell" and strategy.position_size < 0
        if swapping and lx < nz(lx[1], lx)
            Action := 1
            PosType := 3
            OrderType := 1
            Price := math.round_to_mintick(close)
            strategy.close('Short', comment='Close')
        if not swapping and lx > nz(lx[1], lx)
            Action := 1
            PosType := 3
            OrderType := 1
            Price := math.round_to_mintick(close)
            strategy.close('Short', comment='Close')

// Limit entries and exits
if swapping and DTperiod and mode == "Limit"
    if strategy.position_size < 0
        Action := 1
        PosType := 1
        OrderType := 2
        Price := ll
        if ifBuy
            strategy.entry('Long', strategy.long, limit=ll)
        else
            PosType := 3
            strategy.exit('Exit', limit=ll)
    if strategy.position_size > 0
        Action := 2
        PosType := 2
        OrderType := 2
        Price := lh
        if ifSell
            strategy.entry('Short', strategy.short, limit=lh)
        else
            PosType := 3
            strategy.exit('Exit', limit=lh)
    if strategy.closedtrades + strategy.opentrades > 0 and strategy.position_size == 0
        if ifBuy
            Action := 1
            PosType := 1
            OrderType := 2
            Price := ll
            strategy.entry('Long', strategy.long, limit=ll)
        if ifSell
            Action := 2
            PosType := 2
            OrderType := 2
            Price := lh
            strategy.entry('Short', strategy.short, limit=lh)
if not swapping and DTperiod and mode == "Limit"
    if strategy.position_size < 0
        Action := 1
        PosType := 1
        OrderType := 2
        Price := lh
        if ifBuy
            strategy.entry('Long', strategy.long, stop=lh)
        else
            PosType := 3
            strategy.exit('Exit', stop=lh)
    if strategy.position_size > 0
        Action := 2
        PosType := 2
        OrderType := 2
        Price := ll
        if ifSell
            strategy.entry('Short', strategy.short, stop=ll)
        else
            PosType := 3
            strategy.exit('Exit', stop=ll)
    if strategy.closedtrades + strategy.opentrades > 0 and strategy.position_size == 0
        if ifBuy
            Action := 1
            PosType := 1
            OrderType := 2
            Price := lh
            strategy.entry('Long', strategy.long, stop=lh)
        if ifSell
            Action := 2
            PosType := 2
            OrderType := 2
            Price := ll
            strategy.entry('Short', strategy.short, stop=ll)

// Everything is closed and canceled
if not DTperiod
    strategy.cancel_all()
    strategy.close_all(comment='Close')

// Alerts
// Convert to string variables
string Action_Txt = Action == 1 ? "Buy" : Action == 2 ? "Sell" : na
string PosType_Txt = PosType == 1 ? "Long" : PosType == 2 ? "Short" : PosType == 3 ? "Flat" : na
string OrderType_Txt = OrderType == 1 ? "Market" : OrderType == 2 ? "Limit" : na
string Price_Txt = Price > 0 ? str.tostring(Price) : na

// Output
if not (Action == nz(Action[1], Action) and Price == nz(Price[1], Price) and OrderType == nz(OrderType[1], OrderType)) and DTperiod
    alert('{"pair": "' + syminfo.ticker + '", "direction": "' + Action_Txt + '", "entertype": "' + OrderType_Txt + '", "position": "' + PosType_Txt + '", "price": "' + Price_Txt + '"}')

// *********************
// Good job, Soldier! ;>
// *********************

Thêm nữa