이동 평균 가중 표준 편차 거래 전략


생성 날짜: 2023-11-24 13:54:58 마지막으로 수정됨: 2023-11-24 13:54:58
복사: 0 클릭수: 776
avatar of ChaoZhang ChaoZhang
1
집중하다
1621
수행원

이동 평균 가중 표준 편차 거래 전략

개요

이 전략은 가중된 표준 격차 지표를 사용하여 이동 평균과 결합하여 암호화폐의 트렌드 거래를 구현합니다. 전략은 특정 주기 내의 종결 가격과 거래량에 따라 가격의 가중된 표준 격차 통로를 계산합니다. 가격이 통로를 뚫고 상향으로 갈 때, 추가 공백을하십시오. 동시에, 단위 손실을 줄이기 위해 중지 손실 조건을 설정하십시오.

전략 원칙

코드에는 두 개의 사용자 정의 함수가 정의되어 있으며, 각각 시간 연속과 배열 계산 중화 표준 차이가 있습니다. 주요 단계는 다음과 같습니다:

  1. 종식 가격과 거래량에 따라 가중 평균 가격을 계산합니다.
  2. 각 K선과 평균값의 차이의 제곱을 계산합니다.
  3. 샘플량과 무게를 조정한 평균값에 따라 차이는 계산됩니다.
  4. 칸은 표준차를 얻습니다.

이렇게 하면, 중도 평균값의 중심에, 표준 차이의 위아래 거리가 있는 통로가 생기게 됩니다. 가격이 아래에서 통로의 바닥을 돌파할 때, 더 많은 것을 하고, 위에서 통로의 꼭대기를 돌파할 때, 더 많은 것을 하지 않습니다.

우위 분석

이 전략의 가장 큰 장점은 이동 평균과 변동률 분석을 통합한다는 것입니다. 이동 평균은 시장의 추세 방향을 판단하고, 표준 차이는 합리적인 범위를 정의하며, 둘은 상호 검증되며, 신뢰성이 높습니다. 또한 거래량 중량은 가짜 돌파구를 필터링 할 수 있으며 실제 돌파구가 더 많습니다.

이 전략은 또한 많은 초보자들이 이해하지 못하는 중요한 요소인 Loss을 과도하게 되돌리는 것을 피하기 위해 트렌드를 파악하는 데 도움이되는 Stop Loss을 설정합니다.

위험 분석

주요 위험은 시장이 급격한 변동이 발생할 수 있다는 것입니다. 이 경우 표준편차 통도도 크게 변동하여 판단에 도움이되지 않습니다. 또한, 선택주기가 너무 짧고 소음에 방해가 될 수 있다면 오류율이 높습니다.

대책은, 적절히 조정할 수 있는 주기적 파라미터, 평평한 곡선이다. RSI 등과 같은 다른 지표와 결합하여, 돌파의 확인 효과를 증가시키는 것도 고려할 수 있다.

최적화 방향

  1. 최적화 주기 파라미터: 5분, 15분, 30분 등의 다른 주기들을 테스트하여 최적의 조합을 찾아낼 수 있다.
  2. 스톱 스톱 비율을 최적화한다. 다양한 스톱 스톱 포인트를 테스트하여 최적의 수익률을 얻는다.
  3. 필터링 조건을 추가한다. 예를 들어, 합성 트래픽을 결합하여 가짜 돌파구가 Loss를 가져오지 않도록 한다.
  4. 지표를 추가한다. 예를 들어, 종점 가격 위치, 그림선 길이 등으로 K선 엔티티를 확인한다. 오류율을 줄인다.

요약하다

이 전략은 중화 표준 차차 지표를 성공적으로 활용하고, 이동 평균으로 방향을 판단하여, 암호화폐의 추세를 추적 할 수 있습니다. 동시에, 합리적인 스톱 스 설정은 시장의 속도를 파악하고, 과도한 반전이 손실을 초래하는 것을 피하는 데 도움이됩니다. 여러 지표 검증과 파라미터를 조정하여 추가적으로 최적화 할 수 있으며, 신뢰할 수 있는 정량 거래 전략이 형성됩니다.

전략 소스 코드
/*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)