Chiến lược định lượng dựa trên tỷ lệ thay đổi giá và đường trung bình động


Ngày tạo: 2023-12-11 11:18:56 sửa đổi lần cuối: 2023-12-11 11:18:56
sao chép: 1 Số nhấp chuột: 727
1
tập trung vào
1621
Người theo dõi

Chiến lược định lượng dựa trên tỷ lệ thay đổi giá và đường trung bình động

Tổng quan

Chiến lược này kết hợp các chỉ số kỹ thuật về tỷ lệ thay đổi giá và đường trung bình để xác định chính xác điểm mua và điểm bán. Xây dựng ngưỡng mua khi giá giảm rõ rệt và mở vị trí nhiều đầu khi giá giảm hơn; Xây dựng ngưỡng bán khi giá tăng và thanh toán khi tiếp tục tăng.

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

Mua logic

  1. Tính toán ROC thay đổi giá và thiết lập đường mua giảm giá.
  2. Khi giá giảm xuống mức giá mua, ghi lại điểm đó và khởi động đường giới hạn mua.
  3. Mua dòng giới hạn theo các tham số đầu vào và đóng sau khi hết hạn.
  4. Khi giá tiếp tục giảm và phá vỡ đường giới hạn mua, hãy mở vị trí đầu tiên.

Bán logic

  1. Tính toán ROC thay đổi giá và thiết lập một đường giảm giá để bán.
  2. Khi giá phá vỡ đường bán giá, ghi lại điểm đó và bắt đầu bán đường giới hạn.
  3. Bán dòng giới hạn theo các tham số đầu vào và đóng sau khi hết hạn.
  4. Khi giá tiếp tục tăng và phá vỡ đường giới hạn bán, xóa tất cả các vị trí đầu nhiều.

Kiểm soát rủi ro

Chiến lược có chức năng dừng và dừng lỗ, có thể tùy chỉnh các tham số, kiểm soát rủi ro của vị trí trong thời gian thực.

Phương pháp tích lũy

Mỗi khi mở một vị trí giao dịch, tùy theo tham số đầu vào, giá mua tiếp theo được thiết lập theo tỷ lệ nhất định, để thực hiện hiệu quả mua hàng loạt và gia tăng vị trí.

Phân tích lợi thế

  1. ROC rất nhạy cảm với sự thay đổi giá và định vị chính xác.
  2. Sử dụng đường dây giới hạn để xác nhận thêm thời gian mua và bán, tránh phá vỡ giả.
  3. Phương pháp gia tăng có thể theo dõi giá trị thị trường trên cơ sở đảm bảo rủi ro có thể kiểm soát được.
  4. Chức năng Stop Loss Built-in kiểm soát chặt chẽ rủi ro của một vị trí.

Rủi ro và giải pháp

  1. Khi thị trường biến động mạnh, chiến lược có thể mở quá nhiều vị trí. Giải pháp là thiết lập các tham số đặt cược hợp lý, kiểm soát tổng số vị trí.
  2. Khi xu hướng biến động giá không rõ ràng, giá dừng hoặc giá dừng có thể được kích hoạt thường xuyên. Bạn có thể nới lỏng mức dừng hoặc tắt chức năng này.

Lời khuyên tối ưu hóa

  1. Kết hợp với các chỉ số khác để lọc thời gian vào thị trường. Ví dụ, kết hợp với đường trung bình, chỉ khi giá giảm xuống đường trung bình, chỉ báo hiệu ROC.
  2. Tối ưu hóa logic đặt cược, chỉ bắt đầu đặt cược khi đáp ứng một số điều kiện nhất định. Ví dụ: chỉ tiếp tục đặt cược khi giá giảm hơn một mức nhất định.
  3. Cài đặt tham số của các giống khác nhau có thể khác nhau rất nhiều, cần phải có đầy đủ phản hồi và mô phỏng ổ cứng để có được sự kết hợp tham số tối ưu.
  4. Có thể thiết lập Stop Loss thích ứng, tùy thuộc vào mức độ biến động của thị trường.

