Problem: Derzeit ist das berüchtigte TSLAB die bequemste und vollständigste Software (im Folgenden als Software bezeichnet) für die Handelsautomatisierung an der russischen Börse.
Trotz der unbestrittenen Vorteile in Form eines praktischen visuellen Editors zum Schreiben von Handelsskripten, mit dem Sie Roboter auch ohne Kenntnisse der Programmiersprachen schreiben können, gibt es eine Reihe von Nachteilen, die die Verwendung dieser Software für mich äußerst unrentabel machen. Und ich denke nicht nur für mich, da die durchschnittliche Größe eines Kontos bei Mosbirz in der Regel 500.000 Rubel nicht überschreitet.
1. Kosten: Abonnementgebühr von 4500 Rubel pro Monat + Miete eines virtuellen Servers (1000 Rubel pro Monat)
Diese Fixkosten belasten das finanzielle Ergebnis meines Handels sehr stark. Daher mit einer Kontogröße von 500 Tausend Rubel und in der Hoffnung, mindestens 20% pro Jahr daraus zu ziehen, müssen Sie bei den vorhandenen Kosten etwa 32-35% verdienen, um die geplante Rentabilität zu erreichen.
2. Instabilität der Arbeit: Trotz der Tatsache, dass meine Algorithmen hauptsächlich mit Marktaufträgen arbeiten (Art von Aufträgen, die eine 100% ige Ausführung voraussetzen), haben sich meine Positionen oft verdoppelt oder wurden überhaupt nicht ausgeführt.
Ziel: Schreiben von Software zur Automatisierung des Handels zur Minimierung der Fixkosten mit einer praktischen Schnittstelle zum Erstellen von Handelsskripten, mit der Sie Handelsroboter ohne fundierte Programmierkenntnisse schreiben können.
Die Architektur des gesamten Projekts mit den aktuellen und funktionalen und geplanten Verbesserungen ist in der folgenden Abbildung dargestellt.

Der wichtigste Link in der Sendung ist zweifellos die Tradingview-Website (im Folgenden als TV bezeichnet). Aufgrund der integrierten Pine_Script-Sprache bietet es uns lediglich praktische Funktionen zum Schreiben seiner Handelsskripte.
Die Sprache erfordert übrigens keine spezifischen Kenntnisse und ähnelt im Wesentlichen der Easy Language des Metastock-Pakets. Die Verfügbarkeit der Online-Hilfe auf Russisch macht das Schreiben des Codes so angenehm wie möglich.
Ein Beispiel für eine Strategie zum Durchbrechen des gleitenden Durchschnitts (buchstäblich in drei Codezeilen):
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)
Jetzt, da es eine praktische Schnittstelle zum Schreiben von Handelsskripten gibt, muss der Prozess des Sendens von Anwendungen vom Fernsehen direkt an das Handelssystem (in meinem Fall Quik) oder direkt an den Server des Brokers festgelegt werden. Das einzige Problem ist, dass TV keine offene API zum Implementieren dieser Funktionalität hat.
Bei dem Versuch, dieses Problem zu lösen, fiel mir zunächst ein Plug-In zum Testen von WebSelenium ein und durchsuchte XPath-Locators, um die Elemente zu finden, die für Kauf- und Verkaufssignale erforderlich sind.
Die Signale selbst werden in der Tabelle angezeigt und es sollten keine Probleme auftreten. Um nach dem extremen Signal zu suchen, musste in der Tabelle gescrollt werden, aber ich konnte das Bildlaufelement nicht finden (siehe Abbildung unten).

