Dalam artikel sebelumnya, kami menerangkan premis pelaksanaan strategi perdagangan dari pengenalan bahasa C ++, tatabahasa asas, dan struktur strategi.
Salah satu penunjuk yang paling biasa digunakan dalam analisis teknikal, KDJ, diiktiraf oleh kebanyakan peniaga di seluruh dunia. Nama penuh KDJ
KDJ berdasarkan teori statistik, nilai rawak (RSV) dikira oleh nisbah harga tertinggi, terendah dan penutupan garis 9 K baru-baru ini. kemudian mengira nilai K, nilai D dan nilai J mengikut purata bergerak, dan melukis grafik untuk menilai trend harga.
Dengan menggabungkan kelebihan konsep momentum, penunjuk kekuatan dan purata bergerak, kita mengukur tahap perubahan harga saham dari pergerakan julat normal. Apabila nilai K lebih besar daripada nilai D, ia menunjukkan bahawa harga saham kini berada dalam trend menaik. Oleh itu, apabila garis K melintasi garis D dari bawah ke atas, ia adalah masa untuk membeli saham. Sebaliknya, apabila nilai K kurang dari nilai D, ia menunjukkan bahawa pasaran saham kini berada dalam trend menurun. Oleh itu, apabila garis K melintasi garis D dari atas ke bawah, ia adalah masa untuk menjual saham.
Pengiraan penunjuk KDJ adalah rumit. Pertama, nilai rawak (RSV) dikira, dan kemudian nilai K, nilai D, dan nilai J dikira. Kaedah penghitungannya adalah seperti berikut:
RSV = (harga penutupan - N tempoh harga terendah) / (N kitaran harga tertinggi - N kitaran harga terendah) * 100
Nilai K = purata N kitaran RSV
D nilai = purata N kitaran K
J nilai = 3 * K nilai -2 * D nilai
void main(){ // the program starts from this main function
while (true){ // enter the loop
auto ct = exchange.SetContractType(symblo); //set the contract type
auto r = exchange.GetRecords(); // get the K line array
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0]arr[0].size() - 2]; // get the previous k line KDJ indicator K value
auto d = arr[1]arr[1].size() - 2]; // get the previous k line KDJ indicator D value
auto j = arr[2]arr[2].size() - 2]; // get the previous k line KDJ indicator J value
}
}
Terdapat banyak cara untuk menggunakan KDJ, yang boleh digunakan secara bersendirian atau digabungkan dengan penunjuk lain. Artikel ini kita akan menggunakannya dengan cara yang paling mudah, iaitu: Jika nilai K lebih besar daripada nilai D, kita percaya bahawa kuasa beli menguat, gelombang pasaran yang meningkat telah terbentuk, dan isyarat kedudukan panjang pembukaan dihasilkan; jika nilai K kurang daripada nilai D, kita percaya bahawa kuasa penjualan menguat, dan gelombang trend menurun telah terbentuk, isyarat kedudukan pendek pembukaan dihasilkan.
Jika nilai D berubah dari atas ke bawah selepas kedudukan dibuka, kita percaya bahawa kuasa beli melemah, atau kuasa jual menguat, dan isyarat kedudukan panjang penutupan dihasilkan; jika kedudukan pendek dibuka, nilai D berubah dari bawah ke atas, kita percaya bahawa kekuatan kuasa jual melemah, atau bahawa kuasa beli menguat, dan isyarat kedudukan pendek ditutup dihasilkan.
Posisi panjang terbuka: Jika tidak ada kedudukan, dan nilai K lebih besar daripada nilai D
Posisi pendek: Jika tidak ada kedudukan, dan nilai K adalah kurang daripada nilai D
Penutupan kedudukan panjang: Jika terdapat kedudukan panjang yang dipegang dan nilai D adalah kurang daripada nilai D garis K yang menembusi
Penutupan kedudukan pendek: Jika terdapat kedudukan pendek yang dipegang dan nilai D lebih besar daripada nilai D garis K yang menembusi
Langkah pertama dalam melaksanakan strategi dengan kod adalah untuk terlebih dahulu mempertimbangkan apa data yang kita perlukan? melalui API mana untuk mendapatkan? selepas kita mendapat data, bagaimana untuk mengira logik perdagangan? seterusnya, mana cara untuk meletakkan pesanan? akhirnya, mari kita pelaksanaannya langkah demi langkah:
Yang dipanggil seni bina strategi adalah cara untuk merancang keseluruhan strategi. Seperti yang ditunjukkan di bawah, seni bina terdiri daripada dua fungsi: satu adalah fungsi utama, program bermula dari fungsi utama, dan fungsinya adalah untuk menangani teras logika strategi. perkara seperti: menilai sama ada sambungan dengan pertukaran ok, menapis maklumat log yang tidak perlu, kawalan selang masa pelaksanaan teras logika strategi; dan yang lain adalah fungsi onTick, dalam fungsi ini, terutamanya adalah logika strategi, yang terdiri daripada: Dapatkan data mentah, mengira data, tempat pesanan, dan banyak lagi.
bool onTick(){ // onTick function
// strategy logic
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick()){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Kod di atas adalah kerangka strategi C ++ yang dicipta oleh alat platform FMZ Quant. Ini adalah format pengekodan tetap, semua logik perdagangan bermula dari baris 2, dan tidak ada perubahan yang dibuat di tempat lain. Di samping itu, jika anda seorang veteran, anda boleh menambah atau mengubah suai ciri mengikut keperluan anda.
Anda boleh menganggap perpustakaan kelas dagangan sebagai modul fungsional. Kelebihan menggunakan perpustakaan kelas dagangan adalah ia membolehkan anda memberi tumpuan kepada menulis logik strategi. Sebagai contoh, apabila kita menggunakan perpustakaan kelas dagangan, untuk membuka atau menutup kedudukan, kita boleh menggunakan antara muka API secara langsung dalam perpustakaan kelas dagangan; tetapi jika kita tidak menggunakan perpustakaan kelas dagangan, kita perlu mendapatkan harga pasaran ketika membuka kedudukan. Perlu mempertimbangkan isu pesanan yang tidak dilaksanakan dan isu pesanan pengeluaran, dan sebagainya.
Data mentah yang berbeza adalah bahagian penting dalam logik perdagangan. Data apa yang kita perlukan? Dari logik perdagangan strategi kita, kita mula-mula perlu mendapatkan data garis K. Dengan data garis K asal, kita boleh mengira penunjuk KDJ, dan akhirnya membandingkan hubungan antara nilai K dan nilai D untuk menentukan sama ada untuk meletakkan pesanan. Jadi mari kita dapatkan data ini.
Pertama, kita perlu mendapatkan susunan K-garis, kerana susunan K-garis akan digunakan untuk mengira penunjuk KDJ. seperti berikut:
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Seperti yang ditunjukkan di atas:
Baris 1 : Menentukan pembolehubah yang digunakan untuk menerima status kedudukan.
Baris 3 hingga 12: Fungsi onTick ditakrifkan, dan fungsi ini membawa parameter. Parameter ini adalah untuk lulus dalam pelbagai perdagangan, dalam kes ini, menggunakan k-garis mingguan.
Baris 14 hingga 24: Tentukan fungsi utama yang mengendalikan logik bukan strategi. Satu-satunya perkara yang boleh diubah ialah kod kontrak
Mari kita fokus pada fungsi onTick dan lihat bagaimana ia mendapat data K-garis:
Baris 4 hingga 7 : tetapkan jenis kontrak dan jenis dagangan, jika jenis kontrak dan jenis dagangan tidak berjaya, pulangkan false
Baris 8: Dapatkan susunan K-baris, yang merupakan format tetap.
Lini 9 hingga 11: Saring panjang garis K, kerana parameter yang kita gunakan untuk mengira penunjuk KDJ adalah 9. Apabila bilangan garis K kurang daripada 9, mustahil untuk mengira penunjuk KDJ. Jadi di sini kita ingin menyaring panjang garis K. Jika garis K kurang daripada 10, hanya kembali false terus dan terus menunggu garis K seterusnya.
Seterusnya, kita perlu mengira nilai K dan D penunjuk KDJ. Adalah perlu untuk mendapatkan array penunjuk KDJ terlebih dahulu, dan mendapatkan nilai K dan nilai D dari array ini. Pada platform FMZ Quant, mendapatkan array KDJ sangat mudah, hanya hubungi API KDJ, kesukaran adalah untuk mendapatkan nilai nilai K dan D, kerana array KDJ adalah array dua dimensi.
Array dua dimensi sebenarnya mudah difahami, yang merupakan array array, urutan yang diperoleh adalah: mula-mula mendapatkan array yang ditentukan dalam array, dan kemudian mendapatkan elemen yang ditentukan dari array yang ditentukan, seperti yang ditunjukkan di bawah:
#include <iostream>
using namespace std;
int main(){
int hour [3][2] = {{100, 50}, {66, 88}, {10, 90}};
cout << hours[0][0]; // get the hours array first elements of first element, the result is 100
cout << hours[0][1]; // get the hours array first elements of second element, the result is 50
cout << hours[1][0]; // get the hours array second elements of first element, the result is 66
return(0);
}
Seperti yang ditunjukkan di bawah, baris ke-12 secara langsung menggunakan API FMZ Quant untuk mendapatkan array penunjuk KDJ, yang merupakan array dua dimensi: arr = [nilai K, nilai K, nilai K...], [nilai D, nilai D, nilai D...], [nilai J, nilai J, nilai J...]]
Baris 13 adalah untuk mendapatkan nilai k dari baris K sebelumnya, nilai K adalah arr[0], kemudian mendapatkan elemen penultimate dari arr[0], arr[0].size() boleh digunakan untuk memperoleh panjang array arr[0], arr[0].size() - 2 adalah elemen terakhir kedua array, letakkan bersama adalah: auto k = arr [0] [arr [0].size () - 2 ]; baris 14 dan 15 adalah pengiraan yang sama.
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Dengan data di atas, kita boleh menulis logik perdagangan dan meletakkan bahagian pesanan sekarang. Ia juga sangat mudah, yang paling biasa digunakan adalah pernyataan
double position = 0; // position status parameter, the default is 0
bool onTick(string symbol){ // onTick function, all strategy logic are in this function
auto ct = exchange.SetContractType(symbol); // set the contract type and trading variety
if(ct == false){ // if the setting contract type and trading variety is not successful
return false; // return false
}
auto r = exchange.GetRecords(); // get the k-line array
if(!r.Valid || r.size() < 10){ // if getting the k-line array or the number of k-line is less than 10
return false; // return false
}
auto arr = TA.KDJ(r, 9, 3, 3); // calculate the KDJ indicator
auto k = arr[0][arr[0].size() - 2]; // get the K value of the previous K line
auto d = arr[1][arr[1].size() - 2]; // get the D value of the previous K line
auto dPre = arr[1][arr[1].size() - 3]; // get the D value of the second last of the K line
string action; // define a string variable action
// if currently holding long position, and the previous K line's D value is less than the second last k line's D value, close all position
// if currently holding short position, and the previous K line's D value is greater than the second last k line's D value, close all position
if((d < dPre && position > 0) || (d > dPre && position <0)){
action = "cover";
}else if (k > d && position <= 0){ // if the previous K line's K value is greater than the previous K line's D value, and there are no long positions
action = "buy"; // set the variable action to "buy"
}else if (k < d && position >= 0){ // if the previous K line's K value is less than the previous K line's D value, and there are no short positions
action = "sell"; // set the variable action to "sell"
}
if (action.size() > 0){ // if there are placing order instruction
position = ext::Trade(action, symbol, 1); // calling the C++ trading class library, placing orders according the direction of variable "action". and also renew the position status.
}
return true; // return true
}
}
void main(){ // program starts from here
while (true){ // enter the loop
if (exchange.IO("status") == 0) // if the connection with the exchange if not stable.
sleep(1000); // pause for 1 second
continue; // skip this loop, enter the next loop
}
if(!onTick("this_week")){ // if the connection with the exchange is stable, enter this if loop, start executing the onTick function
sleep(1000); // pause for 1 second
}
}
}
Dalam kod di atas, baris 19 hingga 28 adalah logika perdagangan dan kod untuk meletakkan pesanan. Walau bagaimanapun, sebelum ini, kita perlu menentukan pembolehubah rentetan " tindakan " pada baris 16, yang digunakan untuk membantu menentukan tindakan pesanan.
Baris 19 hingga baris 21 adalah: jika kini memegang kedudukan panjang, dan nilai K garis sebelumnya
Baris 21 hingga baris 25 adalah: syarat untuk membuka kedudukan panjang dan pendek. Apabila syarat itu benar, set
Baris 26 hingga baris 28 menjalankan logik pesanan penempatan. Pertama, mengikut panjang pembolehubah rentetan
Terdapat dua tempat yang perlu diperhatikan:
Cuba (tetapi tidak semestinya) menulis logik strategi seperti keadaan K-line semasa ditubuhkan, kemudian meletakkan pesanan pada k-line seterusnya. atau keadaan k-line sebelumnya ditubuhkan, meletakkan pesanan pada k-line semasa, dengan cara ini, hasil backtest dan prestasi pasaran sebenar tidak jauh berbeza.
Secara amnya, logik kedudukan penutupan harus ditulis di hadapan logik kedudukan pembukaan. Tujuan ini adalah untuk cuba membuat logik strategi memenuhi jangkaan anda. Sebagai contoh, jika logik strategi hanya memenuhi keadaan di mana ia perlu melakukan arah yang bertentangan perdagangan selepas hanya menutup kedudukan, peraturan situasi jenis ini adalah untuk menutup kedudukan pertama dan kemudian membuka kedudukan baru. Jika kita menulis logik kedudukan penutupan di hadapan logik kedudukan pembukaan, ia akan sempurna memenuhi peraturan ini.
Di atas kita belajar bagaimana untuk menganalisis penunjuk teknikal KDJ dan mengubahnya menjadi strategi perdagangan kuantitatif yang lengkap. Termasuk: pengenalan strategi, kaedah pengiraan penunjuk KDJ, logik strategi, syarat perdagangan, pelaksanaan kod strategi, dll. Melalui kes strategi ini, bukan sahaja kita berkenalan dengan kaedah pengaturcaraan C ++ pada platform FMZ Quant, tetapi juga strategi yang berbeza boleh disesuaikan mengikut kes dalam bahagian ini.
Untuk mencapai strategi perdagangan kuantitatif adalah meringkaskan pengalaman atau sistem perdagangan subjektif kita sendiri, dan kemudian mendapatkan data mentah yang diperlukan secara berasingan, dan mengira data yang diperlukan untuk logik strategi, dan akhirnya memanggil API pesanan untuk merealisasikan perdagangan.
Setakat ini, tutorial penulisan strategi dalam siri ini telah sampai ke penghujungnya, saya percaya bahawa jika anda mengikuti tutorial langkah demi langkah yang membawa anda ke sini, anda akan mendapat banyak. Bagaimanapun, dari perspektif kursus asas perdagangan kuantitatif, Jalan Panjang telah berjalan lebih daripada separuh. Dalam bab terakhir, kami akan mengajar anda bagaimana menggunakan alat perdagangan backtesting FMZ Quant, dan bagaimana mengelakkan lubang dalam backtesting dan membuat persediaan akhir untuk perdagangan pasaran sebenar. Walaupun ia adalah sebahagian kecil kandungan, ia adalah langkah besar dalam memasuki dunia perdagangan kuantitatif!
Cuba untuk melaksanakan algoritma penunjuk KDJ menggunakan bahasa C ++ pada platform FMZ Quant.
Cuba gunakan pengetahuan dalam seksyen ini untuk membuat strategi penunjuk CCI.