Tóm tắt

Chiến lược tổng hợp sử dụng chỉ số ROC để xác định chính xác điểm mua và bán, lọc tín hiệu theo cách giới hạn đường dây, bảo vệ rủi ro dừng lỗ và mở rộng lợi nhuận bằng cách tăng vị trí. Với các tham số được thiết lập hợp lý, có thể thu được lợi nhuận dư thừa trong khi đảm bảo rủi ro trong phạm vi có thể kiểm soát được. Trong tương lai, có thể tối ưu hóa hơn nữa bộ lọc tín hiệu và cơ chế kiểm soát gió để chiến lược phù hợp với môi trường thị trường nhiều hơn.

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

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @version=4
// © A3Sh

// Rate of price change / Price averaging strategy //
// When the price drops to a specified percentage, a Long Entry Threshold is setup.
// The Long Entry Threshold is only active for a specified number of bars and will de-activate when not crossed. 
// When the price drops further and crosses the Entry Threshold with a minimum of a specified percentage, a Long Position is entered. 
// The same reverse logic used to close the Long Position.
// Stop loss and take profit are active by default. With proper tweaking of the settings it is possible to de-activate SL and TP.

// The strategy is inspired by the following strategies:
// Price Change Scalping Strategy developed by Prosum Solutions, https://www.tradingview.com/script/ue7Uc3sN-Price-Change-Scalping-Strategy-v1-0-0/
// Scalping Dips On Trend Strategy developed by Coinrule, https://www.tradingview.com/script/iHHO0PJA-Scalping-Dips-On-Trend-by-Coinrule/

strategy(title = "ROC_PA_Strategy_@A3Sh", overlay = true )

// Portfolio & Leverage Example
// credit: @RafaelZioni, https://www.tradingview.com/script/xGk5K4DE-BTC-15-min/
ge(value, precision) => round(value * (pow(10, precision))) / pow(10, precision)

