Chiến lược giao dịch dựa trên quy tắc có hệ thống độc đáo này thuộc thể loại xu hướng sau đây. Nó sử dụng các chuỗi giá chuẩn hóa được chuyển đổi từ giá ticker thô sang tín hiệu giao dịch tạo tỷ lệ. Các kỹ thuật quản lý rủi ro và quản lý rủi ro tiên tiến, thường được dành riêng cho quản lý danh mục đầu tư của tổ chức, được sử dụng trong chiến lược này - các công nghệ kiểm soát rủi ro và kiểm soát rủi ro đã được chứng minh được sử dụng bởi các cố vấn tài chính như cố vấn giao dịch hàng hóa và quỹ tương lai được quản lý.
Các giao dịch cốt lõi là đơn giản, dài khi giá được chuẩn hóa qua HMA, ngắn khi qua HMA.
Kích thước vị trí được điều chỉnh năng động dựa trên sự biến động giá gần đây và mục tiêu rủi ro hàng năm được người dùng xác định. Các vị trí được cân nhắc rủi ro, kích thước lớn hơn với biến động thấp hơn và nhỏ hơn với biến động cao hơn. Sự biến động gần đây là độ lệch chuẩn của lợi nhuận trong 14 giai đoạn gần đây, sau đó được ngoại suy vào biến động hàng năm như lợi nhuận dự kiến. Mục tiêu rủi ro hàng năm được sử dụng làm tham chiếu cho kích thước vị trí điều chỉnh biến động. Mục tiêu mặc định là 10% tổng vốn. Đầu tư ban đầu nên được đặt là lỗ tối đa mỗi giao dịch. Đòn bẩy tối đa cho phép đạt được mục tiêu rủi ro nếu biến động tự nhiên cơ bản là không đủ và giảm thiểu biến động quá thấp.
Các điểm dừng cứng dựa trên giá trung bình gần đây thực phạm vi nhân, người dùng có thể cấu hình.
Các biện pháp kiểm soát rủi ro bao gồm lựa chọn trung bình động thay thế, điều chỉnh các mục tiêu rủi ro.
Chiến lược này tích hợp các kỹ thuật khác nhau như bình thường hóa, điều chỉnh vị trí năng động, dừng cứng để kiểm soát rủi ro. Giao dịch dựa trên các quy tắc theo xu hướng đơn giản. Các tham số có thể được điều chỉnh theo sở thích cá nhân và chế độ thị trường. Đáng thử nghiệm và xác minh thêm cho ứng dụng thực tế khả thi.
/*backtest start: 2023-01-17 00:00:00 end: 2024-01-23 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/ // © Crunchster1 //@version=5 strategy(title="Crunchster's Normalised Trend Strategy", shorttitle="Normalised Trend Strategy", overlay=false ) // Inputs and Parameters src = input(close, 'Source', group='Strategy Settings') length = input.int(title="Lookback period for price normalisation filter", defval=14, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the volatility adjustment of returns, which is used to transform the price series into the "real price"') hlength = input.int(title="Lookback period for Hull Moving Average", defval=100, minval=2, group='Strategy Settings') offset = input.int(title="HMA Offset", defval=0, minval=0, group='Strategy Settings') long = input(true, 'Long', inline='08', group='Strategy Settings') short = input(true, 'Short', inline='08', group='Strategy Settings', tooltip='Toggle long/short strategy on/off') stopMultiple = input.float(1, 'Stop multiple', step=0.25, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price') 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(10, 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(false, '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 = true // Normalised returns calculation nRet = (src - src[1]) / ta.stdev((src - src[1]), length) nPrice = ta.cum(nRet) //Hull Moving Average - using normalised price series fHMA = ta.wma(2 * ta.wma(nPrice[offset], hlength / 2) - ta.wma(nPrice[offset], hlength), math.round(math.sqrt(hlength))) //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 // Strategy Rules if long longCondition = ta.crossover(nPrice, fHMA) and window exitlong = ta.crossunder(nPrice, fHMA) if (longCondition) strategy.entry('Go Long!', strategy.long, qty=shares) if strategy.position_size > 0 strategy.exit('Stop Long', from_entry = 'Go Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple))) if (exitlong) strategy.close('Go Long!', immediately = true) if short shortCondition = ta.crossunder(nPrice, fHMA) and window exitshort = ta.crossover(nPrice, fHMA) if (shortCondition) strategy.entry('Go Short!', strategy.short, qty=shares) if strategy.position_size < 0 strategy.exit('Stop Short', from_entry = 'Go Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple))) if (exitshort) strategy.close('Go Short!', immediately = true) // Visuals of trend and direction plot(nPrice, title='Real Price', color=color.black) MAColor = fHMA > fHMA[3] ? #00ff00 : #ff0000 MA1 = plot(fHMA, title='Hull MA', color=MAColor) MA2 = plot(fHMA[3], title='Hull MA Offset', color=MAColor) fill(MA1, MA2, title='Band Filler', color=MAColor)