
Die Strategie verwendet den gewichteten Standard Differenz-Indikator in Kombination mit einem Moving Average, um Trend-Handel mit Kryptowährungen zu realisieren. Die Strategie berechnet den gewogenen Standard Differenz-Kanal des Preises anhand des Schlusskurses und der Transaktionsmenge in einem bestimmten Zeitraum.
Der Code definiert zwei benutzerdefinierte Funktionen, die jeweils abweichend von der gewichteten Standarddifferenz für die Berechnung von Zeitreihen und Arrays berechnet werden. Die wichtigsten Schritte sind:
Auf diese Weise erhalten wir einen Kanal mit einer gewogenen Durchschnittspreis in der Mitte und einer Standarddifferenz in der Unterseite. Wenn der Preis von unten den unteren Teil des Kanals durchbricht, machen wir mehr; wenn er von oben den oberen Teil des Kanals durchbricht, machen wir weniger.
Der größte Vorteil dieser Strategie besteht darin, dass sie eine Kombination aus Moving Average und Volatilitätsanalyse darstellt. Die Moving Average beurteilt die Richtung der Markttrends, die Standarddifferenz definiert einen angemessenen Bereich, die sich gegenseitig verifizieren und eine hohe Zuverlässigkeit aufweisen. Darüber hinaus kann das Transaktionsgewicht falsche Durchbrüche filtern und die Wahrscheinlichkeit eines tatsächlichen Durchbruchs ist höher.
Die Strategie bietet auch einen Stop-Loss-Stop, um den Trend zu erfassen und zu vermeiden, dass ein Umkippen zu einem übermäßigen Verlust führt. Dies ist ein Punkt, den viele Anfänger nicht beherrschen können.
Das Risiko besteht hauptsächlich darin, dass die Märkte stark schwanken können. In diesem Fall schwanken auch die Standardabweichungskanäle erheblich und sind für die Beurteilung nicht geeignet. Darüber hinaus ist die Fehlerrate hoch, wenn die Auswahlperiode zu kurz ist und leicht durch Lärm gestört wird.
Die Gegenmaßnahme ist, dass die Periodiparameter angepasst werden können, um die Kurve zu glätten. Es kann auch in Kombination mit anderen Indikatoren wie dem RSI in Betracht gezogen werden, um die Bestätigung des Durchbruchs zu erhöhen.
Die Strategie nutzt erfolgreich den gewichteten Standard-Differenz-Indikator, unterstützt durch die Beurteilung der Richtung durch bewegliche Durchschnitte, um die Trends für Kryptowährungen zu verfolgen. Gleichzeitig hilft eine vernünftige Stop-Loss-Einstellung, die Marktdynamik zu erfassen und zu verhindern, dass eine übermäßige Umkehr zu Verlusten führt. Durch die Parameteranpassung und Multi-Indikator-Verifizierung kann die Strategie weiter optimiert und eine zuverlässige quantitative Handelsstrategie gebildet werden.
/*backtest
start: 2023-11-16 00:00:00
end: 2023-11-23 00:00:00
period: 45m
basePeriod: 5m
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/
// © rumpypumpydumpy © cache_that_pass
//@version=4
strategy("[cache_that_pass] 1m 15m Function - Weighted Standard Deviation", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=20, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.075)
f_weighted_sd_from_series(_src, _weight, _n) => //{
// @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from time series variables
// @parameters:
// _src: time series variable of sample values
// _weight: time series of corresponding weight values.
// _n : number of samples
_xw = _src * _weight
_sum_weight = sum(_weight, _n)
_mean = sum(_xw, _n) / _sum_weight
float _sqerror_sum = 0
int _nonzero_n = 0
for _i = 0 to _n - 1
_sqerror_sum := _sqerror_sum + pow(_mean - _src[_i], 2) * _weight[_i]
_nonzero_n := _weight[_i] != 0 ? _nonzero_n + 1 : _nonzero_n
_variance = _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
_dev = sqrt(_variance)
_mse = _sqerror_sum / _sum_weight
_rmse = sqrt(_mse)
[_mean, _variance, _dev, _mse, _rmse]
//}
// -----------------------------------------------------------------------------
f_weighted_sd_from_arrays(_a_src, _a_weight, _n) => //{
// @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from arrays
// Expects index 0 of the arrays to be the most recent sample and weight values!
// @parameters:
// _a_src: array of sample values
// _a_weight: array of corresponding weight values.
// _n : number of samples
float _mean = na, float _variance = na, float _dev = na, float _mse = na
float _rmse = na, float _sqerror_sum = na, float _sum_weight = na
float[] _a_xw = array.new_float(_n)
int _nonzero_n = 0
if array.size(_a_src) >= _n
_sum_weight := 0
_sqerror_sum := 0
for _i = 0 to _n - 1
array.set(_a_xw, _i, array.get(_a_src, _i) * array.get(_a_weight, _i))
_sum_weight := _sum_weight + array.get(_a_weight, _i)
_nonzero_n := array.get(_a_weight, _i) != 0 ? _nonzero_n + 1 : _nonzero_n
_mean := array.sum(_a_xw) / _sum_weight
for _j = 0 to _n - 1
_sqerror_sum := _sqerror_sum + pow(_mean - array.get(_a_src, _j), 2) * array.get(_a_weight, _j)
_variance := _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
_dev := sqrt(_variance)
_mse := _sqerror_sum / _sum_weight
_rmse := sqrt(_mse)
[_mean, _variance, _dev, _mse, _rmse]
//}
// -----------------------------------------------------------------------------
// Example usage :
// -----------------------------------------------------------------------------
len = input(20)
// -----------------------------------------------------------------------------
// From series :
// -----------------------------------------------------------------------------
[m, v, d, mse, rmse] = f_weighted_sd_from_series(close, volume, len)
plot(m, color = color.blue)
plot(m + d * 2, color = color.blue)
plot(m - d * 2, color = color.blue)
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// From arrays :
// -----------------------------------------------------------------------------
var float[] a_src = array.new_float()
var float[] a_weight = array.new_float()
if barstate.isfirst
for i = 1 to len
array.unshift(a_weight, i)
array.unshift(a_src, close)
if array.size(a_src) > len
array.pop(a_src)
[a_m, a_v, a_d, a_mse, a_rmse] = f_weighted_sd_from_arrays(a_src, a_weight, len)
plot(a_m, color = color.orange)
plot(a_m + a_d * 2, color = color.orange)
plot(a_m - a_d * 2, color = color.orange)
// -----------------------------------------------------------------------------
series_text = "Mean : " + tostring(m) + "\nVariance : " + tostring(v) + "\nSD : " + tostring(d) + "\nMSE : " + tostring(mse) + "\nRMSE : " + tostring(rmse)
array_text = "Mean : " + tostring(a_m) + "\nVariance : " + tostring(a_v) + "\nSD : " + tostring(a_d) + "\nMSE : " + tostring(a_mse) + "\nRMSE : " + tostring(a_rmse)
debug_text = "Volume weighted from time series : \n" + series_text + "\n\nLinearly weighted from arrays : \n" + array_text
//debug = label.new(x = bar_index, y = close, text = debug_text, style = label.style_label_left)
//.delete(debug[1])
//test strategy
if low <= (m - d * 2)
strategy.entry("LE", strategy.long)
if high >= (m + d * 2)
strategy.entry("SE", strategy.short)
// User Options to Change Inputs (%)
stopPer = input(3.11, title='Stop Loss %', type=input.float) / 100
takePer = input(7.50, title='Take Profit %', type=input.float) / 100
// Determine where you've entered and in what direction
longStop = strategy.position_avg_price * (1 - stopPer)
shortStop = strategy.position_avg_price * (1 + stopPer)
shortTake = strategy.position_avg_price * (1 - takePer)
longTake = strategy.position_avg_price * (1 + takePer)
if strategy.position_size > 0
strategy.exit(id="Close Long", stop=longStop, limit=longTake)
// strategy.close("LE", when = (longStop) or (longTake), qty_percent = 100)
if strategy.position_size < 0
strategy.exit(id="Close Short", stop=shortStop, limit=shortTake)
// strategy.close("SE", when = (shortStop) or (shortTake), qty_percent = 100)