TA 指标库
MACD 指数平滑异同平均线
KDJ 随机指标
RSI 强弱指标
ATR 平均真实波幅
OBV 能量潮
MA 移动平均线
EMA 指数平均数指标
BOLL 布林带
Alligator Alligator Indicator
CMF 蔡金货币流量指标
Highest 周期最高价
Lowest 周期最低价
Untuk mencuba menulis ujian dengan MACD, sebelum kita membuka label MACD pada dokumen API, lihat perihal yang lebih terperinci.
Jika anda berminat dengan DIF, DEA, algoritma penunjuk dan lain-lain, anda boleh mencari algoritma MACD di Baidu, terdapat banyak sumber, antarmuka yang dibungkus dengan baik.
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);
}
}
Hasil ujian piringan analog:
Seperti yang dapat dilihat, semua penunjuk yang dikira pada permulaan adalah null, dan data di belakang bermula dengan nilai tertentu, kerana kitaran pengiraan yang ditetapkan oleh parameter penunjuk tidak dapat dikira sebelum jumlah data tidak memenuhi kitaran ini. Oleh itu, sebelum menggunakan penunjuk, anda perlu mengetahui keterangan penunjuk tersebut. Dan dalam program, tentukan panjang data K-line yang digunakan untuk mengira penunjuk. Jangan mengira nilai yang tidak sah jika panjangnya tidak mencukupi, dan menggunakan nilai yang tidak sah akan menyebabkan kesilapan program.
Di bawah ini, kita menggunakan antara muka grafik untuk menunjukkan indikator yang dikira pada carta dan membandingkan grafik rak sebenar pertukaran (pilih OKCoin rak sebenar), lihat kod terlebih dahulu:
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);
}
}
Parameter kitaran K pada antara muka bot ditetapkan sebagai 1 minit, kerana ia memerlukan masa untuk berjalan untuk melihat kesan, pilih kitaran yang sedikit lebih kecil; sebagai berikut:
Seperti yang dilihat dari grafik Pencipta Kuantitifikasi Robot Berjalan DIF dikira kira-kira 2.729 DEA kira-kira 2.646 Tapak kuantiti MACD kira-kira 0.0831 Bagan perbelanjaan pertukaran OKCoin sebenar menunjukkan DIF 2.73 dan DEA 2.65 Seperti yang anda lihat, perbezaan antara kedua-dua DIF, DEA adalah kecil, OKCoin melakukan empat lima, dan MACD hampir dua kali ganda, kerana OKCoin dihitung seperti ini: (DIF - DEA) * 2, biasanya DIF - DEA = 2.729 - 2.646 = 0.083, jika dikalikan semula dengan 2, 0.166 adalah kira-kira sama dengan 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)]
Seperti yang anda lihat, tetapan parameter adalah talib.STOCHRSI ((records, 14, 14, 3, 3); pada dasarnya masih kod yang serupa dengan MACD di atas, dengan beberapa perubahan, jalankan dan lihat.
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);
}
}
Saya tidak menunjukkan skrin gambar, tetapi terdapat perbezaan dengan angka rasmi OKCoin, dan BOSS mengatakan bahawa algoritma pelaksanaan Talib mungkin tidak sama dengan OKCoin.Pengertian STOCHRSIJika anda melihat bagaimana penunjuk ditulis, saya menulis yang tidak dioptimumkan, rendah kecekapan, berjalan perlahan, hak untuk belajar.
hokshelatoAnda mengatakan bahawa garis K terakhir perlu diperbaharui dan ditambahkan terlebih dahulu, kerana garis K terakhir sentiasa berubah, dan hanya apabila garis K baru dihasilkan, baris K sebelumnya akan ditetapkan. Saya tidak faham, bukankah data garis K yang diperoleh melalui `GetRecords (r) ` tidak pasti? `records (length -1) ` mewakili data garis K yang berada di garis masa semasa, langsung digambar ke dalam carta, dan data garis K yang baru digariskan, ditambah ke elemen terakhir carta, bukan?
ShandianliyuAdakah terdapat penjelasan yang lebih terperinci mengenai TA.ATR ((records, 14)), yang saya tidak dapati dalam dokumentasi API BotVS, video, dan juga panduan penggunaan penuh. Apabila saya memanggil TA.ATR ((records, 14) ((parameter adalah 30 minit k baris), kembali adalah satu barisan bilangan yang panjangnya 177. Apakah maksud barisan ini?
FangBeiVersi python https://dn-filebox.qbox.me/b5d2b0ecc1e196a6bfc68eb45cd818c50d279915.png https://dn-filebox.qbox.me/157db5e2659fd13bcf552cd82fe456ba469939f8.png
FangBeiversi python def main (: sementara benar: records = _C ((exchange.GetRecords); # Mendapatkan data baris K, dengan kata laluan yang ditetapkan secara lalai untuk pusingan baris K, _C adalah fungsi terbina dalam yang boleh disalahgunakan. macd = TA.MACD ((records); # Jika tidak menambahkan parameter, parameter lalai 12, 26, 9 digunakan Log (("macd[0]", macd[0]); # DIF Log (("macd[1]", macd[1]); # DEA Log (("macd[2]", macd[2]); # MACD Log (("macd[0] panjang", len ((macd[0])); # DIF panjang Log (("macd[1] panjang", len ((macd[1])); # DEA panjang Log (("macd[2] panjang", len ((macd[2])); # MACD panjang Log (("records Length:", len ((records)); # menunjukkan panjang rekod. Sleep ((1000 * 60 * 5);
Pencipta Kuantiti - Impian KecilTanda masa garis KBar adalah masa permulaan Bar ini, bukan masa nyata, dan masa permulaan Bar tidak berubah.
hokshelatoOh, yang saya fahami sebelum ini adalah kesalahan pada jam K-Line. Setelah di-debug, saya mendapati bahawa mekanisme BotVS adalah seperti ini, contohnya dengan K-Line yang anda katakan: Jika saya ingin mendapatkan data K-line pada 1 Mac, panggilan `GetRecords ((D1) ` akan mengembalikan banyak rekod, tetapi mereka semua mempunyai waktu yang sama, iaitu `2018-03-01 00:00:00 `. Maksudnya, walaupun saya memanggil `GetRecords(D1) ` pada 1 Mac pada pukul 10.00, garis masa K yang diperoleh masih 2018-03-01 **00**:00:00. Oleh itu, hanya dengan garis terakhir yang anda katakan tidak pasti sehingga ada garis masa baru, iaitu 2018-03-**02** 00:00:00, maka hari 1 Mac tidak pasti. Kesilapan yang saya fahami sebelum ini adalah bahawa saya mengira bahawa saya akan kembali pada 1 Mac pada pukul 1, 2 dan 3 pagi, iaitu pada 2018-03-01 **01**:00:00, 2018-03-01 **02**:00:00, 2018-03-01 **03**:00:00.
Pencipta Kuantiti - Impian KecilGetRecords (() mendapatkan data garis K. Kecuali bilangan pertama, selebihnya pasti (kerana kitaran telah selesai), bilangan pertama tidak pasti kerana kitaran tidak berakhir, Close sentiasa berubah. Contohnya garis K hari, tiang K hari semasa, ketika hari ini tidak berakhir, tidak ada yang tahu berapa harga hari ini akhirnya akan ditutup.
Pencipta Kuantiti - Impian KecilTidak sopan ^^
ShandianliyuSaya faham, terima kasih banyak!
Pencipta Kuantiti - Impian KecilYa, setaraf dengan bilangan negatif baris pertama K Bar.
ShandianliyuBaiklah, terima kasih banyak untuk jawapan anda. Akhirnya, pastikan, var a = TA.ATR ((records, 14), a[a.length-1] ini menunjukkan ATR data k baris terbaru, bukan?
Pencipta Kuantiti - Impian KecilYa, secara spesifik, jumlah pulangan adalah berdasarkan pertukaran dan tidak dapat ditentukan. Oleh itu, pertukaran biasanya menyediakan data yang terhad.
ShandianliyuSaya faham, TA.ATR adalah operasi matematik untuk rekod yang disalurkan. Saya tidak menjelaskan sebelum ini, saya ingin bertanya, adakah panjang yang dikembalikan ditentukan oleh pertukaran apabila mendapatkan data baris k dengan fungsi exchange.GetRecords?
Pencipta Kuantiti - Impian KecilFungsi indikator ini mengembalikan berapa banyak data yang sesuai dengan data K baris iaitu records, berapa panjang set rekod yang anda masukkan, berapa panjang yang dihitung.
ShandianliyuMaaf, saya masih tidak faham, maksud saya, jika fungsi ini dipanggil, apakah panjang data yang dikembalikan adalah yang diberikan oleh pertukaran? Saya mendapati bahawa apabila fungsi ini dipanggil pada masa yang berbeza, walaupun parameternya sama, panjang data yang dikembalikan mungkin berbeza.
Pencipta Kuantiti - Impian KecilIa ditentukan oleh panjang garis K ^^
ShandianliyuTerima kasih atas jawapan anda, ini jelas, dan saya ingin bertanya, apa yang menentukan panjang 117?
Pencipta Kuantiti - Impian KecilSebagai contoh, rekod yang dihantar adalah garis K hari, ATR yang dikira adalah satu set, dan elemen negatif pertama dari set ini adalah penunjuk ATR hari itu (tarikh garis K hari terakhir). Dengan itu, anda mengelaskan garis K 30 minit, garis K 15 minit. Set 177 yang dikira adalah 177 kitaran garis K, yang sepadan dengan penunjuk ATR setiap garis KBar.
Pencipta Kuantiti - Impian KecilBerikan dadah. Jika sekarang data garis K hanya 10 Bar, saya meminta MA ((15) iaitu garis rata 15 kitaran, maka pasti tidak boleh keluar, kerana hanya 10 kitaran, tidak dapat mengira purata 15 kitaran.
FangBeiSelain itu, saya menggunakan tick-back pada tahap cakera, dan tidak ada data yang dikembalikan.
FangBeiMengapa data di atas tidak memenuhi keperluan kitaran?
Pencipta Kuantiti - Impian KecilContoh ini agak baik, tetapi dalam penggunaan sebenar, data penunjuk terkini adalah pada titik terakhir, iaitu elemen indeks -1. Sebelumnya tidak memenuhi keperluan kitaran. Di bawah ini adalah data yang berguna, seperti: https://dn-filebox.qbox.me/b7837ea30e5d8396ffa91c48204f2fbc9a7f4504.png