이 전략은 암호화폐에 대한 트렌드 거래를 구현하기 위해 가중 표준편차 지표와 이동 평균을 결합하여 사용합니다. 특정 기간 동안의 폐쇄 가격과 볼륨에 따라 가중 표준편차 가격 채널을 계산합니다. 가격이 상위 또는 하위 채널을 통과하면 긴 또는 짧은 포지션을 취합니다. 거래 당 손실을 제한하기 위해 스톱 손실 및 수익 조건도 설정됩니다.
코드는 시간 계열과 배열에서 중량 표준편차를 계산하는 두 가지 사용자 정의 함수를 정의합니다. 주요 단계는 다음과 같습니다.
이것은 가중 평균 가격 중심의 채널을 제공합니다. 상단과 하단 한계가 표준편차에서 떨어져 있습니다. 가격이 채널 하단에서 넘어지면, 길게 가십시오. 위에서 상단으로 넘어지면, 짧게 가십시오.
이 전략의 가장 큰 장점은 이동 평균과 변동성 분석의 조합입니다. MA는 시장 트렌드 방향을 판단하고 SD 범위는 합리적인 대역을 정의합니다. 둘 다 더 높은 신뢰성을 위해 서로를 검증합니다. 또한 볼륨 가중화는 실제 파업에서 더 높은 성공 확률을 위해 잘못된 파장을 필터하는 데 도움이됩니다.
스톱 로스 및 영업 포인트 는 추세 에 따라 거래 하는 데 더 도움 이 되고, 역전 에 대한 과도 한 손실 을 피 하는 데 도움 이 된다. 이것은 많은 초보 트레이더 들 이 실행 하지 못하는 미묘 한 방법 이다.
주요 위험은 시장의 격렬한 변동입니다. 이것은 SD 채널이 야만적으로 변동 할 수 있으며 판단을 어렵게 할 수 있습니다. 또한 너무 짧은 기간을 선택하는 것은 소음과 오류에 의해 오해 될 위험이 있습니다.
치료법은 매개 변수와 기간 설정을 적절하게 매끄럽게 하는 것입니다. 브레이크아웃 확인을 향상시키기 위해 RSI와 같은 다른 지표를 결합하는 것을 고려하십시오.
이 전략은 암호화폐 트렌드를 추적하기 위해 MA와 함께 가중 표준 편차 지표를 성공적으로 사용합니다. 합리적인 스톱 로스/트랙 노프트 설정은 또한 거래 시장 리듬을 돕고 과도한 역전 손실을 피합니다. 매개 변수 조정 및 멀티 지표 확인을 통한 추가 최적화는 탄탄한 알고 거래 전략의 신뢰성을 향상시킬 수 있습니다.
/*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)