
Diese einzigartige, regulierte und systematisierte Handelsstrategie gehört in die Kategorie Trendfollowing. Sie generiert Handelssignale durch die Verwendung von Preise, die durch Preisuniformisierung erzeugt wurden, anstatt direkt mit den Aktienpreisen. Die Strategie nutzt die Techniken der fortgeschrittenen Positionsanpassung und Risikomanagement, die normalerweise nur in der Portfolio-Management-Institution verwendet werden, als Beweis für die Positionsanpassung von Commodity Trading Advisors (CTAs) und Futures-Fonds.
Der Regulierungspreis ist die kumulierte Tagesrendite des Preises, berechnet aus der gesamten Zeitreihenfolge der Preise. Die Regulierungsfrequenz wird vom Benutzer definiert. Auf der Grundlage des Regulierungspreises wird der Hull Moving Average berechnet und dient als Hauptindikator für die Trendbeurteilung.
Der Kern der Handelsstrategie ist sehr einfach: Der Regulierungspreis überschreitet den Hull Moving Average nach oben und überschreitet den Kaufkurs nach unten. Die neuen Handelssignale werden die alten umgekehrten Positionen aktiv ausgleichen.
Positionsgröße basiert auf der jüngsten Preisfluktuation und dem vom Benutzer definierten jährlichen Risikoziel. Im Wesentlichen wird die Positionsgröße nach der Volatilität angepasst. Bei geringer Volatilität wird eine größere Position gehalten, bei hoher Volatilität eine kleinere Position. Die jüngste Volatilität beträgt die 14-tägige Preisdifferenz-Rendite-Standarddifferenz, die auf die erwartete jährliche Volatilität übertragen wird.
Die Stop-Loss-Einstellungen basieren auf den Faktoren der aktuellen, durchschnittlich realen Preisbewegungen.
Risikokontrollmaßnahmen umfassen die Nutzung verschiedener Moving Average-Kombinationen, die Anpassung der Positionsrisikoziele usw.
Die Strategie integriert mehrere Technologien, um Risiken zu kontrollieren, wie z. B. Preisuniformisierung, dynamische Verlagerung, Stop-Loss usw. Die Verwendung von einfachen Trend-Follow-Prinzipien für den Handel. Die Parameter können nach Markt- und persönlichen Bedingungen angepasst und optimiert werden.
/*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)