资源加载中... loading...

STOCHRSI 指标理解

Author: 发明者量化-小小梦, Created: 2016-08-24 19:25:22, Updated: 2017-10-11 11:07:31

STOCHRSI 指标理解

  • 这几天帮一个朋友解决一个关于指标的问题,这个指标就是 STOCHRSI 。在网上查了很多资料,中文的真是甚少。而且仅有的也不是讲的很清楚。对于我这样的 交易小白,简直是天书。 不过只要研究多少会有点收获的,下面分享下经验,需要用这个的朋友可以借鉴。

在网上找到了一些 关于这个指标的计算公式。

/*
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;
*/

天哪! 我竟然耐心看完了。(当时看见这个的时候,就感觉碰到钉子了。) 这个描述是通用 公式。但是有点编程经验的我也只能 猜!猜!猜!

  • 1.在网上找到的资料说,这个指标有大概3个不同形态。上面的公式是其中2个。 但是资料也没说,这3个不同形态的其他详细信息。
  • 2.在各个平台的图表行情中看、对比。发现,关于这个指标的描述各不相同。平台上的 talib指标库 中的指标函数 STOCHRSI 的参数描述也没有完全明白。
  • 3.用talib指标库 传入参数 14,14,3,3 这组参数,得出的数据和其他平台的对比,发现差异较大。看了看参数描述发现不一样。于是放弃现成的。
  • 4.有点想动手撸这个指标…(有点怕怕,弄不好就被代码虐了)。

经过了一番痛苦挣扎… 总结:

  • 1、这个指标不管哪种形态,RSI 指标是这个指标的基础数据。对比了其他平台描述和上述公式。确定STOCHRSI指标的参数必然有一个是RSI的参数。
  • 2、又发现 这个指标的不同描述,有的描述是指标输出的是 %K , %D两条线。 有的描述是 输出的为 STOCHRSI , MA(3) (这个描述的参数是14,14,3,3) 分析了一下, 其实 虽然是2种不同形态, %K === STOCHRSI , %D === MA(3) 输出的2条线(数据)计算公式是一样的。 确定 MA(3)中的3是一个参数。 剩下2个参数,动手往上面的公式里面带入,就是M 和 P1了 。14、3 都试试。最终发现撸出来的指标数据 ,终于对的上其他平台上的数据了。

绿色是快线 %K ,橙色是 %D img

  • 自己写的指标,可以对比下 OKCoin的 。 如有问题欢迎留言 ^^

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];
}

More

lijingxfdj function main() { 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]) } --- 梦总,我调用了这个函数,并且打印出来的数据跟币安上的StochRsi的实际值是对不上的

J 回测时发现这个函数的速度非常慢,有待提高

J 还是没看明白,这最后到底要怎么用 talib.STOCHRSI() 才能对的上bitcoinwisdom的数据?

发明者量化-小小梦 可能是对比的问题,确定对比的数据是同样品种、周期、参数、BAR位置。这个之前测试过,应该是一样的。

发明者量化-小小梦 talib 是一个 指标库 开源的。在BotVS 是这样使用的 , 比如求均线 talib.MA(records, 10); // records 所求均线的周期 的K线数据 计算出来就是 records K线 10个bar 的均线。 可以来BotVS QQ群: 608262365

发明者量化-小小梦 FstochRSI(records,n,m,p1,p2) 对应 OKCoin 参数 是一样的, 除了第一个 records 这个是 K线数据 ,就是 计算指标的数据源, 我对比过 OK 的图表算出的数据是一样的,就是这个算法 回测 有点慢。

发明者量化-小小梦 可能算法或者代码需要优化

J 太好了,现在正常了。谢谢!

发明者量化-小小梦 代码已经写在帖子上了, 可以对比下看看。

J 先用STOCH函数了,感觉效果差不多

发明者量化-小小梦 talib的 对不上,内部计算,有些不一样。我自己写了下 STOCHRSI ,稍后贴出来。