R Parabolic SAR и предвзятый уклон
Я проверяю это в R
с использованием SAR()
функция от великого TTR
пакет реализован Джошуа Ульрихом. Я не уверен, является ли это стандартным поведением Parabolic SAR. Если да, мне нужна помощь с внедрением "будущего слепого" SAR.
Для простоты я буду работать с короткими векторами и целочисленными значениями вместо данных ряда в реальном времени.
L <- c(1:4, 5)
H <- c(2:5, 6)
ParSAR <- SAR(cbind(H, L))
cbind(L, H, ParSAR)
L H ParSAR
[1,] 1 2 1.000000
[2,] 2 3 1.000000
[3,] 3 4 1.080000
[4,] 4 5 1.255200
[5,] 5 6 1.554784
Я изменю только одно значение в последнем интервале, где Low - High
диапазон теперь будет 5 - 7 вместо 5 - 6.
L <- c(1:4, 5)
H <- c(2:5, 7)
Мы получаем:
L H ParSAR
[1,] 1 2 0.5527864
[2,] 2 3 0.5817307
[3,] 3 4 0.6784614
[4,] 4 5 0.8777538
[5,] 5 7 1.2075335
Ожидается ли такое поведение, что вся история Parabolic SAR сильно изменится? Если значения SAR в строках от 1 до 4 изменяются другим будущим значением в строке 5, это вносит предварительное смещение в предыдущие строки.
Если это стандартное поведение Parabolic SAR и мне нужно его для тестирования, мне придется пересчитать его для каждой строки, всегда маскируя все будущие данные (строки).
Желаемый результат состоит в том, чтобы иметь значение Parabolic SAR для каждой строки, как я мог бы засвидетельствовать это в определенный момент времени, не зная будущего.
РЕДАКТИРОВАТЬ 2016-06-18
Пример упрощенного кода для user3666197:
> SAR(cbind(c(2, 3, 4, 5, 6), c(1, 2, 3, 4, 5)), c(0.02, 0.2))
[1] 1.000000 1.000000 1.080000 1.255200 1.554784
> SAR(cbind(c(2, 3, 4, 5, 7), c(1, 2, 3, 4, 5)), c(0.02, 0.2))
[1] 0.5527864 0.5817307 0.6784614 0.8777538 1.2075335
3 ответа
Реализация Parabolic SAR R идет с упреждением.
Значение initGap является стандартным отклонением всех данных HL за все время:
initGap <- sd(drop(coredata(HL[, 1] - HL[, 2])), na.rm = TRUE)
Ссылки: https://github.com/joshuaulrich/TTR/issues/23
Резкое влияние на мой оригинальный пример вызвано короткой выборкой данных и использованными крайними значениями.
@user3666197:
Ваш тест дает одинаковые результаты для обоих коротких примеров, потому что в обоих случаях значение по умолчанию initGap = 0.
используется. Это не относится к функции оболочки R, как отмечено выше:
# Gap for inital SAR
initGap <- sd(drop(coredata(HL[,1] - HL[,2])), na.rm=TRUE)
В pSAR не реализован предварительный просмотр.
После небольшого обзора кода реализации pSAR Джошуа Улриха можно подтвердить нулевой просмотр в исходном коде.
Проблемы могут появиться на первый взгляд из функции подписи вызова, но R
-раппер исправляет это.
#'@export
"SAR" <-
function(HL, accel=c(.02,.2)) {
# Parabolic Stop-and-Reverse (SAR)
# ----------------------------------------------
# HL = HL vector, matrix, or dataframe
# accel[1] = acceleration factor
# accel[2] = maximum acceleration factor
...
# Gap for inital SAR
initGap <- sd(drop(coredata(HL[,1] - HL[,2])), na.rm=TRUE)
# Call C routine
sar <- .Call("sar", HL[,1], HL[,2], accel, initGap, PACKAGE = "TTR")
reclass( sar, HL )
}
SAR()
реализация использует опубликованный интерфейс вызова sar()
:
SEXP sar ( SEXP hi, /* HIGH[]-s */ SEXP lo, /* LOW[]-s */ SEXP xl, /* [initial AF value, max AF value] */ SEXP ig /* initial GAP */ )
где нет заглядывать в будущее (нулевой прогноз) ни в одном из for(){...}
сканеры (все это только назад).
ОБНОВИТЬ
Тестовые выходы из обоих заданных наборов данных:
|>>> sar( ( 2, 3, 4, 5, 6 ), ( 1, 2, 3, 4, 5 ), ( 0.02, 0.2 ) )
[1.0, 1, 1.08, 1.2552, 1.5547840000000002]
|
|>>> sar( ( 2, 3, 4, 5, 7 ), ( 1, 2, 3, 4, 5 ), ( 0.02, 0.2 ) )
[1.0, 1, 1.08, 1.2552, 1.5547840000000002]
Наблюдается нулевая перспектива в реализации алгоритма pSAR, проведенного Джошуа Ульрихом.
Q.E.D.
Постфактум
как было отмечено с самого начала,
sar()
Функция оказалась правильно реализованной техническим индикатором pSAR. Оболочка R была проблемой, так как она решает, какие параметры лежат в основе, правильно работающая функцияsar()
вызывается. В случае, если в сигнатуру вызова загружены параметры, несущие предвзятое смещение, за такое поведение следует винить не пользователя, а пользователя.Q.E.D.
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# CRAN - R-Project TTR lib: indicators:: # Joshua ULRICH: >>> https://github.com/joshuaulrich/TTR/tree/master/src + https://cran.r-project.org/web/packages/TTR/TTR.pdf
def sar( Hi, Lo, acceleration_factor = ( 0.02, 0.2 ), initGap = 0. ):
""" __doc__
USAGE: calculate parabolic SAR on given inputs
sar( Hi,
Lo,
acceleration_factor = ( 0.02, 0.2 ),
initGap = 0.
)
PARAMS: Hi: High[]s in []-alike representation
Lo: Low[]-s in []-alike representation
acceleration_factor: [ afSTEP, afMAX ], ref. pSAR rules
initGap: initial gap under first valid Low[]
RETURNS: pSAR[]
THROWS: n/a
EXAMPLE: |>>> QuantFX.sar( (2,3,4,5,6), (1,2,3,4,5) )
[1.0, 1, 1.08, 1.2552, 1.5547840000000002]
|
|>>> QuantFX.sar( (2,3,4,5,7), (1,2,3,4,5) )
[1.0, 1, 1.08, 1.2552, 1.5547840000000002]
"""
"""
#___________________________________________________________/* Initalize loop and PROTECT counters */
int i, P=0;
#___________________________________________________________/* Ensure all arguments are double */
if(TYPEOF(hi) != REALSXP) {
PROTECT(hi = coerceVector(hi, REALSXP)); P++;
}
if(TYPEOF(lo) != REALSXP) {
PROTECT(lo = coerceVector(lo, REALSXP)); P++;
}
if(TYPEOF(xl) != REALSXP) {
PROTECT(xl = coerceVector(xl, REALSXP)); P++;
}
double initGap = asReal( ig ); ### ------------------------ extern ( ig )
#___________________________________________________________/* Pointers to function arguments */
double *d_hi = REAL(hi);
double *d_lo = REAL(lo);
double *d_xl = REAL(xl);
"""
#___________________________________________________________/* Input object length */
#int nr = nrows(hi);
nRows = len( Hi )
#___________________________________________________________/* Initalize result R object */
#SEXP sar; PROTECT(sar = allocVector(REALSXP,nr)); P++;
#double *d_sar = REAL(sar);
sar = [None] * nRows
#___________________________________________________________/* Find first non-NA value */
#int beg = 1;
begFrom = 1
#for(i=0; i < nr; i++) {
for i in xrange( nRows ):
if ( np.isnan( Hi[i] )
or np.isnan( Lo[i] )
):
sar[i] = None # NA_REAL; /* skip-it */
begFrom += 1
else:
break # /* break */
pass
pass
#___________________________________________________________/* Initialize values needed by the routine */
#int sig0 = 1, sig1 = 0;
sig0 = 1
sig1 = 0
xpt0 = Hi[begFrom-1]
xpt1 = 0
afStp = acceleration_factor[0]
afMAX = acceleration_factor[1]
af0 = afStp
af1 = 0
sar[begFrom-1] = Lo[begFrom-1] - initGap # /* SUB initGap from 1st Lo[] to begin from */
for i in xrange( begFrom, nRows ):
#_________________________________________________________/* Increment signal, extreme point, and acceleration factor */
sig1 = sig0
xpt1 = xpt0
af1 = af0
#_________________________________________________________/* Local extrema */
lmin = min( Lo[i-1], Lo[i] ) #?? pSAR_RULE_Exc 2 ?? 2 last bars checked
lmax = max( Hi[i-1], Hi[i] )
#_________________________________________________________/* Create signal and extreme price vectors */
if ( sig1 == 1 ): #/* Previous buy signal */
#ig0 = ( Lo[i] > d_sar[i-1]) ? 1 : -1 #/* New signal */
sig0 = 1 if ( Lo[i] > sar[i-1] ) else -1 #/* New signal */
xpt0 = max( lmax, xpt1 ) #/* New extreme price */
else: #/* Previous sell signal */
#ig0 = ( Hi[i] < d_sar[i-1]) ? -1 : 1 #/* New signal */
sig0 = -1 if ( Hi[i] < sar[i-1] ) else 1 #/* New signal */
xpt0 = min( lmin, xpt1 ) #/* New extreme price */
pass
"""
/*
* Calculate acceleration factor (af)
* and stop-and-reverse (sar) vector
*/
"""
#_________________________________________________________/* No signal change */
if ( sig0 == sig1 ):
#_______________________________________________________/* Initial calculations */
sar[i] = sar[i-1] + ( xpt1 - sar[i-1] ) * af1
#f0 = ( af1 == afMAX ) ? afMAX : ( afStp + af1 )
af0 = afMAX if ( af1 == afMAX ) else ( afStp + af1 )
#_______________________________________________________/* Current buy signal */
if ( sig0 == 1 ):
#f0 = (xpt0 > xpt1) ? af0 : af1 #/* Update acceleration factor */
af0 = af0 if (xpt0 > xpt1) else af1 #/* Update acceleration factor */
sar[i]= min( sar[i], lmin ) #/* Determine sar value */
#_______________________________________________________/* Current sell signal */
else:
#f0 = (xpt0 < xpt1) ? af0 : af1 #/* Update acceleration factor */
af0 = af0 if (xpt0 < xpt1) else af1 #/* Update acceleration factor */
sar[i]= max( sar[i], lmax ) #/* Determine sar value */
#_________________________________________________________/* New signal */
else:
af0 = afStp #/* reset acceleration factor */
sar[i] = xpt0 #/* set sar value */
pass
pass
#___________________________________________________________/* UNPROTECT R objects and return result */
#UNPROTECT(P);
#return(sar);
return sar