Xu hướng sau chiến lược MA dừng lỗ chuyển động

Tác giả:ChaoZhang, Ngày: 2023-10-10 10:36:16
Tags:

Tổng quan

Chiến lược này sử dụng sự kết hợp của trung bình động và chỉ số sức mạnh tương đối để xác định hướng xu hướng, và thực hiện một cơ chế dừng lỗ để đạt được mục tiêu lợi nhuận. Nó phù hợp với thị trường biến động cao, cho phép nhập thị trường nhanh chóng sau khi xu hướng được hình thành và đảm bảo lợi nhuận thông qua dừng lỗ và lấy lợi nhuận.

Chiến lược logic

Chiến lược này sử dụng chỉ số RSI để xác định xu hướng thị trường hiện tại. RSI dưới 30 được coi là giảm, trong khi trên 70 được coi là tăng. Khi RSI crossover báo hiệu xu hướng tăng, nó sẽ dài. Khi RSI crossover báo hiệu xu hướng giảm, nó sẽ ngắn.

Sau khi mở các vị trí, chiến lược sử dụng một cơ chế dừng lỗ di chuyển để theo dõi thay đổi giá và khóa lợi nhuận. Cụ thể, nó ghi lại giá nhập trung bình của mỗi vị trí. Khi giá đạt 1% giá nhập, nó sẽ kích hoạt cơ chế dừng lỗ di chuyển, di chuyển đường dừng lỗ dựa trên sự khác biệt giữa giá hiện tại và giá cao nhất.

Khi giá đạt mức dừng lỗ, nó sẽ thoát khỏi vị trí. Khi giá đạt 3% giá nhập cảnh, nó sẽ kiếm lợi nhuận. Bằng cách sử dụng bảo vệ kép chống lại dừng lỗ và lấy lợi nhuận, nó đạt được mục tiêu lợi nhuận.

Ưu điểm

  • Sử dụng chỉ số RSI để xác định hướng xu hướng cho phép đánh giá nhanh về động lực thị trường
  • Di chuyển dừng lỗ có thể linh hoạt điều chỉnh mức dừng lỗ dựa trên thay đổi giá thời gian thực, tránh dừng lỗ sớm
  • Bảo vệ hai lần chống lại dừng lỗ và lấy lợi nhuận đảm bảo lợi nhuận nhất định trong khi kiểm soát rủi ro

Rủi ro

  • RSI có thể báo hiệu nhập sai nếu sử dụng một mình
  • Khoảng cách dừng lỗ quá nhỏ có thể kích hoạt dễ dàng, trong khi quá lỏng lẻo có thể không dừng lỗ
  • Việc thiết lập lợi nhuận không chính xác cũng có thể không đạt được mục tiêu lợi nhuận

Các chỉ số bổ sung có thể được thêm vào để xác nhận các tín hiệu RSI và giảm các tín hiệu sai. Tối ưu hóa mức dừng lỗ và lấy lợi nhuận dựa trên kiểm tra ngược cũng có thể giúp tìm ra sự kết hợp thông số tốt nhất.

Tối ưu hóa

  • Thêm Bollinger Bands hoặc KD để xác nhận tín hiệu xu hướng và tránh các mục nhập sai
  • Nghiên cứu sử dụng cộng và nhân để mở rộng sự kết hợp của các chỉ số
  • Cố gắng xác nhận nhiều khung thời gian để tránh tín hiệu sai trên khung thời gian duy nhất
  • Nghiên cứu cơ chế dừng lỗ thích nghi để điều chỉnh khoảng cách dừng dựa trên biến động thị trường

Tóm lại

Nhìn chung, đây là một chiến lược theo xu hướng rất chuyên nghiệp và đáng tin cậy. Nó có thể nhanh chóng xác định hướng thị trường và khóa lợi nhuận thông qua việc di chuyển dừng lỗ và lấy lợi nhuận. Tăng thêm các tham số tối ưu hóa và thêm các chỉ số xác nhận có thể cải thiện tỷ lệ thắng và độ tin cậy. Với logic rõ ràng và các tham số linh hoạt, nó là một ví dụ rất tốt cho việc học các chiến lược giao dịch lượng.


/*backtest
start: 2022-10-03 00:00:00
end: 2023-10-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
// Learn more about Autoview and how you can automate strategies like this one here: https://autoview.with.pink/
// strategy("Autoview Build-a-bot - 1m chart", "Strategy", overlay=true, pyramiding=2000, default_qty_value=10000)
// study("Autoview Build-a-bot", "Alerts")

///////////////////////////////////////////////
//* Backtesting Period Selector | Component *//
///////////////////////////////////////////////

