TA 指标库
MACD 指数平滑异同平均线
KDJ 随机指标
RSI 强弱指标
ATR 平均真实波幅
OBV 能量潮
MA 移动平均线
EMA 指数平均数指标
BOLL 布林带
Alligator Alligator Indicator
CMF 蔡金货币流量指标
Highest 周期最高价
Lowest 周期最低价
Untuk mencoba menulis sebuah tes dengan indikator MACD, kita akan membuka label MACD pada dokumen API untuk melihat deskripsi lebih lanjut.
Jika siswa tertarik pada DIF, DEA, algoritma indikator, dll, mereka dapat pergi ke Baidu untuk mencari algoritma MACD, ada banyak sumber daya, antarmuka yang dikemas 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 tes piringan:
Seperti yang dapat dilihat, indikator yang dihitung pada awalnya adalah semua nol, dan data di kemudian hari mulai memiliki nilai tertentu, karena siklus penghitungan yang ditentukan oleh parameter indikator, tidak dapat dihitung indikator sebelum volume data (data catatan) memenuhi siklus ini. Oleh karena itu, sebelum menggunakan indikator, Anda harus memahami deskripsi indikator tersebut. Dan dalam program, menentukan panjang data K-line yang digunakan untuk menghitung indikator. Untuk menghindari menghitung nilai yang tidak valid jika panjangnya tidak cukup, dan menggunakan nilai yang tidak valid dapat menyebabkan kesalahan program.
Di bawah ini kita melihat kode dengan menggunakan antarmuka grafik untuk menunjukkan indikator yang dihitung pada grafik dan membandingkannya dengan grafik real-time di bursa (klik OKCoin untuk real-time):
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 siklus garis K pada antarmuka robot diatur menjadi 1 menit, karena perlu berjalan untuk melihat efeknya, maka pilih siklus yang sedikit lebih kecil.
Seperti yang terlihat dari grafik, inventor mengkuantifikasi robot yang berjalan. DIF yang dihitung sekitar 2.729 dan DEA sekitar 2.646 Bagan perdagangan OKCoin yang sebenarnya menunjukkan DIF sebesar 2.73 dan DEA sebesar 2.65 Seperti yang Anda lihat, dua DIF pertama, DEA, sedikit berbeda, OKCoin melakukan empat kali lima, MACD hampir dua kali lebih buruk karena OKCoin dihitung seperti ini: (DIF - DEA) * 2, biasanya DIF - DEA = 2.729 - 2.646 = 0.083, jika dikalikan lagi dengan 2 adalah 0.166 sekitar 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, parameter set adalah talib.STOCHRSI ((records, 14, 14, 3, 3); pada dasarnya masih kode yang mirip 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 gambarnya, tetapi ada perbedaan dengan angka resmi OKCoin, dan BOSS mengatakan algoritma implementasi dari talib mungkin berbeda dari OKCoin. Saya menelusuri internet dan menemukan sedikit informasi, jadi ada posting lain:Pengertian STOCHRSIAnda bisa melihat bagaimana indikatornya ditulis, yang saya tulis ini tidak dioptimalkan, sangat tidak efisien, berjalan lambat, dan harus belajar.
HokshelatoAnda mengatakan bahwa garis K terakhir perlu diperbarui dan ditambahkan terlebih dahulu, karena garis K terakhir selalu berubah, dan garis K sebelumnya hanya akan ditentukan setelah garis K baru dibuat. Saya tidak mengerti, apakah data K-line yang diperoleh dengan `GetRecords (r) ` tidak pasti? `records (length -1) ` mewakili data K-line yang berada di timestamp saat ini, langsung digambar ke dalam grafik, menunggu data K-line yang memiliki timestamp baru, dan ditambahkan ke elemen terakhir grafik, bukan?
ShandianliyuApakah ada penjelasan yang lebih rinci tentang TA.ATR ((records, 14)), yang tidak saya temukan di dokumentasi API BotVS, video, dan juga manual pengguna lengkap. Ketika saya memanggil TA.ATR ((records, 14) ((parameter adalah 30 menit k-line), yang dikembalikan adalah suatu array dengan panjang 177.
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 asumsi default bahwa siklus baris K yang ditetapkan oleh antarmuka kebijakan, _C adalah fungsi built-in yang toleran terhadap kesalahan. macd = TA.MACD ((records); # Jika tidak menambahkan parameter, parameter default digunakan adalah 12, 26, 9 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)); # Tampilkan panjang record. Sleep ((1000 * 60 * 5);
Penemu Kuantitas - Mimpi KecilK-line Bar adalah waktu awal dari Bar, bukan waktu nyata, dan waktu awal Bar tidak berubah.
HokshelatoWow, kesalahan yang saya pahami sebelumnya adalah pada timeline K. Setelah di-debug, saya menemukan bahwa mekanisme BotVS seperti ini, contohnya dengan K yang Anda sebutkan: Jika saya ingin mendapatkan data K-line pada tanggal 1 Maret, panggilan `GetRecords (D1) ` akan mengembalikan banyak catatan, tetapi mereka semua memiliki waktu yang sama, yaitu `2018-03-01 00:00:00 `. Dengan kata lain, bahkan jika saya menelepon GetRecords pada tanggal 1 Maret pukul 10.00 WIB, garis waktu K yang saya dapatkan masih 2018-03-01 **00**:00:00. Jadi hanya dengan garis terakhir yang Anda katakan akan tidak pasti, sampai ada garis waktu baru, yaitu 2018-03-**02** 00:00:00, maka tanggal 1 Maret tidak akan pasti. Yang saya salah paham sebelumnya adalah saya mengira bahwa saya kembali pada waktu yang berbeda setelah panggilan pada tanggal 1 Maret pukul 1, 2, dan 3 pagi, yaitu 2018-03-01 **01**:00:00, 2018-03-01 **02**:00:00, 2018-03-01 **03**:00:00.
Penemu Kuantitas - Mimpi KecilGetRecords mendapatkan data garis K. Kecuali digit pertama, sisanya pasti (karena siklus telah selesai), digit pertama tidak pasti karena siklus belum berakhir, Close selalu berubah. Misalnya, garis K hari ini, kolom K hari saat ini, ketika hari ini belum berakhir, tidak ada yang tahu berapa harga akhir hari ini.
Penemu Kuantitas - Mimpi KecilTidak sopan ^^
ShandianliyuSaya mengerti, terima kasih banyak!
Penemu Kuantitas - Mimpi KecilYa, yang sesuai dengan bilangan negatif garis K pertama Bar.
ShandianliyuBaik, terima kasih banyak atas jawabannya. Akhirnya, konfirmasi lagi, var a = TA.ATR ((records, 14), a[a.length-1] ini menunjukkan ATR dari data k baris terbaru, kan?
Penemu Kuantitas - Mimpi KecilYa, secara spesifik, jumlah pengembalian yang diberikan oleh bursa tidak dapat ditentukan. Oleh karena itu, bursa umumnya menyediakan data yang terbatas.
ShandianliyuYang saya mengerti, TA.ATR adalah operasi matematis terhadap rekaman yang dikirim. Saya tidak menjelaskan sebelumnya, saya ingin bertanya apakah panjang yang dikembalikan ditentukan oleh pertukaran ketika mendapatkan data k-string dengan fungsi exchange.GetRecords.
Penemu Kuantitas - Mimpi KecilFungsi indikator ini mengembalikan berapa banyak data yang sesuai dengan data baris K, yaitu records, berapa panjang array records yang Anda masukkan, berapa panjang yang dihitung.
ShandianliyuMaaf, saya masih belum mengerti, maksud saya, jika saya memanggil fungsi ini, apakah panjang data yang dikembalikan adalah yang diberikan oleh bursa? Saya menemukan bahwa ketika saya memanggil fungsi ini pada waktu yang berbeda, bahkan jika parameternya sama, panjang data yang dikembalikan mungkin berbeda.
Penemu Kuantitas - Mimpi KecilJadi kita bisa melihat bahwa kita memiliki panjang garis K.
ShandianliyuTerima kasih atas jawaban Anda, ini jelas, dan saya ingin bertanya, apa yang menentukan panjang 117?
Penemu Kuantitas - Mimpi KecilSebagai contoh, rekaman yang ditransmisikan adalah garis K hari, yang dihitung ATR adalah sebuah himpunan, dan elemen pertama dari bilangan negatif dari himpunan ini adalah indikator ATR hari itu (tanggal garis K hari terakhir). Kemudian, mengelompokkan garis K 30 menit, garis K 15 menit. Anda menghitung 177 himpunan adalah 177 siklus garis K, yang sesuai dengan indikator ATR untuk setiap garis KBar.
Penemu Kuantitas - Mimpi KecilPohon beraneka ragam Jika saat ini data garis K hanya 10 Bar, saya meminta MA ((15) yaitu garis rata 15 siklus, maka pasti tidak bisa keluar, karena hanya ada 10 siklus, tidak dapat menghitung rata-rata 15 siklus.
FangBeiSelain itu, saya melakukan tes balik dengan tik pada tingkat disk, dan tidak ada data yang dikembalikan.
FangBeiMengapa data di atas tidak memenuhi persyaratan siklus?
Penemu Kuantitas - Mimpi KecilContoh ini cukup bagus, hanya dalam penggunaan praktis, data indikator terbaru adalah yang terakhir dalam suatu array, yaitu elemen dengan indeks -1. Di bawah ini adalah data yang berguna, seperti: https://dn-filebox.qbox.me/b7837ea30e5d8396ffa91c48204f2fbc9a7f4504.png