Wie sollte das Glas der Preise aussehen? - Seite 12

 
Die Verzögerung bei der Veröffentlichung von tumbler ist darauf zurückzuführen, dass ein neuer Motortyp hergestellt werden muss. Als eigenständige Anwendung, die als unabhängiger Motor arbeitet, muss Beaker eine Benutzer-API bereitstellen, da es sonst als geschlossenes Programm viel weniger wert ist. Die Motoren, die ich in der Vergangenheit entwickelt habe, waren völlig abhängig von Benutzerbefehlen und hatten keine eigene Funktionalität. Der neue Motortyp muss sowohl unabhängig als auch von außen gesteuert arbeiten. Ich löse dieses Problem jetzt.
 

Heute wurde ein weiterer wichtiger Schritt nach vorn gemacht. Der Motor kann nun als eigenständige Anwendung arbeiten und seine Parameterwerte mit der angeschlossenen Benutzeranwendung synchronisieren. Die Anwendung ist wie zuvor verbunden, kann aber jetzt Werte abfragen, die von der Motorfunktionalität festgelegt werden. Dies ist also ein Übergang zu einer neuen Ebene der Interaktion zwischen den Programmen. Die Engine als eigenständiges Programm kann ihre Funktionalität akkumulieren und die den Anwendungen zur Verfügung gestellte API erweitern.

Im Falle des Preisstapels- er ist zu einer eigenständigen Anwendung geworden (die ich morgen, übermorgen fertigstellen werde), und funktioniert als Indikator. Über die Verbindung können die Benutzer die Werte dieses Bechers abrufen und überschreiben und sie in geänderter Form an den Becher zurückgeben. Zum Beispiel: Der Preis in einem der Glasfelder wurde vom Benutzercode analysiert, und es stellt sich heraus, dass es sich um den Stand eines wichtigen Indikators handelt. Der Benutzer sendet seine Markierung in dieses Feld, und sie wird neben dem Preis angezeigt. Dies eröffnet interessante neue Möglichkeiten für die Entwicklung sowohl von Motoren als auch von Anwenderprogrammen.

SZZ: Die GUI-Slider-Ereignisse, die bisher nur an die Anwendung gesendet wurden, werden jetzt auch intern von der Engine empfangen, und die parallele Verarbeitung von Ereignissen erfolgt an beiden Enden - in der Engine (gemäß meinem Code) und in der Benutzeranwendung (gemäß dem Benutzercode). Wenn Sie auf die Schaltfläche klicken, werden sowohl die Funktionen des Motors als auch die Funktionen der angeschlossenen Anwendung ausgelöst.
 
Eine weitere Sache, die in der Tasse fehlt, ist der Gewinn, wenn Sie jetzt auf dem Markt schließen, d.h. unter Berücksichtigung der Tassenfüllung - relevant für Positionen, die etwas größer sind als kleine (z.B. 100-150 Lots).
 
Wird es irgendwelche Hotkeys geben?
 
Andrey Gladyshev:
Wird es Hotkeys geben?
Ganz genau.
 
Aleksey Vyazmikin:
Eine weitere Sache, die in der Tasse fehlt, ist der Gewinn, wenn Sie jetzt auf dem Markt schließen, d.h. die Tasse füllen - relevant für Positionen, die etwas größer als klein sind (z.B. 100-150 Lots).
Bericht über die Becherfüllung. Ich werde nach der Veröffentlichung der Grundversion nachdenken, um nicht zu verzögern.
 
Der Preisbecher wird bereitstehen. Die Dokumentation der API-Verbindung war sehr verspätet. Es ist äußerst zeitaufwendig, die Dokumentation in einer eigenen Auszeichnungssprache zu verfassen. Und die Dokumentation des Bechers muss auch gemacht werden. Und das Glas selbst. Und zur gleichen Zeit, um den Code zu optimieren, Konstruktor, beheben Fehler und Funktionen hinzufügen. Deshalb ist er auch so lang. Aber dann wird alles schneller und schneller gehen.
 
In welcher Sprache ist das Programm geschrieben?
Wie hoch ist die tatsächliche Verarbeitungsgeschwindigkeit der eingehenden Daten?
Wie werden die Daten den Preisstufen zugeordnet?
Handelt es sich um eine for-Schleife oder gibt es eine Variable mit Daten für jede Ebene?
Die Tatsache, dass Sie die Art der Ansicht des Glases wie in westlichen Terminals gewählt haben, ist richtig.
Ich würde vorschlagen, den Becher um die Verwaltung verknüpfter OCO-Aufträge auf bis zu drei Ebenen zu erweitern.
Aber im Allgemeinen können wir jedes funktionale Western Market Dock nehmen und sehen, was darin implementiert ist.
Oder sehen Sie sich an, wie QScalp Scalper Drive implementiert ist.
 
Roman:
In welcher Sprache ist das Programm geschrieben?
Wie hoch ist die tatsächliche Verarbeitungsgeschwindigkeit der eingehenden Daten?
Wie sind die Daten nach Preisniveaus verteilt?
In einer for-Schleife oder for hat jede Ebene ihre eigene Variable mit Daten?
Die Tatsache, dass Sie die Art der Abbildung des Bechers gewählt haben, wie in den westlichen Terminals, ist richtig.
Ich würde vorschlagen, das Glas um die Verwaltung von verknüpften OCO-Geboten auf bis zu drei Ebenen zu ergänzen.

