# StochRSI(和okcoin一致)

Author: fangj, Date: 2017-09-26 12:44:22
Tags: Tool RSI

```function Stoch_RSI(records) {
/*
LC:=REF(CLOSE,1);
RSI:=SMA(MAX(CLOSE-LC,0),14,1)/SMA(ABS(CLOSE-LC),14,1)*100;
STOCH_RSI=STOCH_RSI:=MA(RSI-LLV(RSI,14),3)/MA(HHV(RSI,14)-LLV(RSI,14),3)*100;
STOCH_RSI_MA:SMA(STOCH_RSI,3);
*/

//计算RSI
var rsi = TA.RSI(records, 14);
// STOCH_RSI:=MA(RSI-LLV(RSI,14),3)/MA(HHV(RSI,14)-LLV(RSI,14),3)*100;
//填充空白数据
var raw_stoch_rsi = [], raw_stoch_rsi_a = [], raw_stoch_rsi_b = [];
for (var i = 0; i < 14; i++) {
raw_stoch_rsi[i] = 50;
raw_stoch_rsi_a[i] = 0.5;
raw_stoch_rsi_b[i] = 1;
}
//计算指标
for (i = 14; i < rsi.length; i++) {
var the_next_index = i + 1;
var first_index = the_next_index - 14;
var period_data = rsi.slice(first_index, the_next_index);
var llv = _.min(period_data);
var hhv = _.max(period_data);
var current_rsi = rsi[i];
raw_stoch_rsi_a.push(current_rsi - llv);
raw_stoch_rsi_b.push(hhv - llv);
}
//分别对分子分母滑动平均
var raw_stoch_rsi_a_ma = TA.MA(raw_stoch_rsi_a, 3);
var raw_stoch_rsi_b_ma = TA.MA(raw_stoch_rsi_b, 3);
for (i = 0; i < rsi.length; i++) {
var v = raw_stoch_rsi_a_ma[i] / raw_stoch_rsi_b_ma[i] * 100;
v = isNaN(v) ? 50 : v;
raw_stoch_rsi[i] = v;
}
// 滑动平均
var stoch_rsi_K = raw_stoch_rsi;
var stoch_rsi_D = TA.MA(stoch_rsi_K, 3);
stoch_rsi = [stoch_rsi_K, stoch_rsi_D];
return stoch_rsi;
}

var chart = { // 这个 chart 在JS 语言中 是对象， 在使用Chart 函数之前我们需要声明一个配置图表的对象变量chart。
__isStock: true,                                    // 标记是否为一般图表，有兴趣的可以改成 false 运行看看。
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},    // 缩放工具
title: {text: 'K线图'},                       // 标题
rangeSelector: {                                    // 选择范围
buttons: [{type: 'hour', count: 1, text: '1h'}, {type: 'hour', count: 3, text: '3h'}, {
type: 'hour',
count: 8,
text: '8h'
}, {type: 'all', text: 'All'}],
selected: 0,
inputEnabled: true
},
xAxis: {type: 'datetime'},                         // 坐标轴横轴 即：x轴， 当前设置的类型是 ：时间
yAxis: [{                                           // 坐标轴纵轴 即：y轴， 默认数值随数据大小调整。
title: {text: '价格'},                           // 标题
opposite: false,
height: '60%',// 是否启用右边纵轴
},
{                                           // 坐标轴纵轴 即：y轴， 默认数值随数据大小调整。
title: {text: 'stoch_rsi'},                           // 标题
top: '65%',
height: '35%',
offset: 0,
opposite: false,                                // 是否启用右边纵轴
}],
series: [                                          // 数据系列，该属性保存的是 各个 数据系列（线， K线图， 标签等..）
{
type: 'candlestick',
name: '价格',
id: 'primary',
data: []
},  // 索引为0， data 数组内存放的是该索引系列的 数据
{name: "SRSI_K", id: "SRSI_K", data: [], yAxis: 1}, // 索引为1，设置了dashStyle : 'shortdash' 即：设置 虚线。
{name: "SRSI_D", id: "SRSI_D", dashStyle: 'shortdash', data: [], yAxis: 1},
]
};

function main() {
exchange.SetContractType("quarter");
var ObjChart = Chart(chart);  // 调用 Chart 函数，初始化 图表。
ObjChart.reset();             // 清空
var preBarTime = 0;
while (true) {
var nowTime = new Date().getTime();   // 获取本次轮询的 时间戳，  即一个 毫秒 的时间戳。用来确定写入到图表的X轴的位置。
var records = exchange.GetRecords(PERIOD_H1);  // 获取行情数据
var stoch_rsi = Stoch_RSI(records);
stoch_rsi_quick = stoch_rsi[0];
stoch_rsi_slow = stoch_rsi[1];

for (var i = 0; i < records.length; i++) {         // 遍历records
var r_quick = stoch_rsi_quick[i];
var r_slow = stoch_rsi_slow[i];
if (isNaN(r_quick)) {
r_quick = 50;
}
if (isNaN(r_slow)) {
r_slow = 50;
}
if (records[i].Time == preBarTime) {
ObjChart.add(0, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close], -1);  // 添加
} else if (records[i].Time > preBarTime) {
preBarTime = records[i].Time;
ObjChart.add(0, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close]);  // 添加