TA 指标库
MACD 指数平滑异同平均线
KDJ 随机指标
RSI 强弱指标
ATR 平均真实波幅
OBV 能量潮
MA 移动平均线
EMA 指数平均数指标
BOLL 布林带
Alligator Alligator Indicator
CMF 蔡金货币流量指标
Highest 周期最高价
Lowest 周期最低价
Nehmen wir den MACD-Indikator und versuchen wir, einen Test zu schreiben.
Wenn Sie Interesse an DIF, DEA, Indikator-Algorithmen haben, können Sie auf Baidu nach MACD-Algorithmen suchen.
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);
}
}
Die Ergebnisse der Analogplattenuntersuchung:
Wie man sieht, sind alle berechneten Indikatoren zu Beginn null, die Daten nach Beginn haben einen bestimmten Wert, da die Berechnungszyklen, für die die Indikatorparameter festgelegt sind, nicht berechnet werden können, bevor der Datensatz ("Records-Daten") diesen Zyklus nicht erfüllt. Daher ist es wichtig, die Beschreibung des Indikators zu verstehen, bevor man ihn benutzt, und die Länge der K-Liniendaten, die für die Berechnung des Indikators verwendet werden, im Programm zu beurteilen, damit man nicht einen ungültigen Wert berechnet, wenn die Länge unzureichend ist, und ein ungültiger Wert verwendet wird, der zu einem Programmierfehler führt.
Hier sehen wir den Code, indem wir die berechneten Indikatoren in einem Diagramm anzeigen lassen, und sie mit den realen Diagrammen der Börse vergleichen (Real-Disk wählt 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);
}
}
Die K-Linie-Zyklus-Parameter auf der Roboter-Schnittstelle sind auf 1 Minute gesetzt. Da man eine Weile laufen muss, um die Effekte zu sehen, wählt man eine etwas kleinere Periode.
Wie aus dem Diagramm zu sehen ist, wurden die Erfinder quantifiziert, die Roboter wurden betrieben. Der berechnete DIF beträgt etwa 2.729 und die DEA beträgt etwa 2.646. Der MACD-Quantitätsstamm beträgt etwa 0.0831 Die tatsächliche OKCoin-Börse Verhaltensdiagramm zeigt einen DIF von 2.73 und einen DEA von 2.65 und einen MACD-Quantitätspfosten von 0.17 Man sieht, dass die ersten beiden DIF, DEA, die Unterschiede sehr klein sind, OKCoin hat vier bis fünf gemacht, und der MACD ist doppelt so schlecht, weil OKCoin so berechnet: (DIF - DEA) * 2, normalerweise DIF - DEA = 2.729 - 2.646 = 0.083, wenn man es wiederum mit 2 multipliziert, ist 0.166 ungefähr gleich 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)]
Wie Sie sehen können, ist die Parameter-Einstellung talib.STOCHRSI ((records, 14, 14, 3, 3); im Grunde noch oben MACD ähnlicher Code, ein paar Änderungen, laufen Sie und sehen Sie.
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);
}
}
Ich habe keine Screenshots gezeigt, aber es gibt einen Unterschied zu den offiziellen Zahlen von OKCoin, und BOSS sagt, dass die Implementierungsalgorithmen von Talib-Konto möglicherweise anders sind als bei OKCoin.STOCHRSI-Indikatoren verstehenIch habe das hier nicht optimiert, es ist sehr uneffizient, es läuft ziemlich langsam, aber es ist gut, es zu lernen.
HokshelatoSie sagen, dass die letzte K-Linie erst aktualisiert und hinzugefügt werden muss, weil die letzte K-Linie sich ständig ändert und die vorherige K-Linie erst dann festgestellt wird, wenn eine neue K-Linie erzeugt wird. Ich bin nicht ganz sicher, ob die K-Linien-Daten, die durch `GetRecords (() ` erhalten wurden, nicht eindeutig sind? `records (length -1) ` repräsentieren die K-Linien-Daten, die in der aktuellen Zeit gezeichnet sind, direkt in das Diagramm gezeichnet werden können, und es gibt neue Zeitgezeichnete K-Linien-Daten, die dann zum letzten Element des Diagramms hinzugefügt werden können, oder?
ShandyanliyuGibt es eine detailliertere Beschreibung von TA.ATR ((records, 14)), die ich nicht in der API-Dokumentation, dem Video und dem vollständigen Benutzerhandbuch von BotVS finden konnte.
FangBeiDie Python-Version Sie werden von der Website des Unternehmens freigegeben. https://dn-filebox.qbox.me/b5d2b0ecc1e196a6bfc68eb45cd818c50d279915.png
FangBeiPython Version Def main (: Während wahr: records = _C ((exchange.GetRecords); # Erhält K-Liniendaten, wobei die K-Linienzyklen, die von der Strategieinterface standardmäßig festgelegt werden, als _C als eine fehlerfreundliche eingebaute Funktion gelten. macd = TA.MACD ((records); # Wenn keine Parameter hinzugefügt werden, werden die Standardparameter 12, 26, 9 verwendet Log (("macd[0]", macd[0]); # DIF Log (("macd[1]", macd[1]); # DEA Log (("macd[2]", macd[2]); # MACD Log (("macd[0] Länge", len ((macd[0])); # DIF Länge Log (("macd[1] Länge", len ((macd[1])); # DEA Länge Log (("macd[2] Länge", len ((macd[2])); # MACD Länge Log (("records Länge:", len ((records)); # zeigt die Länge der Records an. Schlaf ((1000 * 60 * 5);
Die Erfinder quantifizieren - Kleine TräumeDie Zeitscheibe der K-Linie Bar ist die Startzeit dieser Bar, nicht die Echtzeit.
HokshelatoHey, was ich vorher falsch verstanden habe, war die Zeitleiste der K-Linie. Nach dem Debug haben wir herausgefunden, dass der Mechanismus von BotVS so aussieht: Wenn ich die K-Daten für den 1. März erhalten möchte, dann rufe ich GetRecords (D1) auf, das viele Aufzeichnungen zurückgibt, aber sie haben alle die gleiche Zeitspanne und sind `2018-03-01 00:00:00 `. Das heißt, selbst wenn ich am 1. März um 10 Uhr get getRecords ((D1) ` aufgerufen habe, erhielt ich den K-Zeitfenster, der immer noch 2018-03-01 **00**:00:00 ist. Ich habe mir vorgestellt, dass ich nach dem 1. März um 1, 2 und 3 Uhr eine andere Uhrzeit für meine Rückmeldung gehalten habe, nämlich 2018-03-01 **01**:00:00, 2018-03-01 **02**:00:00, 2018-03-01 **03**:00:00.
Die Erfinder quantifizieren - Kleine TräumeGetRecords (() erhalten K-Linien-Daten. Außer dem ersten Zähler, der Rest ist festgestellt (denn der Zyklus ist abgeschlossen), ist der erste Zähler unsicher, weil der Zyklus nicht abgeschlossen ist und Close ständig in Bewegung ist. Zum Beispiel die Tages-K-Line, die aktuelle Tages-K-Linien-Säule, wenn der Tag nicht abgeschlossen ist, weiß niemand, wie viel der Preis am Ende des Tages sein wird.
Die Erfinder quantifizieren - Kleine TräumeDas ist unhöflich.
ShandyanliyuIch verstehe. Vielen Dank!
Die Erfinder quantifizieren - Kleine TräumeJa, das entspricht dem Negativ der ersten K-Linie Bar.
ShandyanliyuIch möchte Ihnen noch einmal bestätigen, dass var a = TA.ATR ((records, 14), a[a.length-1] die ATR für die jüngsten k-Linien-Daten ist.
Die Erfinder quantifizieren - Kleine TräumeJa. Es ist nicht möglich, die Höhe der Rendite zu bestimmen.
ShandyanliyuIch verstehe, dass TA.ATR))) im Wesentlichen eine mathematische Operation für die eingegangenen Aufzeichnungen ist. Ich habe es nicht klar gemacht, aber ich möchte fragen, ob die Länge, die zurückgegeben wird, von der Börse bestimmt wird, wenn die Funktion exchange.GetRecords))) die Daten der K-Zeile erhält.
Die Erfinder quantifizieren - Kleine TräumeDiese Indikatorfunktion gibt an, wie viele Daten zurück, die mit den K-Linien-Daten, also den records, korrespondieren, und wie lange ist die Längenordnung, die Sie eingeben, und wie lange ist die Längenordnung, die Sie berechnen.
ShandyanliyuEntschuldigung, ich bin noch nicht ganz klar, ich meine, wenn man diese Funktion anruft, ist die Länge der zurückgegebenen Daten die, die von der Börse angegeben wird? Ich habe festgestellt, dass die Länge der zurückgegebenen Daten unterschiedlich sein kann, wenn man diese Funktion zu verschiedenen Zeiten anruft, auch wenn die Parameter gleich sind.
Die Erfinder quantifizieren - Kleine TräumeDas ist die Länge der K-Leitung ^^
ShandyanliyuDank für Ihre Antwort ist das klar, aber ich möchte auch fragen, was die Länge von 117 bestimmt?
Die Erfinder quantifizieren - Kleine TräumeZum Beispiel, wenn die eingegangenen Rekorde die Tageszeile K sind, ist die berechnete ATR eine Array, und das erste Element der Negativzahl dieser Array ist der ATR-Indikator für den Tag (das Datum des letzten Tages der K-Leitung).
Die Erfinder quantifizieren - Kleine TräumeIch habe eine Kastanienbrust. Wenn ich jetzt nur 10 Bar K-Liniendaten habe, und ich frage nach MA ((15)), also 15-Zyklus-Gerade, dann ist es sicherlich nicht möglich, weil es nur 10 Zyklen gibt und es nicht möglich ist, den Durchschnitt von 15 Zyklen zu berechnen.
FangBeiAußerdem habe ich mit dem Tick-Record auf der echten Ebene getestet und keine Daten zurückgegeben.
FangBeiWarum erfüllen die vorhergehenden Daten nicht die Zyklusanforderungen?
Die Erfinder quantifizieren - Kleine TräumeDas ist ein gutes Beispiel, denn in der Praxis werden die aktuellsten Indikatordaten am Ende der Array, also dem Element mit Index -1, verwendet. Das ist eine sehr wichtige Frage, die wir uns im Laufe der Zeit gefragt haben. Siehe auch: https://dn-filebox.qbox.me/b7837ea30e5d8396ffa91c48204f2fbc9a7f4504.png