Bagaimana dan mengapa saya menulis parser untuk situs web Tradingview. Otomasi perdagangan DIY

Masalah: Saat ini, perangkat lunak yang paling nyaman dan lengkap (selanjutnya disebut sebagai perangkat lunak) untuk otomasi perdagangan di pasar saham Rusia adalah TSLAB yang terkenal kejam .


Meskipun ada kelebihan yang tidak diragukan dalam bentuk editor visual yang nyaman untuk menulis skrip perdagangan, yang memungkinkan Anda untuk menulis robot bahkan tanpa pengetahuan bahasa pemrograman, ada sejumlah kelemahan yang membuat menggunakan perangkat lunak ini sangat tidak menguntungkan bagi saya. Dan saya pikir tidak hanya untuk saya, mengingat bahwa ukuran rata-rata akun di Mosbirz sebagai aturan tidak melebihi 500 ribu rubel.


1. Biaya: Biaya berlangganan 4.500 rubel per bulan + sewa server virtual (1000 rubel per bulan)
Biaya tetap ini menempatkan beban yang sangat berat pada hasil keuangan perdagangan saya. Karena itu, memiliki ukuran akun 500 ribu rubel dan berharap untuk mendapatkan setidaknya 20% per tahun darinya, dengan biaya yang ada Anda perlu mendapatkan sekitar 32-35% untuk mencapai profitabilitas yang direncanakan.


2. Ketidakstabilan kerja: Terlepas dari kenyataan bahwa algoritma saya bekerja terutama dengan pesanan pasar (jenis pesanan, yang mengasumsikan eksekusi 100%), posisi saya sering berlipat ganda atau tidak dieksekusi sama sekali.


Tujuan: Menulis perangkat lunak untuk mengotomatiskan perdagangan untuk meminimalkan biaya tetap dengan antarmuka yang nyaman untuk membuat skrip perdagangan yang memungkinkan Anda untuk menulis robot perdagangan tanpa pengetahuan pemrograman yang mendalam.


Arsitektur seluruh proyek dengan fungsi saat ini dan fungsionalitas serta perbaikan yang direncanakan disajikan pada gambar di bawah ini.



Tautan paling penting dalam program ini tidak diragukan lagi adalah situs web Tradingview (selanjutnya disebut sebagai TV). Itu hanya menyajikan kepada kita fungsionalitas yang nyaman untuk menulis skrip perdagangannya karena bahasa Pine_Script bawaan.


Ngomong-ngomong, bahasa tersebut tidak memerlukan pengetahuan khusus dan pada dasarnya menyerupai paket Easy Language of Metastock, dan ketersediaan bantuan online dalam bahasa Rusia membuat penulisan kode senyaman mungkin.


Contoh strategi untuk menerobos moving average (secara harfiah dalam tiga baris kode):


mov_average=sma(close,x) strategy.entry("My Long Entry Id", strategy.long,when=close>mov_average) strategy.entry("My Short Entry Id", strategy.short,when=close<mov_average) 

Sekarang memiliki antarmuka yang nyaman untuk menulis skrip perdagangan, masih harus menetapkan proses pengiriman aplikasi dari TV langsung ke sistem perdagangan (dalam kasus saya, ini adalah Quik), atau langsung ke server broker. Satu-satunya masalah adalah bahwa TV tidak memiliki API terbuka untuk mengimplementasikan fungsi ini.


Dalam mencoba menyelesaikan masalah ini, hal pertama yang terjadi pada saya adalah menggunakan plug-in untuk menguji WebSelenium dan dengan mencari pencari XPath untuk menemukan elemen yang kita butuhkan yang bertanggung jawab untuk sinyal jual-beli.


Sinyal itu sendiri ditampilkan di tabel, dan seharusnya tidak ada masalah. Tetapi untuk mencari sinyal ekstrem, tabel membutuhkan pengguliran, tetapi saya tidak dapat menemukan elemen gulir (lihat gambar di bawah).



Karena itu, saya harus mencari solusi lain.