Deshalb musste ich nach einer anderen Lösung suchen.
Visuell werden die TV-Signale im Canvas-Element angezeigt. Die Signalfarbe kann bei Bedarf geändert werden (zB: Rotverkauf, Grünkauf).
Die im Fernsehen eingestellten Farben stellen wir in unserer Anwendung ein. Die Anwendung selbst ist in Java geschrieben, die grafische Oberfläche wird mithilfe der Swing-Bibliothek implementiert
Weiter im Programm selbst müssen wir den Canvas-Bereich (oder nur den gescannten Bereich) auswählen, in dem wir nach Steuerfarben suchen.
Die folgende Abbildung zeigt die Tradingview-Website mit drei ausgewählten Instrumenten, für die jeweils die Farbe des Handelssignals festgelegt ist. Diese Farben werden in meinem Parse_Signal-Programm dupliziert.
.
Nach dem Einstellen des Scanbereichs und dem Einstellen des Typs des gehandelten Instruments (die Programmeinstellungen dauern übrigens 5 Minuten und werden in einer Datei mit der Erweiterung .txt gespeichert). Drücken Sie anschließend die Taste "START" und das Programm beginnt zu arbeiten.
Es funktioniert in zwei Threads.
1 erster Thread:
Scannt den ausgewählten Bereich (in diesem Fall Leinwand).
Wir führen den Scan klassisch mit der Funktionalität der Robot-Klasse durch:
BufferedImage buf= robot.createScreenCapture(new Rectangle(selection.x, selection.y, selection.width, selection.height))
Als nächstes wird der resultierende Scan in ein Array von Pixeln aufgeteilt:
int[] pixels = copyFromBufferedImage(buf);
Sucht im Pixelarray nach den Steuerfarben von Handelssignalen. Suche von links nach rechts. Das heißt, Es ist die Farbe des Pixels ganz rechts, die für das Programm relevant ist:
for(int i=0;i<pixels.length;i++ ) { if (pixels[i] == (buy.getBackground().getRGB() & 0xFFFFFF)) { position = 1;

Zeichnet eine Handelstransaktion (in einer Datei mit der Erweiterung .tri) gemäß der Vorlage auf, abhängig von der gefundenen Farbe. Hier ist im Quik-Handelsterminal eigentlich alles einfach, es ist möglich, Transaktionen automatisch aus einer Datei zu lesen. Es reicht uns, sie nach einem bestimmten Muster zu registrieren. Wenn ein neuer Eintrag angezeigt wird, sendet Quik eine Anfrage an den Server des Brokers. Die Datei wird alle 500 ms gelesen. Informationen zu Handelssignalen können optional entweder per Post, Telefon oder an das Handelssystem gesendet werden (drei Parameter können gleichzeitig ausgewählt werden). 1 Thread arbeitet mit einer Frequenz von 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 Der Programmablauf führt die Anforderung des Preises des gehandelten Instruments durch, indem er die HTML-Seite der Finam- Site analysiert . Das JSOUP-Plugin wird verwendet. Hier lade ich einfach die HTML-Seiten hoch und suche nach dem Code des gewünschten Handelsinstruments (zB Si, Sber usw.).
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)
Es ist klar, dass dies ein schwaches Glied im Programm ist, da jede Änderung an der HTML-Seite eine Ausnahme auslöst. Daher ist es in Zukunft geplant, Austauschinformationen anzufordern, um diese direkt über Quik oder direkt vom Server des Brokers anzufordern.
Zu diesem Zweck können Sie die vorgefertigte DLL-Bibliothek für Quik in C # verwenden. Da ich jedoch in Java schreibe, ist es in meinem Fall einfacher, ein Skript in Lua (der integrierten Quik-Sprache) zu implementieren, das die Kauf- und Verkaufspreise in einer separaten Datei aufzeichnet, die das Programm erstellt Parse_Signal und liest dann.
Es sollte beachtet werden, dass wir tatsächlich eine ziemlich sperrige Menge von TV + Parser + Quik bekommen. Und trotz der Stabilität dieser Lösung ist geplant, Anwendungen in Zukunft nicht an Quik, sondern direkt an den Broker-Server zu senden ( z. B. mit der Atlentis-Schnittstelle von Alora als Option ). Die Bibliothek ist wirklich wieder in C # implementiert, also müssen Sie sich etwas einfallen lassen.
Mit diesem Programm konnte ich die ersten Aufgaben lösen, die ich mir selbst gestellt hatte:
nämlich zeitweise zur Reduzierung der Fixkosten.
Der Programmcode wird gemeinfrei veröffentlicht.
Wenn jemand bereit ist, seine Ideen zur Interaktion mit dem Fernsehen zu teilen, würde ich mich sehr freuen, dies in den Kommentaren zu sehen.