//* https://www.tradingview.com/script/eCC1cvxQ-Backtesting-Period-Selector-Component *//
//* https://www.tradingview.com/u/pbergden/ *//
//* Modifications made *//

testStartYear = input(1, "Backtest Start Year") 
testStartMonth = input(11, "Backtest Start Month")
testStartDay = input(10, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)

testStopYear = input(77777777, "Backtest Stop Year")
testStopMonth = input(11, "Backtest Stop Month")
testStopDay = input(15, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)

testPeriod() => true

/////////////////////////////////////
//* Put your strategy logic below *//
/////////////////////////////////////
RSIlength = input(6,title="RSI Period Length") 
price = close
vrsi = (rsi(price, RSIlength))
src = close
len = input(2, minval=1, title="Length")

up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

rsin = input(14)
sn = 100 - rsin
ln = 0 + rsin

// Put your long and short rules here
longLocic = crossunder(rsi, ln)
shortLogic = crossover(rsi, sn)

//////////////////////////
//* Strategy Component *//
//////////////////////////

isLong = input(true, "Longs Only")
isShort = input(false, "Shorts Only")
isFlip = input(false, "Flip the Opens")

long = longLocic
short = shortLogic

if isFlip
    long := shortLogic
    short := longLocic
else
    long := longLocic
    short := shortLogic

if isLong
    long := long
    short := na

if isShort
    long := na
    short := short
    
////////////////////////////////
//======[ Signal Count ]======//
////////////////////////////////

sectionLongs = 0
sectionLongs := nz(sectionLongs[1])
sectionShorts = 0
sectionShorts := nz(sectionShorts[1])

if long
    sectionLongs := sectionLongs + 1
    sectionShorts := 0

if short
    sectionLongs := 0
    sectionShorts := sectionShorts + 1

//////////////////////////////
//======[ Pyramiding ]======//
//////////////////////////////

pyrl = input(2, "Pyramiding less than") // If your count is less than this number
pyre = input(1, "Pyramiding equal to") // If your count is equal to this number
pyrg = input(1000000, "Pyramiding greater than") // If your count is greater than this number

longCondition = long and sectionLongs <= pyrl or long and sectionLongs >= pyrg or long and sectionLongs == pyre ? 1 : 0 and vrsi < 20
shortCondition = short and sectionShorts <= pyrl or short and sectionShorts >= pyrg or short and sectionShorts == pyre ? 1 : 0

////////////////////////////////
//======[ Entry Prices ]======//
////////////////////////////////

last_open_longCondition = na
last_open_shortCondition = na
last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])
last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1])

////////////////////////////////////
//======[ Open Order Count ]======//
////////////////////////////////////

sectionLongConditions = 0
sectionLongConditions := nz(sectionLongConditions[1])
sectionShortConditions = 0
sectionShortConditions := nz(sectionShortConditions[1])

if longCondition
    sectionLongConditions := sectionLongConditions + 1
    sectionShortConditions := 0

if shortCondition
    sectionLongConditions := 0
    sectionShortConditions := sectionShortConditions + 1
    
///////////////////////////////////////////////
//======[ Position Check (long/short) ]======//
///////////////////////////////////////////////

last_longCondition = na
last_shortCondition = na
last_longCondition := longCondition ? time : nz(last_longCondition[1])
last_shortCondition := shortCondition ? time : nz(last_shortCondition[1])

in_longCondition = last_longCondition > last_shortCondition
in_shortCondition = last_shortCondition > last_longCondition

/////////////////////////////////////
//======[ Position Averages ]======//
/////////////////////////////////////

totalLongs = 0.0
totalLongs := nz(totalLongs[1])
totalShorts = 0.0
totalShorts := nz(totalShorts[1])
averageLongs = 0.0
averageLongs := nz(averageLongs[1])
averageShorts = 0.0
averageShorts := nz(averageShorts[1]) 

if longCondition
    totalLongs := totalLongs + last_open_longCondition
    totalShorts := 0.0

if shortCondition
    totalLongs := 0.0
    totalShorts := totalShorts + last_open_shortCondition

averageLongs := totalLongs / sectionLongConditions
averageShorts := totalShorts / sectionShortConditions

/////////////////////////////////
//======[ Trailing Stop ]======//
/////////////////////////////////

isTS = input(false, "Trailing Stop")
tsi = input(100, "Activate Trailing Stop Price (%). Divided by 100 (1 = 0.01%)") / 100 
ts = input(100, "Trailing Stop (%). Divided by 100 (1 = 0.01%)") / 100

last_high = na
last_low = na
last_high_short = na
last_low_short = na
last_high := not in_longCondition ? na : in_longCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_high_short := not in_shortCondition ? na : in_shortCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_shortCondition ? na : in_shortCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])
last_low_short := not in_longCondition ? na : in_longCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

