Comment et pourquoi ai-je écrit un analyseur pour le site Web Tradingview. Automatisation du commerce de bricolage

Problème: À l'heure actuelle, le célèbre TSLAB est le logiciel le plus pratique et le plus complet (ci - après dénommé logiciel) pour l'automatisation du commerce sur le marché boursier russe.


Malgré les avantages incontestables sous la forme d'un éditeur visuel pratique pour l'écriture de scripts de trading, qui vous permet d'écrire des robots même sans connaissance des langages de programmation, il existe un certain nombre d'inconvénients qui rendent l'utilisation de ce logiciel extrêmement peu rentable pour moi. Et je pense non seulement pour moi, étant donné que la taille moyenne d'un compte à Mosbirz ne dépasse généralement pas 500 000 roubles.


1. Coût: frais d'abonnement de 4500 roubles par mois + location d'un serveur virtuel (1000 roubles par mois)
Ce coût fixe pèse très lourdement sur le résultat financier de mon métier. Par conséquent, ayant une taille de compte de 500 mille roubles et en espérant en tirer au moins 20% par an, avec les coûts existants, vous devez gagner environ 32 à 35% pour atteindre la rentabilité prévue.


2. Instabilité du travail: Malgré le fait que mes algorithmes fonctionnent principalement avec des ordres de marché (type d'ordres, qui suppose une exécution à 100%), mes positions ont souvent doublé ou n'ont pas été exécutées du tout.


Objectif: écrire un logiciel pour automatiser le trading afin de minimiser les coûts fixes avec une interface pratique pour créer des scripts de trading qui vous permet d'écrire des robots de trading sans aucune connaissance approfondie de la programmation.


L'architecture de l'ensemble du projet avec les améliorations actuelles et fonctionnelles et prévues est présentée dans la figure ci-dessous.



Le lien le plus important du programme est sans aucun doute le site Web Tradingview (ci-après dénommé TV). Il nous présente simplement des fonctionnalités pratiques pour écrire ses scripts de trading en raison du langage Pine_Script intégré.


La langue, en passant, ne nécessite pas de connaissances spécifiques et ressemble essentiellement à la langue facile du package Metastock, et la disponibilité de l'aide en ligne en russe rend l'écriture du code aussi agréable que possible.


Un exemple de stratégie pour briser la moyenne mobile (littéralement en trois lignes de code):


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) 

Ayant maintenant une interface pratique pour écrire des scripts de trading, il reste à établir le processus d'envoi des applications de la télévision directement au système de trading (dans mon cas, c'est le programme Quik), ou directement au serveur du courtier. Le seul problème est que le téléviseur n'a pas d'API ouverte pour implémenter cette fonctionnalité.


En essayant de résoudre ce problème, la première chose qui m'est venue a été d'utiliser un plug-in pour tester WebSelenium et en recherchant les localisateurs XPath pour trouver les éléments dont nous avons besoin qui sont responsables des signaux d'achat-vente.


Les signaux eux-mêmes sont affichés dans le tableau et il ne devrait y avoir aucun problème. Mais pour rechercher le signal extrême, la table nécessitait un défilement, mais je n'ai pas pu trouver l'élément de défilement (voir la figure ci-dessous).



J'ai donc dû chercher une autre solution.


Visuellement, les signaux TV sont affichés dans l'élément canvas. La couleur du signal peut être modifiée si nécessaire (ex: vente rouge, achat vert).


Les couleurs définies dans le téléviseur que nous avons définies dans notre application. L'application elle-même est écrite en Java, l'interface graphique est implémentée à l'aide de la bibliothèque Swing
Plus loin dans le programme lui-même, nous devons sélectionner la zone de canevas (ou simplement la zone numérisée), dans laquelle nous rechercherons les couleurs de contrôle.


La figure ci-dessous montre le site de tradingview avec trois instruments sélectionnés, la couleur du signal de trading est définie pour chacun d'eux. Ces couleurs sont dupliquées dans mon programme Parse_Signal.


.


Après avoir défini la zone de numérisation et défini le type de l'instrument à échanger (en passant, les paramètres du programme prennent 5 minutes et sont enregistrés dans un fichier avec l'extension .txt). Ensuite, appuyez sur le bouton "START" et le programme commence à fonctionner.


Cela fonctionne en deux fils.


1 premier fil:


  • Numérise la zone sélectionnée (dans ce cas, le canevas).
    Nous effectuons le scan de façon classique en utilisant les fonctionnalités de la classe Robot:


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

  • Ensuite, il divise le scan résultant en un tableau de pixels:


     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; 

  • Recherche dans le tableau de pixels les couleurs de contrôle des signaux de trading. Recherche de gauche à droite. C'est-à-dire c'est la couleur du pixel le plus à droite qui est pertinente pour le programme:


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


  • Enregistre une transaction commerciale (dans un fichier avec l'extension .tri) selon le modèle, en fonction de la couleur trouvée. Ici, en fait, tout est simple dans le terminal de trading Quik, il est possible de lire automatiquement les transactions d'un fichier. Il nous suffit de les enregistrer selon un certain schéma. Quik, lorsqu'une nouvelle entrée apparaît, envoie une demande au serveur du courtier. Le fichier est lu toutes les 500 ms. Les informations sur les signaux de trading peuvent éventuellement être envoyées soit par courrier, soit par téléphone, soit au système de trading (trois paramètres peuvent être sélectionnés simultanément). 1 thread fonctionne avec une fréquence de 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 le flux de programme exécute la demande de prix de l'instrument négocié en analysant la page html du site Finam . Le plugin JSOUP est utilisé. Ici, je télécharge simplement les pages html et recherche le code de l'instrument de trading requis (ex: Si, Sber, etc.).


 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) 

Il est clair qu'il s'agit d'un maillon faible du programme, car toute modification de la page html lèvera une exception. Par conséquent, à l'avenir, il est prévu de demander des informations d'échange à demander directement via Quik, ou directement depuis le serveur du courtier.
Pour ce faire, vous pouvez utiliser la bibliothèque .dll prête à l'emploi pour Quik en C #, mais puisque j'écris en Java, dans mon cas, il sera plus facile d'implémenter un script en lua (le langage Quik intégré), qui enregistrera les prix d'achat et de vente dans un fichier séparé, que le programme Parse_Signal et lira ensuite.


Il convient de noter qu'en fait, nous obtenons un bouquet plutôt volumineux de TV + Parser + Quik. Et malgré la stabilité de cette solution, il est prévu à l'avenir d'envoyer des applications non pas à Quik, mais directement au serveur du courtier ( ex: utilisation de l'interface Atlentis d'Alor en option ). La bibliothèque est vraiment à nouveau implémentée en C #, vous devez donc trouver quelque chose.


Ce programme m'a permis de résoudre les tâches initiales que je me suis fixées:
à savoir, parfois, pour réduire les coûts fixes.


Le code du programme est publié dans le domaine public.


Si quelqu'un est prêt à partager ses idées sur l'interaction avec la télévision, je serai très heureux de le voir dans les commentaires.

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


All Articles