В Интернете я нашел несколько расчетных формул для этого показателя.
/*
LC := REF(CLOSE,1); //REF(C,1) 上一周期的收盘价
RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100;
%K: MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100; LLV(l,60)表示:检索60天内的最低价,可适应于检索任何股票
%D:MA(%K,P2);
LC := REF(CLOSE,1);
RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100;
STOCHRSI:MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100;
*/
О боже! Я просто терпеливо смотрела на это. Это описание является общей формулой. Но даже я с небольшим опытом программирования могу только догадываться!
После тяжелейшей борьбы... В итоге:
Зеленый - это скоростная линия %K, оранжевый - %D.
function LLV(array,period){
if(!array || array.length - period < 0){
throw "error:" + array;
}
var min = array[array.length - period];
for(var i = array.length - period; i < array.length; i++){
if( array[i] < min ){
min = array[i];
}
}
return min;
}
function HHV(array,period){
if(!array || array.length - period < 0){
throw "error:" + array;
}
var max = array[array.length - period];
for(var i = array.length - period; i < array.length; i++){
if( array[i] > max){
max = array[i];
}
}
return max;
}
function DeleteNullEle(initArr){
var dealArr = [];
var initArrLen = initArr.length;
for(var i = 0,j = 0 ; i < initArrLen ; i++,j++){
if(initArr[i] === null || isNaN(initArr[i]) ){
j--;
continue;
}
dealArr[j] = initArr[i];
}
return dealArr;
}
/*
LC := REF(CLOSE,1); //REF(C,1) 上一周期的收盘价
RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100;
%K: MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100; LLV(l,60)表示:检索60天内的最低价,可适应于检索任何股票
%D:MA(%K,P2);
LC := REF(CLOSE,1);
RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100;
STOCHRSI:MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100;
*/
function FstochRSI(records,n,m,p1,p2){
var len = records.length;
//var LC = records[len-2];//上一周期收盘价
//var rsi = TA.RSI(records,n);// RSI 数组 ,talib
var rsi = talib.RSI(records,n);
rsi = DeleteNullEle(rsi);//ceshi
var arr1 = [];
var arr2 = [];
var arr3 = [];
var arr4 = [];
var rsi_a = [];
var rsi_b = [];
var k = [];
var d = null;
/*不包含当前柱
for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV
for(var aa = 0 ; aa <= a; aa++ ){
rsi_a.push(rsi[aa]);
}
arr1.push(rsi[a] - TA.Lowest(rsi_a,m));
}
for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV
for(var bb = 0 ; bb <= b; bb++ ){
rsi_b.push(rsi[bb]);
}
arr2.push(TA.Highest(rsi_b,m) - TA.Lowest(rsi_b,m));
}
*/
for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV
if(a < m){
continue;
}
for(var aa = 0 ; aa <= a; aa++ ){
rsi_a.push(rsi[aa]);
}
arr1.push(rsi[a] - LLV(rsi_a,m));
}
for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV
if(b < m){
continue;
}
for(var bb = 0 ; bb <= b; bb++ ){
rsi_b.push(rsi[bb]);
}
arr2.push(HHV(rsi_b,m) - LLV(rsi_b,m));
}
arr1 = DeleteNullEle(arr1);
arr2 = DeleteNullEle(arr2);
//Log("arr1:",arr1.length,"-",arr1);//ceshi
//Log("arr2:",arr2.length,"-",arr2);//ceshi
arr3 = talib.MA(arr1,p1);
arr4 = talib.MA(arr2,p1);
arr3 = DeleteNullEle(arr3);
arr4 = DeleteNullEle(arr4);
//Log("ceshi");//ceshi
var c = 0;
var diff = 0;
if(arr3.length !== arr4.length){//实测 长度不相等
throw "error: !=" + arr3.length + "----" + arr4.length;
diff = arr4.length - arr3.length; //example diff = 10 - 6
}else{
//throw "error:" + arr3.length + "----" + arr4.length;
}
for( ;c < arr3.length ; c++ ){
k.push(arr3[c] / arr4[c + diff] * 100);
}
d = talib.MA(k,p2);
return [k,d,rsi];
}
Лижингксфджfunction main (()) {c:$a exchange.SetContractType (("swap") // настроить на постоянный контракт var records = exchange.GetRecords ((PERIOD_M15)) - перейти к следующему разделу. let [k, d, rsi] = FstochRSI ((records, 14, 14, 3, 3); Log (("K", k[k.length-2]) Log (("D",d[d.length-2]) {y:bi} --- В общем, я вызвал эту функцию, и данные, которые были напечатаны, не совпадают с фактическими значениями StochRsi на биткоине.
JПри повторном тестировании мы обнаружили, что эта функция работает очень медленно и требует улучшения.
JВ конце концов, что делать с данными talib.STOCHRSI, чтобы выполнить эту задачу?
Изобретатели количественного измерения - мечтыВозможно, это проблема контрастности, которая определяет, что данные контрастности одинаковые по разновидности, циклам, параметрам, местоположению BAR.
Изобретатели количественного измерения - мечтыtalib - это индикаторная база с открытым исходным кодом. В BotVS используется, например, для поиска средних линий talib.MA ((records, 10); // records для поиска средних линий циклов. Вычисляется, что records K-линия имеет 10 бар.
Изобретатели количественного измерения - мечтыFstochRSI ((records, n, m, p1, p2) соответствует параметрам OKCoin, которые одинаковы, за исключением того, что первая запись - это K-линейные данные, то есть источник данных для вычисления показателя, который я сравнил с данными, вычисленными на диаграмме OK, то есть алгоритм повторяется немного медленнее.
Изобретатели количественного измерения - мечтыВозможно, алгоритм или код нуждаются в оптимизации.
JОчень хорошо, теперь все нормально.
Изобретатели количественного измерения - мечтыКод уже написан в сообщении, сравнить можно по ссылке.
JСначала используйте функцию STOCH, и вы почувствуете почти то же самое.
Изобретатели количественного измерения - мечтыТалиб не согласен, внутренние вычисления немного отличаются. Я сам написал STOCHRSI и опубликовал позже.