Hệ thống theo dõi xu hướng tái cân bằng vị trí động

Tác giả:ChaoZhang, Ngày: 2024-01-26 14:41:08
Tags:

img

Tổng quan

Chiến lược này tích hợp hệ thống chéo trung bình động theo cấp số nhân và hệ thống giao dịch rùa, hai chiến lược giao dịch có hệ thống phổ biến. Nó được thiết kế đặc biệt cho khung thời gian hàng ngày để theo dõi xu hướng thị trường trong thời gian thực bằng cách quản lý vị trí năng động.

Chiến lược logic

Chiến lược bao gồm hai chiến lược phụ: chiến lược xu hướng và chiến lược phá vỡ.

Chiến lược xu hướng sử dụng EMA nhanh và EMA chéo chậm như các tín hiệu giao dịch. Thời gian EMA nhanh được người dùng xác định và thời gian EMA chậm là 5 lần so với EMA nhanh.

Chiến lược đột phá sử dụng mức trung bình của giá cao nhất và thấp nhất trong một khoảng thời gian nhìn lại cố định như đường cơ sở.

Kích thước vị trí dựa trên biến động giá gần đây và mục tiêu rủi ro hàng năm được xác định bởi người dùng. Kích thước lớn hơn được lấy khi biến động thấp trong khi kích thước nhỏ hơn được lấy khi biến động cao. Điều này nhận ra quản lý vị trí năng động với điều chỉnh rủi ro.

Các điểm dừng cứng được thiết lập là số nhân của phạm vi trung bình thực sự. Các điểm dừng theo sau là mức giá cao nhất gần đây hoặc thấp nhất gần đây.

Phân tích lợi thế

Những lợi thế chính của chiến lược này bao gồm:

  1. Kết hợp các chiến lược phụ theo dõi xu hướng và đột phá thích nghi với môi trường thị trường khác nhau với độ bền mạnh mẽ.

  2. Ứng dụng các kỹ thuật định kích thước vị trí và quản lý rủi ro tiên tiến quản lý vị trí một cách năng động và kiểm soát rủi ro hiệu quả.

  3. Các vị trí điều chỉnh biến động dựa trên biến động gần đây và mục tiêu rủi ro hàng năm duy trì rủi ro danh mục tương đối ổn định trên các chế độ biến động cao / thấp.

  4. Thiết lập stop loss dựa trên biến động giá thực tế tránh những lỗ nhỏ không cần thiết từ các stop run.

  5. Điều chỉnh trailing stop trong thời gian thực linh hoạt theo xu hướng để ghi lại lợi nhuận và dừng lại kịp thời.

Phân tích rủi ro

Những rủi ro chính của chiến lược này là:

  1. Tùy thuộc vào tối ưu hóa tham số. Các tham số khác nhau ảnh hưởng đáng kể đến hiệu suất chiến lược vì vậy cần phải thử nghiệm toàn diện để tìm các tham số tối ưu.

  2. Lượng dừng thường xuyên trong các xu hướng hỗn loạn.

  3. Nhạy cảm đối với vốn ban đầu và chi phí giao dịch: vốn ban đầu không đủ và chi phí giao dịch cao ảnh hưởng tiêu cực đến lợi nhuận.

  4. Sự dựa vào ước tính biến động chính xác để định kích thước vị trí và kiểm soát rủi ro.

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

Các hướng tối ưu hóa chính bao gồm:

  1. Tìm kiếm các bộ tham số tối ưu thông qua kiểm tra ngược nhiều hơn với bộ dữ liệu lịch sử lớn hơn.

  2. Cải thiện cơ chế dừng bằng cách thử nghiệm các điểm dừng khác nhau như dừng di chuyển, dừng thời gian, dừng biến động v.v.

  3. Tối ưu hóa kích thước vị trí và quản lý rủi ro bằng cách thử nghiệm các mục tiêu rủi ro khác nhau để tìm ra hồ sơ rủi ro-lợi nhuận tốt nhất.

  4. Cố gắng thêm các chỉ số phụ để cải thiện độ chính xác tín hiệu và tính mạnh mẽ của chiến lược.

  5. Kiểm tra các khoảng thời gian giữ khác nhau bằng cách hỗ trợ quyết định với các tín hiệu khung thời gian cao hơn để cải thiện độ chính xác phân bổ vị trí.

