2.7 Penggunaan penunjuk

Penulis:Mimpi kecil, Dicipta: 2016-11-10 16:19:36, Dikemas kini: 2019-08-01 09:25:06

Penggunaan penunjuk


  • TA - Mengoptimumkan penulisan semula sebahagian daripada fungsi indeks yang biasa digunakan

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.

img

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:

img

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:

img img

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.

Kaedah penggunaan penunjuk lain adalah hampir sama.

  • Talib -http://ta-lib.org/

    Selain daripada penunjuk yang biasa digunakan di TA, terdapat banyak lagi penunjuk di Talib. Sebagai contoh, kita cuba menggunakan indikator talib.STOCHRSI dan lihat penerangan dokumen 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)]

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.


Lebih lanjut

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);

Mimpi 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.

Mimpi 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.

Mimpi kecilTidak sopan ^^

ShandianliyuSaya faham, terima kasih banyak!

Mimpi 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?

Mimpi 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?

Mimpi 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.

Mimpi kecilIa ditentukan oleh panjang garis K ^^

ShandianliyuTerima kasih atas jawapan anda, ini jelas, dan saya ingin bertanya, apa yang menentukan panjang 117?

Mimpi 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.

Mimpi 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?

Mimpi 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