TA 指标库
MACD 指数平滑异同平均线
KDJ 随机指标
RSI 强弱指标
ATR 平均真实波幅
OBV 能量潮
MA 移动平均线
EMA 指数平均数指标
BOLL 布林带
Alligator Alligator Indicator
CMF 蔡金货币流量指标
Highest 周期最高价
Lowest 周期最低价
Давайте попробуем написать тест на MACD, прежде чем мы откроем этикетку MACD в документации API и посмотрим, как это описано.
Если вы заинтересованы в DIF, DEA, алгоритмах показателей и т. д., вы можете найти алгоритмы MACD в Baidu, где есть много ресурсов, хорошо упакованный интерфейс, который мы готовы использовать.
function main(){
var records = null;
var macd = null;
while(true){
records = _C(exchange.GetRecords); // 获取K线数据 ,默认为策略界面设置的K线周期, _C 是一个容错的内置函数。
// _C 详见 https://www.fmz.com/bbs-topic/320 问题7。
macd = TA.MACD(records); // 不加参数的话,使用的是默认参数 12, 26, 9
Log("macd[0]", macd[0]); // DIF
Log("macd[1]", macd[1]); // DEA
Log("macd[2]", macd[2]); // MACD
Log("macd[0]长度", macd[0].length); // DIF 长度
Log("macd[1]长度", macd[1].length); // DEA 长度
Log("macd[2]长度", macd[2].length); // MACD 长度
Log("records 长度:", records.length); // 显示一下 records 的长度。
Sleep(1000 * 60 * 5);
}
}
Результаты испытаний на диске:
Как видно, все вычисленные показатели начинаются с нуля, а последующие данные начинаются с конкретных значений, что связано с циклами вычислений, заданными параметрами показателей, и не может быть вычислен показатель до тех пор, пока объем данных не достигнет этого цикла. Таким образом, перед использованием показателя необходимо сначала узнать описание показателя; и в программе определить длину данных K-строки, используемых для расчета показателя; чтобы не вычислить недействительные значения при недостаточной длине, а использование недействительных значений приведет к ошибкам в программе.
Ниже мы используем графический интерфейс, чтобы показать вычисленные показатели на графике и сравнить их с реальными диаграммами бирж (включая реальные диаграммы OKCoin).
var ChartCfg = {
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
chart: { zoomType:'x',panning:true },//图表类型
title: { text: "K-macd"}, //标题
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: false
},
subtitle: {text: "测试macd"},//副标题
xAxis:{type: 'datetime'},
yAxis: [{
title: {text: 'K线'},//标题
style: {color: '#4572A7'},//样式
opposite: false //生成右边Y轴
},
{
title:{text: "macd"},
opposite: true //生成右边Y轴 ceshi
}
],
series: [//系列
{type:'candlestick',yAxis:0,name:'K',id:'KLine',data:[]},
{name:"DIF",type:'spline',yAxis:1,data:[]},
{name:"DEA",type:'spline',yAxis:1,data:[]},
{name:"MACD量柱",type:'spline',yAxis:1,data:[]},
]
};
function main(){
var records = null;
var macd = null;
var perRecords = _C(exchange.GetRecords);
var perRecordTime = perRecords[perRecords.length - 1].Time;
var chart_obj = Chart(ChartCfg); // 初始化图表
chart_obj.reset();
while(true){
records = _C(exchange.GetRecords); // 获取K线数据 ,默认为策略界面设置的K线周期, _C 是一个容错的内置函数。
if(!records && records.length < 26 ){
continue;
}
macd = TA.MACD(records, 12, 26, 9); // 不加参数的话,使用的是默认参数 12, 26, 9
if(records[records.length - 1].Time !== perRecordTime){ // _C 详见 https://www.fmz.com/bbs-topic/320 问题7。
//先更新,再添加K线
chart_obj.add(0, [records[records.length - 2].Time, records[records.length - 2].Open, records[records.length - 2].High, records[records.length - 2].Low, records[records.length - 2].Close], -1); // 跟新刚完成的bar。
chart_obj.add(0, [records[records.length - 1].Time, records[records.length - 1].Open, records[records.length - 1].High, records[records.length - 1].Low, records[records.length - 1].Close]); // 添加新出现的bar
//先更新,添加指标线
chart_obj.add(1, [records[records.length - 2].Time, macd[0][records.length - 2]], -1); // 更新
chart_obj.add(1, [records[records.length - 1].Time, macd[0][records.length - 1]]);
chart_obj.add(2, [records[records.length - 2].Time, macd[1][records.length - 2]], -1); // 更新
chart_obj.add(2, [records[records.length - 1].Time, macd[1][records.length - 1]]);
chart_obj.add(3, [records[records.length - 2].Time, macd[2][records.length - 2]], -1); // 更新
chart_obj.add(3, [records[records.length - 1].Time, macd[2][records.length - 1]]);
perRecordTime = records[records.length - 1].Time;
}else{
//只更新当前的bar 和 线
chart_obj.add(0, [records[records.length - 1].Time, records[records.length - 1].Open, records[records.length - 1].High, records[records.length - 1].Low, records[records.length - 1].Close], -1);
chart_obj.add(1, [records[records.length - 1].Time, macd[0][records.length - 1]], -1); // 更新
chart_obj.add(2, [records[records.length - 1].Time, macd[1][records.length - 1]], -1); // 更新
chart_obj.add(3, [records[records.length - 1].Time, macd[2][records.length - 1]], -1); // 更新
}
chart_obj.update(ChartCfg);
Sleep(1000);
}
}
Параметры K-линейных циклов на интерфейсе робота установлены на 1 минуту, так как для того, чтобы увидеть эффект, требуется некоторое время, поэтому выбирают циклы, которые немного меньше.
Как видно из рисунка, количественное определение изобретателя, выполненное роботом, рассчитанный DIF составляет около 2.729 и DEA - около 2.646, MACD - около 0.0831. Фактический OKCoin обменный портфельный график показывает DIF 2.73 и DEA 2.65 MACD столбики 0.17 Как вы можете видеть, первые два DIF, DEA имеют небольшую разницу, OKCoin делает четыре и пять, MACD вдвое меньше, потому что OKCoin рассчитывается так: (DIF - DEA) * 2, обычно DIF - DEA = 2.729 - 2.646 = 0.083, если умножить еще раз на 2, это 0.166 примерно равно 0.17.
STOCHRSI Stochastic Relative Strength Index
STOCHRSI(Records[Close],Time Period = 14,Fast-K Period = 5,Fast-D Period = 3,Fast-D MA = 0) = [Array(outFastK),Array(outFastD)]
Вы можете видеть, что параметры настройки talib.STOCHRSI ((records, 14, 14, 3, 3); в основном это код, похожий на верхний MACD, с некоторыми изменениями.
var ChartCfg = {
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
chart: { zoomType:'x',panning:true },//图表类型
title: { text: "stochrsi"}, //标题
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: false
},
subtitle: {text: "测试stochrsi"},//副标题
xAxis:{type: 'datetime'},
yAxis: [{
title: {text: 'K线'},//标题
style: {color: '#4572A7'},//样式
opposite: false //生成右边Y轴
},
{
title:{text: "K-D"},
opposite: true //生成右边Y轴 ceshi
}
],
series: [//系列
{type:'candlestick',yAxis:0,name:'K',id:'KLine',data:[]},
{name:"K",type:'line',yAxis:1,data:[]},
{name:"D",type:'line',yAxis:1,data:[]},
]
};
function main(){
var records = null;
//var macd = null;
var stochrsi = null;
var perRecords = _C(exchange.GetRecords);
var perRecordTime = perRecords[perRecords.length - 1].Time;
var chart_obj = Chart(ChartCfg); // 初始化图表
chart_obj.reset();
while(true){
records = _C(exchange.GetRecords); // 获取K线数据 ,默认为策略界面设置的K线周期, _C 是一个容错的内置函数。
if(!records && records.length < 26 ){
continue;
}
//macd = TA.MACD(records, 12, 26, 9); // 不加参数的话,使用的是默认参数 12, 26, 9
stochrsi = talib.STOCHRSI(records, 14, 5, 3, 0);
if(records[records.length - 1].Time !== perRecordTime){ // _C 详见 https://www.fmz.com/bbs-topic/320 问题7。
//添加K线
chart_obj.add(0, [records[records.length - 2].Time, records[records.length - 2].Open, records[records.length - 2].High, records[records.length - 2].Low, records[records.length - 2].Close], -1); // 跟新刚完成的bar。
chart_obj.add(0, [records[records.length - 1].Time, records[records.length - 1].Open, records[records.length - 1].High, records[records.length - 1].Low, records[records.length - 1].Close]); // 添加新出现的bar
//添加指标线
chart_obj.add(1, [records[records.length - 2].Time, stochrsi[0][records.length - 2]], -1); // 更新
chart_obj.add(1, [records[records.length - 1].Time, stochrsi[0][records.length - 1]]);
chart_obj.add(2, [records[records.length - 2].Time, stochrsi[1][records.length - 2]], -1); // 更新
chart_obj.add(2, [records[records.length - 1].Time, stochrsi[1][records.length - 1]]);
perRecordTime = records[records.length - 1].Time;
}else{
//只更新当前的bar 和 线
chart_obj.add(0, [records[records.length - 1].Time, records[records.length - 1].Open, records[records.length - 1].High, records[records.length - 1].Low, records[records.length - 1].Close], -1);
chart_obj.add(1, [records[records.length - 1].Time, stochrsi[0][records.length - 1]], -1); // 更新
chart_obj.add(2, [records[records.length - 1].Time, stochrsi[1][records.length - 1]], -1); // 更新
}
chart_obj.update(ChartCfg);
LogStatus("倒数第一组数据:", stochrsi[0][stochrsi[0].length - 1], stochrsi[1][stochrsi[1].length - 1], " 倒数第二组数据:", stochrsi[0][stochrsi[0].length - 2], stochrsi[1][stochrsi[1].length - 2]);
Sleep(1000);
}
}
Я не показываю скриншоты, но есть некоторые различия с официальными цифрами OKCoin, и BOSS говорит, что алгоритм реализации талиб-купора может отличаться от OKCoin.Понимание показателей STOCHRSIКак только вы увидите, как написаны все показатели, я напишу это без оптимизации, с низкой эффективностью, работает медленно, и вы должны учиться.
ХокшелатоВы говорите, что последняя K-линия должна быть обновлена и добавлена сначала, потому что последняя K-линия постоянно изменяется, и только после того, как будет создана новая K-линия, последняя K-линия будет определена. Я не совсем понимаю, а K-линейные данные, полученные с помощью `GetRecords (), не являются ли определенными? `records (length -1) ` представляют собой K-линейные данные с текущим временным знаком, которые можно прямо нарисовать в графике, а затем добавить к последнему элементу диаграммы новые K-линейные данные с новым временным знаком, верно?
ШандианлиюЕсть ли более подробное описание TA.ATR ((records, 14)), которое я не нашел в документации, видео и в полном руководстве по использованию BotVS. Когда я вызываю TA.ATR ((records, 14) ((параметры 30 минут k-линии), возвращается ряд длиной 177; что означает этот ряд?
ФанбэйВерсия Python https://dn-filebox.qbox.me/b5d2b0ecc1e196a6bfc68eb45cd818c50d279915.png https://dn-filebox.qbox.me/157db5e2659fd13bcf552cd82fe456ba469939f8.png
ФанбэйPython версия def main ((): while true: records = _C ((exchange.GetRecords); # Добывает K-линейные данные, принимая по умолчанию K-линейные циклы, установленные интерфейсом политики, _C является ошибочно допустимой встроенной функцией. macd = TA.MACD ((records); # Если не добавлять параметры, используются параметры 12, 26, 9 по умолчанию Log (("macd[0]", macd[0]); # DIF Log (("macd[1]", macd[1]); # DEA Log (("macd[2]", macd[2]); # MACD Log (("macd[0] длина", len ((macd[0])); # DIF длина Log (("macd[1] length", len ((macd[1])); # DEA length Log (("macd[2] length", len ((macd[2])); # MACD length Log (("records Длина:", len ((records)); # показывает длину записей. Sleep ((1000 * 60 * 5);
Изобретатели количественного измерения - мечтыВремя на K-линии Bar - это время начала этого Bar, а не реальное время, время начала Bar не меняется.
ХокшелатоО, я раньше понимал, что ошибка в том, что в K-линии есть ** временная лента **. После дешифровки я обнаружил, что механизм BotVS выглядит так: Если я хочу получить K-линейные данные 1 марта этого дня, вызов GetRecords (D1) вернет множество записей, но все они имеют одинаковые временные рамки. То есть, даже если я вызвал `GetRecords(D1)` 1 марта в 10 часов, полученный K-линейный часовой пояс остается 2018-03-01 **00**:00:00. Поэтому только последнее, о чем вы говорите, будет неопределенным, пока не появится новый часовой пояс, то есть 2018-03-**02** 00:00:00, то время 1 марта будет определенным. Ранее я ошибался в том, что думал, что после вызовов 1 марта в 1:00, 2:00 и 3:00 я вернулся в другое время, то есть 2018-03-01 **01**:00:00, 2018-03-01 **02**:00:00, 2018-03-01 **03**:00:00.
Изобретатели количественного измерения - мечтыGetRecords (()) полученные данные о K-линии, кроме первой, остальная часть определена (поскольку цикл завершен), первая часть не определена, потому что цикл не закончен, Close постоянно меняется. Например, дневная K-линия, текущий дневный K-линейный столбец, в то время как сегодня не закончился, никто не знает, какая цена сегодня в конечном итоге будет закрыта.
Изобретатели количественного измерения - мечтыНеприветливо.
ШандианлиюПонял, спасибо большое!
Изобретатели количественного измерения - мечтыДа, соответствует. Противосчет первой линии K Bar.
ШандианлиюХорошо, спасибо большое за ваш ответ. Наконец, подтвердите, что var a = TA.ATR ((records, 14), а[a.length-1] это означает ATR последней строки k?
Изобретатели количественного измерения - мечтыДа. Конкретное количество возврата рассматривается на бирже, но не может быть указано. Поэтому биржа обычно предоставляет ограниченные данные.
ШандианлиюЭто я понимаю, что TA.ATR ((() по сути является математическим расчетом с входящими записями. Я не выразился раньше, я хотел бы спросить, используя функцию exchange.GetRecords (()) при получении данных к-строки, длина возвращения определяется биржей?
Изобретатели количественного измерения - мечтыЭта показательная функция возвращает количество данных, которое соответствует данным K-линий, то есть records, которые вы вводите, сколько длины устроения records, сколько длины вычисляется.
ШандианлиюПростите, я все еще не совсем понимаю, я имею в виду, если вы вызовите эту функцию, то длина возвращаемой информации будет данной биржей? Я обнаружил, что при вызове этой функции в разное время длина возвращаемой информации может быть разной, даже если параметры одинаковы.
Изобретатели количественного измерения - мечтыЭто зависит от длины линии K ^^
ШандианлиюСпасибо, что ответили, это понятно, но я хотел бы спросить, что определяет длину 117.
Изобретатели количественного измерения - мечтыНапример, входящие записи представляют собой K-линию дня, и вычисленный ATR - это множество, первым дефолтом которого является ATR-показатель за день (дата последнего из K-линий дня). Следовательно, вычисляется 30 минут K-линии, 15 минут K-линии.
Изобретатели количественного измерения - мечтыПоднимите орехи. Если сейчас K-линейные данные имеют только 10 Бар, и я прошу MA ((15) то есть 15-циклическую среднюю линию, то, конечно, не получится, потому что только 10 циклов, невозможно вычислить среднее значение 15-циклических циклов.
ФанбэйКроме того, я использовал реальный тик, и он не возвращал никаких данных.
ФанбэйПочему эти данные не отвечают требованиям цикла?
Изобретатели количественного измерения - мечтыВ этом примере хорошо, что в практическом использовании последние данные показателя находятся в конце матрицы, то есть элемент с индексом -1. Посмотрите, что мы можем сделать, если мы не ставим перед собой цели, которые мы не можем достичь. https://dn-filebox.qbox.me/b7837ea30e5d8396ffa91c48204f2fbc9a7f4504.png