port     = input(25, group = "Risk", title = "Portfolio Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)
leverage = input(1,  group = "Risk", title = "Leverage", minval = 1, maxval = 100)
mm       = input(5,  group = "Risk", title = "Broker Maintenance Margin Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)

c = ge((strategy.equity * leverage / open) * (port  / 100), 4)

// Take Profit
tpa = input(true, type = input.bool,  title = "Take Profit", group = "Risk", inline = "Take Profit")
tpp = input(5.6,    type = input.float, title = "Percentage" , group = "Risk", step = 0.1, minval = 0.1, inline = "Take Profit")
tp  = strategy.position_avg_price + (strategy.position_avg_price / 100 * tpp)
plot (tpa and strategy.position_size > 0 ? tp : na, color = color.gray, title = "take profit", style= plot.style_linebr, linewidth = 1)

// Stop Loss
sla = input(true, type = input.bool, title = "Stop Lossss ", group = "Risk", inline = "Stop Loss")
slp = input(2.5,   type = input.float, title = "Percentage",   group = "Risk", step = 0.1, minval = 0.1, inline = "Stop Loss")
sl  = strategy.position_avg_price - (strategy.position_avg_price / 100 *slp)
plot (sla and strategy.position_size > 0 ? sl : na, color = color.red, title = "stopp loss", style= plot.style_linebr, linewidth = 1)

stopLoss = sla ? sl : na

// Long position entry layers. Percentage from the entry price of the the first long
ps2 = input(2, group = "Price Averaging Layers", title = "2nd Layer Long Entry %", step = 0.1)
ps3 = input(5, group = "Price Averaging Layers", title = "3rd Layer Long Entry %", step = 0.1)
ps4 = input(9, group = "Price Averaging Layers", title = "4th Layer Long Entry %", step = 0.1)

// ROC_Trigger Logic to open Long Position
rocLookBack  = input(3,   group = "ROC Logic to OPEN Long Entry", title="Rate of Change bar lookback")
rocThreshold = input(0.5, group = "ROC Logic to OPEN Long Entry", title="ROC Threshold % to Setup Long Entry", step = 0.1)
entryLimit   = input(0.5, group = "ROC Logic to OPEN Long Entry", title="Price Drop Threshold % to OPEN Long Entry", step = 0.1)
entryTime    = input(3,   group = "ROC Logic to OPEN Long Entry", title="Duration of Long Entry Threshold Line in bars")
minLimit     = input(0.8, group = "ROC Logic to OPEN Long Entry", title="Min % of Price Drop to OPEN Long Entry", step = 0.1)

//ROC calculation based to the price level of previous X bars
roc = close[rocLookBack]  - (close / 100 * rocThreshold)
plot (roc, color = color.gray, title = "roc threshold", linewidth = 1 , transp = 20)

rocT1      = open > roc and close < roc ? 1 : 0 // When the price CROSSES the Entry Limit
rocT2      = (open < roc) and (close < roc) ? 1 : 0 // When the price is BELOW the Entry Limit
rocTrigger = rocT1 or rocT2

// Condition for Setting Up a Long Entry Thershold Line
rocCrossed    = false
var SetUpLong = false

if rocTrigger and not SetUpLong

    rocCrossed := true
    SetUpLong  := true

// Defining the Value of the Long Entry Thershold
condforValue = rocCrossed and (open - low) / (open / 100) > 0 or (open < roc and close < roc) ? low - (close / 100 * entryLimit) : roc - (close / 100 * entryLimit)
openValue    = valuewhen (rocCrossed, condforValue, 0)

// Defining the length of the Long Entry Thershold in bars, specified with an input parameter
sincerocCrossed = barssince (rocCrossed)
plotLineOpen    = (sincerocCrossed <= entryTime) ? openValue : na
endLineOpen     = sincerocCrossed == entryTime  ? 1 : 0

// Set the conditions back to false when the Entry Limit Threshold Line ends after specied number of bars
if endLineOpen and SetUpLong
    
    rocCrossed := false
    SetUpLong  := false    

// Set minimum percentage of price drop to open a Long Position.
minThres = (open - close) / (open / 100) > minLimit ? 1 : 0

// Open Long Trigger
openLong = crossunder (close, plotLineOpen) and strategy.position_size == 0 and minThres

plot (strategy.position_size == 0 ? plotLineOpen : na, title = "Long Entry Threshold", color= color.yellow, style= plot.style_linebr, linewidth = 2)

// Show vertical dashed line when long condition is triggered 
// credit: @midtownsk8rguy, https://www.tradingview.com/script/EmTkvfCM-vline-Function-for-Pine-Script-v4-0/
vline(BarIndex, Color, LineStyle, LineWidth) => 
    return = line.new(BarIndex, low - tr, BarIndex, high + tr, xloc.bar_index, extend.both, Color, LineStyle, LineWidth) 
// if (openLong)
//     vline(bar_index, color.blue, line.style_dashed, 1)

// ROC_Trigger Logic to close Long Position
rocLookBackL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Rate of Change bar lookback")
entryThresholdL = input(0.8, group = "ROC Logic to CLOSE Long Entry", title = "ROC Threshold % to Setup Close Threshold", step = 0.1) // Percentage from close price
entryLimit_CL   = input(1.7, group = "ROC Logic to CLOSE Long Entry", title = "Price Rise Threshold % to CLOSE Long Entry", step = 0.1) // Percentage from roc threshold
entryTime_CL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Duration of Entry Limit in bars")

roc_CL = close[rocLookBackL]  + (close/100 *entryThresholdL)
//plot(rocL, color=color.gray, linewidth=1, transp=20)

rocT1_CL = open < roc_CL and close > roc_CL ? 1 : 0
rocT2_CL = (open > roc_CL) and (close > roc_CL)  ? 1 : 0 
rocTrigger_CL = rocT1_CL or rocT2_CL

// Condition for Setting Up a Long CLOSE Thershold Line
rocCrossed_CL  = false

var SetUpClose = false

if rocTrigger_CL and not SetUpClose
    // The trigger for condA occurs and the last condition set was condB.
    rocCrossed_CL := true
    SetUpClose    := true

// Defining the Value of the Long CLOSE Thershold
condforValue_CL= rocCrossed_CL and (high - open) / (open / 100) > 0 or (open > roc_CL and close > roc_CL) ? high + (close / 100 * entryLimit_CL) : roc_CL + (close / 100 * entryLimit_CL)
closeValue = valuewhen (rocCrossed_CL, condforValue_CL, 0)

// Defining the length of the Long CLOSE Thershold in bars, specified with an input parameter
sincerocCrossed_CL = barssince(rocCrossed_CL)
plotLineClose = (sincerocCrossed_CL <= entryTime_CL) ? closeValue : na
endLineClose = (sincerocCrossed_CL == entryTime_CL)  ? 1 : 0

// Set the conditions back to false when the CLOSE Limit Threshold Line ends after specied number of bars
if endLineClose and SetUpClose

    rocCrossed_CL := false
    SetUpClose := false    

plot(strategy.position_size > 0 ? plotLineClose : na, color = color.white, title = "Close Long Threshold", style = plot.style_linebr, linewidth = 2)

// ROC Close + Take Profit combined
closeCondition = close < tp ? plotLineClose : tpa ? tp : plotLineClose

// Store values to create and plot the different PA layers
long1 = valuewhen(openLong, close, 0)
long2 = valuewhen(openLong, close - (close / 100 * ps2), 0)
long3 = valuewhen(openLong, close - (close / 100 * ps3), 0)
long4 = valuewhen(openLong, close - (close / 100 * ps4), 0)

eps1 = 0.00
eps1 := na(eps1[1]) ? na : eps1[1]

eps2 = 0.00
eps2 := na(eps2[1]) ? na : eps2[1]

eps3 = 0.00
eps3 := na(eps3[1]) ? na : eps3[1]

eps4 = 0.00
eps4 := na(eps4[1]) ? na : eps4[1]

plot (strategy.position_size > 0 ? eps1 : na, title = "Long 1 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps2 : na, title = "Long 2 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps3 : na, title = "Long 3 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps4 : na, title = "Long 4 Layer", style = plot.style_linebr)

// Ener Long Positions
if (openLong and strategy.opentrades == 0) 
    eps1 := long1
    eps2 := long2
    eps3 := long3
    eps4 := long4
    strategy.entry("Long1", strategy.long, c, comment = "a=binance2 e=binance s=bnbusdt b=buy q=20% t=market")

if (strategy.opentrades == 1)
    strategy.entry("Long2", strategy.long, c, limit = eps2, comment = "a=binance2 e=binance s=bnbusdt b=buy q=25% t=market")

if (strategy.opentrades == 2)
    strategy.entry("Long3", strategy.long, c, limit = eps3, comment = "a=binance2 e=binance s=bnbusdt b=buy q=33.3% t=market")

if (strategy.opentrades == 3)
    strategy.entry("Long4", strategy.long, c, limit = eps4, comment = "a=binance2 e=binance s=bnbusdt b=buy q=50% t=market")

// Setup Limit Close / Take Profit / Stop Loss order 
strategy.exit("Exit", stop = stopLoss, limit = closeCondition, when =(rocTrigger_CL and strategy.position_size > 0), comment= "a=binance2 e=binance s=bnbusdt b=sell q=100% t=market")

// Make sure that all open limit orders are canceled after exiting all the positions 
longClose = strategy.position_size[1] > 0 and strategy.position_size == 0 ? 1 : 0   

if longClose
    strategy.cancel_all()