Kết luận

Chiến lược này tích hợp hai loại chính của các chiến lược giao dịch: theo xu hướng và đột phá. Bằng cách áp dụng các kỹ thuật điều chỉnh vị trí năng động tiên tiến, nó kiểm soát hiệu quả rủi ro trong khi theo dõi các chuyển động của thị trường để kiếm lợi nhuận. Nó thể hiện tiềm năng lợi nhuận mạnh và đáng để thử nghiệm và tối ưu hóa thêm.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
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/
// © Crunchster1

//@version=5
strategy(title="Crunchster's Turtle and Trend System", shorttitle="Turtle Trend", overlay=true, slippage=10, pyramiding=1, precision = 4, calc_on_order_fills = false, calc_on_every_tick = false, default_qty_value = 0.1, initial_capital = 1000, commission_value = 0.06, process_orders_on_close = true)

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for fast EMA", defval=10, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the fast exponential moving average. The slow EMA is 5x the fast EMA length')
blength = input.int(title="Lookback period for Breakout", defval=20, minval=5, step=5, group='Strategy Settings')

long = input(true, 'Long', inline='08', group='Strategy toggle')
short = input(true, 'Short', inline='08', group='Strategy toggle', tooltip='Toggle long/short strategy on/off')

EMAwt = input(false, 'Trend', inline='01', group='Strategy toggle')
breakwt = input(true, 'Breakout', inline='01', group='Strategy toggle', tooltip='Toggle trend/breakout strategy on/off')

stopMultiple = input.float(2, 'Stop multiple', step=0.5, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
trail = input.int(10, 'Trail lookback', step=5, group='Risk Management Settings', tooltip='Lookback period for the trailing stop')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(15, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(true, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')

// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')

start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = time >= start and time <= finish

// Breakout strategy
lower = ta.lowest(low[1], blength)
upper = ta.highest(high[1], blength)
basis = math.avg(upper, lower)
signal = 20*(close - basis) / (upper - lower)

// Trend strategy
fEMA = ta.ema(close[1], length)
sEMA = ta.ema(close[1], length*5)
emadiff = fEMA - sEMA
nemadiff = 5*emadiff/(ta.stdev(close - close[1], 252))

//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe

risk = 1.1
if comp
    risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
    risk := strategy.initial_capital

shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
    shares := lev*maxcapital/close

//To set the price at the entry point of trade
Posopen() =>
    math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0

var float openN = na
if Posopen()
    openN := stopL

// Trailing stop
tlower = ta.lowest(low[1], trail)
tupper = ta.highest(high[1], trail)
tbasis = math.avg(tupper, tlower)
tsignal = 20*(close - tbasis) / (tupper - tlower)

// Strategy Rules
if EMAwt
    if long
        longCondition2 = (nemadiff >2 and nemadiff[1] <2) and window
        exitlong = tsignal <= -10
        if (longCondition2)
            strategy.entry('Trend Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Trend Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Trend Long!', immediately = true)

    if short
        shortCondition2 = (nemadiff <-1 and nemadiff[1] >-1) and window
        exitshort = tsignal >= 10
        if (shortCondition2)
            strategy.entry('Trend Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Trend Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Trend Short!', immediately = true)

if breakwt
    if long
        longCondition1 = (signal >= 10) and window
        exitlong = tsignal <= -10
        if (longCondition1)
            strategy.entry('Break Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Break Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Break Long!', immediately = true)

    if short
        shortCondition1 = (signal <= -10) and window
        exitshort = tsignal >= 10
        if (shortCondition1)
            strategy.entry('Break Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Break Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Break Short!', immediately = true)

// Visuals of trend and direction
plot(nemadiff, title='EMA Forecast', color=color.black, display=display.none)
plot(ta.sma(ta.median(math.sqrt(math.pow(nemadiff,2)), 700), 350), 'Forecast mean', color=color.rgb(245, 0, 0), display=display.none)

MAColor = fEMA > sEMA ? #00ff00 : #ff0000
MA1 = plot(fEMA, title='Fast EMA', color=MAColor)
MA2 = plot(sEMA, title='Slow EMA', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)

Thêm nữa