Secara visual, sinyal TV ditampilkan di elemen kanvas. Warna sinyal dapat diubah jika perlu (mis: penjualan-merah, pembelian-hijau).


Warna yang diatur di TV kita atur di aplikasi kita. Aplikasi itu sendiri ditulis dalam Java, antarmuka grafis diimplementasikan menggunakan perpustakaan Swing
Lebih jauh dalam program itu sendiri, kita perlu memilih area kanvas (atau hanya area yang dipindai), di mana kita akan mencari warna kontrol.


Gambar di bawah ini menunjukkan situs web tradingview dengan tiga instrumen yang dipilih, warna sinyal perdagangan ditetapkan untuk masing-masing instrumen tersebut. Warna-warna ini diduplikasi dalam program Parse_Signal saya.


.


Setelah mengatur area pemindaian dan pengaturan dalam jenis instrumen yang diperdagangkan (omong-omong, pengaturan program membutuhkan waktu 5 menit dan disimpan dalam file dengan ekstensi .txt). Selanjutnya, tekan tombol "MULAI" dan program mulai bekerja.


Ini bekerja dalam dua utas.


1 utas pertama:


  • Memindai area yang dipilih (dalam hal ini, kanvas).
    Kami melakukan pemindaian secara klasik menggunakan fungsi dari kelas Robot:


     BufferedImage buf= robot.createScreenCapture(new Rectangle(selection.x, selection.y, selection.width, selection.height)) 

  • Selanjutnya, ini membagi hasil pemindaian menjadi array piksel:


     int[] pixels = copyFromBufferedImage(buf); //,     ,        : public int[] copyFromBufferedImage(BufferedImage bi) { int[] pict = new int[bi.getHeight() * bi.getWidth()]; for (int i = 0; i < bi.getWidth(); i++) for (int j = 0; j < bi.getHeight(); j++) pict[i * bi.getHeight() + j] = bi.getRGB(i, j) & 0xFFFFFF; // 0xFFFFFF:   3   RGB return pict; 

  • Pencarian dalam array piksel untuk warna kontrol sinyal perdagangan. Cari dari kiri ke kanan. Yaitu itu adalah warna piksel paling kanan yang relevan untuk program:


     for(int i=0;i<pixels.length;i++ ) { if (pixels[i] == (buy.getBackground().getRGB() & 0xFFFFFF)) { position = 1; //System.out.println("  ")} else if (pixels[i] == (sell.getBackground().getRGB() & 0xFFFFFF)) { position = -1; //System.out.println("  ");} else if (pixels[i] == (hold.getBackground().getRGB() & 0xFFFFFF)) { position = 0; ...................... ...................... 


  • Merekam transaksi perdagangan (dalam file dengan ekstensi .tri) sesuai dengan templat, tergantung pada warna yang ditemukan. Di sini, pada kenyataannya, semuanya sederhana di terminal perdagangan Quik, dimungkinkan untuk secara otomatis membaca transaksi dari file. Cukup bagi kita untuk mendaftarkannya sesuai dengan pola tertentu. Quik, ketika sebuah entri baru muncul, mengirimkan permintaan ke server broker. File dibaca setiap 500 ms. Informasi tentang sinyal perdagangan dapat secara opsional dikirim baik ke surat, atau telepon, atau ke sistem perdagangan (tiga parameter dapat dipilih secara bersamaan). 1 utas bekerja dengan frekuensi 500 ms.



 if (position==1&&status!=1&&b1==1) { if(dialog.isSend_phone()==true) { new SMS().sendSms(dialog.getPhone(), "TS_1:    "+ (String)dialog.cbFirst.getSelectedItem()+" "+price+" "+new Date(), "TEST-SMS", dialog.getLogin(), dialog.getPassword());} if(dialog.isSend_trade()==true){ tr.Order_Buy();} if(dialog.isSend_mail()==true){ test.sendSignal("BUY","TS_1: Buy in signal at price "+ (String)dialog.cbFirst.getSelectedItem()+" "+price+" "+new Date());} status = 1;} ...................... ...................... 

2 aliran program melakukan permintaan untuk harga instrumen yang diperdagangkan dengan mem-parsing halaman html situs Finam . Plugin JSOUP digunakan. Di sini, saya cukup mengunggah halaman html dan mencari kode instrumen perdagangan yang diperlukan (mis: Si, Sber, dll.).


 public void run() { while (true) { Document doc = null; Document doc_2 = null; try { doc = Jsoup.connect("https://www.finam.ru/quotes/futures/moex/").get(); doc_2 = Jsoup.connect("https://www.finam.ru/profile/mosbirzha-fyuchersy/sbrf").get();} catch (IOException e) { e.printStackTrace(); continue;} StringBuffer buffer = new StringBuffer(doc.text()); StringBuffer buffer_2 = new StringBuffer(doc_2.text()); Map<String, String> map = new HashMap<>() try {map.put(elements[1], buffer.substring(buffer.indexOf("Si "), buffer.indexOf("Si ") + 8).split("Si ")[1]); map.put(elements[2], buffer.substring(buffer.indexOf("RTS "), buffer.indexOf("RTS ") + 10).split("RTS ")[1]); map.put(elements[3], buffer.substring(buffer.indexOf("LKOH "), buffer.indexOf("LKOH ") + 10).split("LKOH ")[1]); map.put(elements[4], buffer.substring(buffer.indexOf("BR "), buffer.indexOf("BR ") +8).split("BR ")[1]); map.put(elements[5], buffer.substring(buffer.indexOf("GAZP "), buffer.indexOf("GAZP ") + 10).split("GAZP ")[1]); map.put(elements[6], buffer.substring(buffer.indexOf("GOLD "), buffer.indexOf("GOLD ") + 11).split("GOLD ")[1]); map.put(elements[7], buffer.substring(buffer.indexOf("MOEX "), buffer.indexOf("MOEX ") + 10).split("MOEX ")[1]); map.put(elements[8], buffer.substring(buffer.indexOf("MIX "), buffer.indexOf("MIX ") + 10).split("MIX ")[1]); map.put(elements[9], "0"); map.put(elements[10], buffer_2.substring(buffer_2.indexOf("  "), buffer_2.indexOf("  ") + 23).split(" ")[2] + buffer_2.substring(buffer_2.indexOf("  "), buffer_2.indexOf("  ") + 23).split(" ")[3]);} catch (Exception e) { System.out.println(e); text.setText("     "); continue;} price = String.valueOf((int) Double.parseDouble(map.get((String) 

Jelas bahwa ini adalah tautan yang lemah dalam program, karena setiap perubahan pada halaman html akan memunculkan Pengecualian. Oleh karena itu, di masa depan direncanakan untuk meminta informasi pertukaran untuk meminta langsung melalui Quik, atau langsung dari server broker.
Untuk melakukan ini, Anda dapat menggunakan pustaka .dll siap pakai untuk Quik di C #, tetapi karena saya menulis di Jawa, dalam kasus saya akan lebih mudah untuk mengimplementasikan skrip dalam lua (bahasa Quik bawaan), yang akan mencatat harga pembelian dan penjualan dalam file terpisah, yang mana program Parse_Signal dan kemudian akan membaca.


Perlu dicatat bahwa sebenarnya kita mendapatkan banyak TV + Parser + Quik. Dan terlepas dari stabilitas solusi ini, di masa depan direncanakan untuk mengirim aplikasi bukan ke Quik, tetapi langsung ke server broker ( mis: menggunakan antarmuka Atlentis dari Alora sebagai pilihan ). Perpustakaan benar-benar sekali lagi diimplementasikan dalam C #, jadi Anda harus datang dengan sesuatu.


Program ini memungkinkan saya untuk menyelesaikan tugas-tugas awal yang saya tetapkan untuk diri saya sendiri:
yaitu, kadang-kadang mengurangi biaya tetap.


Kode program diposting di domain publik.


Jika seseorang siap untuk membagikan ide mereka tentang berinteraksi dengan TV, saya akan sangat senang melihat ini di komentar.

Source: https://habr.com/ru/post/id447912/


All Articles