2.7 Использование индикаторов

Автор:Маленькие мечты, Создано: 2016-11-10 16:19:36, Обновлено: 2019-08-01 09:25:06

Использование показателей


  • ТА - Оптимизировать переписывание частей часто используемой индикаторной библиотеки

TA 指标库
MACD       指数平滑异同平均线
KDJ        随机指标
RSI        强弱指标
ATR        平均真实波幅
OBV        能量潮
MA         移动平均线
EMA        指数平均数指标
BOLL       布林带
Alligator  Alligator Indicator
CMF        蔡金货币流量指标
Highest    周期最高价
Lowest     周期最低价

Давайте попробуем написать тест на MACD, прежде чем мы откроем этикетку MACD в документации API и посмотрим, как это описано.

img

Если вы заинтересованы в 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);
    }
}

Результаты испытаний на диске:

img

Как видно, все вычисленные показатели начинаются с нуля, а последующие данные начинаются с конкретных значений, что связано с циклами вычислений, заданными параметрами показателей, и не может быть вычислен показатель до тех пор, пока объем данных не достигнет этого цикла. Таким образом, перед использованием показателя необходимо сначала узнать описание показателя; и в программе определить длину данных 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 минуту, так как для того, чтобы увидеть эффект, требуется некоторое время, поэтому выбирают циклы, которые немного меньше.

img img

Как видно из рисунка, количественное определение изобретателя, выполненное роботом, рассчитанный 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.

Другие показатели используются в основном аналогично.

  • Талиб -http://ta-lib.org/

    В дополнение к показателям, которые обычно используются в библиотеке TA, в библиотеке Talib есть много других показателей. Например, мы попробуем использовать индикатор talib.STOCHRSI, и посмотрите описание документации API:
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