1. Das Programm ist in zwei Sprachen verfasst. Die Basissprache ist MQL5, und darauf aufbauend meine Auszeichnungssprache.

2. Wird auf die gleiche Weise verteilt wie gesendet. Ich meine in den richtigen Zellen. Es ist schwer in Worte zu fassen. Ich schicke Ihnen den Code später zu. Natürlich musste ich schwitzen, um die Daten in die richtigen Zellen zu bekommen, aber dieses Problem war gelöst.

3. Ich werde alles hinzufügen, wonach ich gefragt werde und was Sinn und Bedeutung hat.
 

Hier ist der Code für die Verteilung der Daten auf die Zellen in meinem Becher:

void On_DOM_Event()
{
 int t = 0;
 //----------------------------
 MqlTick last_tick;
 SymbolInfoTick(Symbol(),last_tick);
 //----------------------------
 MarketBookGet(NULL,priceArray); 
 //----------------------------
 double p = 0;
 long   ask_size = 0, bid_size = 0;
 int    s = ArraySize(priceArray);
 //----------------------------
 if(s > 0)
   {
    //-------------------------   ---
    for(int i1 = 0; i1 < 100; i1++)prices[i1]  = NULL;
    for(int i1 = 0; i1 < 100; i1++)ask_vol[i1] = NULL;
    for(int i1 = 0; i1 < 100; i1++)bid_vol[i1] = NULL; 
    //----------------------------
    int Closest_to_ask = 0;
    //----------------------------
    for(int a1 = 0; a1 < s; a1++)
      {
       if(
              priceArray[a1].price == last_tick.ask
          || (priceArray[a1].price < last_tick.ask && (((a1 + 1 < s) && priceArray[a1 + 1].price >= last_tick.bid) || (a1 + 1 == s)))
         )
         {
          Closest_to_ask = a1;
          break;
         } 
      } 
    //----------------------------
    for(int a2 = Closest_to_ask; a2 >= 0; a2--)
      { //Alert("t ",t,"  a2  ",a2);
       prices[49-t]  =  Normalize_Double(priceArray[a2].price,_Digits,_Point);
       ask_size     +=  priceArray[a2].volume;
       ask_vol[49-t] =  (string)priceArray[a2].volume;
       t++;
      }
    //--------------------------------  
    t = 0;
    //Alert("_Digits   ",_Digits);
    //--------------------------------  
    for(int a3 = Closest_to_ask + 1; a3 < s; a3++)
      { 
       prices[50+t]  =   Normalize_Double(priceArray[a3].price,_Digits,_Point);
       bid_size      +=  priceArray[a3].volume;
       bid_vol[50+t] =   (string)priceArray[a3].volume;
       t++;
      }         
 //------------------------------------------------       
 //------------------------------------------------ 
 E_DOM_1_Price(prices[40]);    E_DOM_1_Ask_size(ask_vol[40]);
 E_DOM_2_Price(prices[41]);    E_DOM_2_Ask_size(ask_vol[41]); 
 E_DOM_3_Price(prices[42]);    E_DOM_3_Ask_size(ask_vol[42]); 
 E_DOM_4_Price(prices[43]);    E_DOM_4_Ask_size(ask_vol[43]); 
 E_DOM_5_Price(prices[44]);    E_DOM_5_Ask_size(ask_vol[44]);
 E_DOM_6_Price(prices[45]);    E_DOM_6_Ask_size(ask_vol[45]);
 E_DOM_7_Price(prices[46]);    E_DOM_7_Ask_size(ask_vol[46]);
 E_DOM_8_Price(prices[47]);    E_DOM_8_Ask_size(ask_vol[47]);  
 E_DOM_9_Price(prices[48]);    E_DOM_9_Ask_size(ask_vol[48]); 
 E_DOM_10_Price(prices[49]);   E_DOM_10_Ask_size(ask_vol[49]);
 //-------------------------------------------------
 E_DOM_11_Price(prices[50]);  E_DOM_11_Bid_size(bid_vol[50]);
 E_DOM_12_Price(prices[51]);  E_DOM_12_Bid_size(bid_vol[51]);
 E_DOM_13_Price(prices[52]);  E_DOM_13_Bid_size(bid_vol[52]); 
 E_DOM_14_Price(prices[53]);  E_DOM_14_Bid_size(bid_vol[53]); 
 E_DOM_15_Price(prices[54]);  E_DOM_15_Bid_size(bid_vol[54]); 
 E_DOM_16_Price(prices[55]);  E_DOM_16_Bid_size(bid_vol[55]); 
 E_DOM_17_Price(prices[56]);  E_DOM_17_Bid_size(bid_vol[56]); 
 E_DOM_18_Price(prices[57]);  E_DOM_18_Bid_size(bid_vol[57]);    
 E_DOM_19_Price(prices[58]);  E_DOM_19_Bid_size(bid_vol[58]); 
 E_DOM_20_Price(prices[59]);  E_DOM_20_Bid_size(bid_vol[59]);
 //------------------------------------------------- 
 }
 RMSG(1);
}


Um die eingehenden Daten zu erfassen, habe ich ein Array mit 100 Zellen erstellt. Ich verteile die eingehenden Daten von der Mitte des Arrays (Zelle 49) auf die asc- und bid-Seite, wobei ich zuvor den nächstgelegenen Preis zur asc- und bid-Seite berechne.