long_ts = isTS and not na(last_high) and low <= last_high - last_high / 100 * ts and longCondition == 0 and last_high >= averageLongs + averageLongs / 100 * tsi
short_ts = isTS and not na(last_low) and high >= last_low + last_low / 100 * ts and shortCondition == 0 and last_low <= averageShorts - averageShorts/ 100 * tsi

///////////////////////////////
//======[ Take Profit ]======//
///////////////////////////////

isTP = input(true, "Take Profit")
tp = input(33, "Take Profit (%). Divided by 100 (1 = 0.01%)") / 100
long_tp = isTP and close > averageLongs + averageLongs / 100 * tp and not longCondition
short_tp = isTP and close < averageShorts - averageShorts / 100 * tp and not shortCondition

/////////////////////////////
//======[ Stop Loss ]======//
/////////////////////////////

isSL = input(true, "Stop Loss")
sl = input(55, "Stop Loss (%). Divided by 100 (1 = 0.01%)") / 100
long_sl = isSL and close < averageLongs - averageLongs / 100 * sl and longCondition == 0
short_sl = isSL and close > averageShorts + averageShorts / 100 * sl and shortCondition == 0

/////////////////////////////////
//======[ Close Signals ]======//
/////////////////////////////////

longClose = long_tp or long_sl or long_ts ? 1 : 0
shortClose = short_tp or short_sl or short_ts ? 1: 0

///////////////////////////////
//======[ Plot Colors ]======//
///////////////////////////////

longCloseCol = na
shortCloseCol = na
longCloseCol := long_tp ? purple : long_sl ? maroon : long_ts ? blue : longCloseCol[1]
shortCloseCol := short_tp ? purple : short_sl ? maroon : short_ts ? blue : shortCloseCol[1]
tpColor = isTP and in_longCondition ? purple : isTP and in_shortCondition ? purple : white
slColor = isSL and in_longCondition ? red : isSL and in_shortCondition ? red : white

//////////////////////////////////
//======[ Strategy Plots ]======//
//////////////////////////////////

plot(isTS and in_longCondition ? averageLongs + averageLongs / 100 * tsi : na, "Long Trailing Activate", blue, style=3, linewidth=2)
plot(isTS and in_longCondition and last_high >= averageLongs +  averageLongs / 100 * tsi ? last_high - last_high / 100 * ts : na, "Long Trailing", fuchsia, style=2, linewidth=3)
plot(isTS and in_shortCondition ? averageShorts - averageShorts/ 100 * tsi : na, "Short Trailing Activate", blue, style=3, linewidth=2)
plot(isTS and in_shortCondition and last_low <= averageShorts - averageShorts/ 100 * tsi ? last_low + last_low / 100 * ts : na, "Short Trailing", fuchsia, style=2, linewidth=3)
plot(isTP and in_longCondition and last_high < averageLongs + averageLongs / 100 * tp ? averageLongs + averageLongs / 100 * tp : na, "Long TP", tpColor, style=3, linewidth=2)
plot(isTP and in_shortCondition and last_low > averageShorts - averageShorts / 100 * tp ? averageShorts - averageShorts / 100 * tp : na, "Short TP", tpColor, style=3, linewidth=2)
plot(isSL and in_longCondition and last_low_short > averageLongs - averageLongs / 100 * sl ? averageLongs - averageLongs / 100 * sl : na, "Long SL", slColor, style=3, linewidth=2)
plot(isSL and in_shortCondition and last_high_short < averageShorts + averageShorts / 100 * sl ? averageShorts + averageShorts / 100 * sl : na, "Short SL", slColor, style=3, linewidth=2)

///////////////////////////////
//======[ Alert Plots ]======//
///////////////////////////////

// plot(longCondition, "Long", green)
// plot(shortCondition, "Short", red)
// plot(longClose, "Long Close", longCloseCol)
// plot(shortClose, "Short Close", shortCloseCol)

///////////////////////////////////
//======[ Reset Variables ]======//
///////////////////////////////////

if longClose or not in_longCondition
    averageLongs := 0
    totalLongs := 0.0
    sectionLongs := 0
    sectionLongConditions := 0

if shortClose or not in_shortCondition
    averageShorts := 0
    totalShorts := 0.0
    sectionShorts := 0
    sectionShortConditions := 0

////////////////////////////////////////////
//======[ Strategy Entry and Exits ]======//
////////////////////////////////////////////

if testPeriod()
    strategy.entry("Long", 1, when=longCondition)
    strategy.entry("Short", 0,  when=shortCondition)
    strategy.close("Long", when=longClose)
    strategy.close("Short", when=shortClose)
    


Thêm nữa