MT5 und trans2quik.dll - Seite 15

 
Konstantin Nikitin:

Nun, Sie können die notwendigen Informationen von QUIK optional über eine Datei senden.

Ja, tsu, ich habe alles schon vor langer Zeit für den Quickie geschrieben, aber es geht nicht schnell,

Ich wollte es schneller machen...

 
prostotrader:

Ja, tsu, ich habe alles schon vor langer Zeit für den Quickie geschrieben, aber es geht nicht schnell,

Ich wollte es schneller machen...

Sie können einfach ein weiteres Skript in Quicksilver einfügen und es kontinuierlich die benötigten Informationen in die Datei einspeisen lassen. Und was geschrieben steht, soll so funktionieren, wie es ist, wenn es Ihnen passt.

 
prostotrader:

Es gibt noch nichts zu erklären, es gibt ein Problem mit Pending Orders, es gibt keine Callbacks im MT5.

Ich möchte schwebende Aufträge in meinem Arsenal haben.

Grüße an die lokalen Stammgäste. Sie können die Programmiervorlagen ausprobieren(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Ich interessiere mich auch für die Verbindung mehrerer Märkte, ich möchte nach Ihrer Verbindung fragen. Soweit ich das Beispiel verstanden habe, werden alle Informationen von MT5 bezogen und die Schnellansicht wird nur für die Eröffnung von Aufträgen über Trans2Quick dll verwendet, richtig?

Oder werden Sie versuchen, auf andere Weise Daten vom Broker zu erhalten? Soweit ich mich erinnere, ist es besser, lua zu verwenden, um Daten vom Quicksilver zu erhalten, aber Sie müssen die Verbindung mit dem Terminal erhöhen...

Паттерн (шаблон) проектирования Observer (наблюдатель)
Паттерн (шаблон) проектирования Observer (наблюдатель)
  • cpp-reference.ru
Паттерн Observer определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются и обновляются автоматически. Паттерн Observer инкапсулирует главный (независимый) компонент в абстракцию Subject и изменяемые (зависимые) компоненты в иерархию Observer. Паттерн...
 
Andrey Azatskiy:

Grüße von lokalen Stammgästen. Sie können versuchen, Programmiervorlagen zu verwenden(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Ich interessiere mich auch für das Thema der Verknüpfung mehrerer Märkte, ich möchte Sie nach Ihrer Verknüpfung fragen. Soweit ich das Beispiel verstanden habe, werden alle Informationen von MT5 bezogen und die Schnellansicht wird nur für die Eröffnung von Aufträgen über Trans2Quick dll verwendet, richtig?

Oder werden Sie versuchen, auf andere Weise Daten vom Broker zu erhalten? Soweit ich mich erinnere, ist es besser, lua zu verwenden, um Daten vom Quicksilver zu erhalten, aber Sie müssen die Verbindung mit dem Terminal erhöhen...

Ich habe bereits geschrieben, dass ich alles per DDE geschrieben habe - Mein Programm - trans2quik.dll

Aber diese Kombination funktioniert nicht schnell genug (mit dem Auge kann man sehen, wie quik im Stapel hinter MT5 zurückbleibt).

Ich wollte Marktdaten über MT5 empfangen und Aufträge über trans2quik.dll senden,

Aber ich habe das Depot vergessen, es kann nur über die Schnellansicht abgerufen werden.

Ich möchte nicht weiter gehen.

 

Ein "Fenster" erschien im Aufbau und ich beschloss, den Export von Daten aus MT5 in Echtzeit fortzusetzen.

Ich habe postMessageW Export implementiert, es funktioniert schnell genug, aber manchmal bleiben die Daten "stecken".

Code des Expertenberaters

//+------------------------------------------------------------------+
//|                                                     PostMess.mq5 |
//|                                      Copyright 2021 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"

#define  HANDLE  long
#define  PVOID   long
#define  WM_USER 0x400
#define  WM_PR_ASK WM_USER + 10
#define  WM_PR_BID WM_USER + 20

#import "User32.dll"
bool PostMessageW(HANDLE hWnd, uint Msg, PVOID wParam, PVOID lParam);
#import

input long HWND = 111111111; //Hahdle window

PVOID wPar, lPar;
HANDLE Wnd;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Wnd = HWND;
   wPar = Digits();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   lPar = 0;
   double s_ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
   if(wPar > 0)
     {
      double a_val = MathPow(10, double(wPar));
      lPar = long(s_ask * a_val);
     }
   else
      lPar = long(s_ask);
   bool result = PostMessageW(Wnd, WM_PR_ASK, wPar, lPar);
//---
   lPar = 0;
   s_ask = SymbolInfoDouble(Symbol(), SYMBOL_BID);
   if(wPar > 0)
     {
      double a_val = MathPow(10, double(wPar));
      lPar = long(s_ask * a_val);
     }
   else
      lPar = long(s_ask);
   result = PostMessageW(Wnd, WM_PR_BID, wPar, lPar);
  }  
//+------------------------------------------------------------------+

Anwendungscode (Delphi XE4)

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Math;

const
  WM_PR_ASK = WM_USER + 10;
  WM_PR_BID = WM_USER + 20;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    procedure ResiveMessPrAsk(var Msg: TMessage); message WM_PR_ASK;
    procedure ResiveMessPrBid(var Msg: TMessage); message WM_PR_BID;
  public

    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1.Caption:= 'Handle: ' + intToStr(integer(Form1.Handle));
end;

procedure TForm1.ResiveMessPrAsk;
var
  a_ask: double;
begin
  if(Msg.WParam > 0) then
  begin
    a_ask:= IntPower(10, Msg.WParam);
    a_ask:= Msg.lParam/a_ask;
  end else
  begin
    a_ask:= Msg.lParam;
  end;
  Label2.Caption:= 'Ask: ' + FloatToStr(a_ask);
  Label2.Update();
end;

procedure TForm1.ResiveMessPrBid;
var
  a_bid: double;
begin
  if(Msg.WParam > 0) then
  begin
    a_bid:= IntPower(10, Msg.WParam);
    a_bid:= Msg.lParam/a_bid;
  end else
  begin
    a_bid:= Msg.lParam;
  end;
  Label3.Caption:= 'Bid: ' + FloatToStr(a_bid);
  Label3.Update();
end;

end.

Zuerst dachte ich, es sei ein Divisionsfehler, um DOUBLE zu erhalten, aber MT5 multipliziert die Zahl mit 10 hoch n,

und in der App wird die resultierende Zahl durch 10 hoch n geteilt.

Es sollte kein Fehler auftreten.

Vielleicht mache ich etwas falsch?

(Zusammenstellung im Anhang)

Hinzugefügt von

Ist das der Grund?


Dateien:
Mess_test.zip  997 kb
 

Alles funktioniert



Vorteile von

1 Der Export funktioniert sehr schnell und belastet weder das Terminal noch das System.

2. Minimaler Code.

3. keine DLL erforderlich.

Benachteiligungen

1. Sie können nur LONG, ULONG, DOUBLE (mit Zahlenwertbegrenzung) und bis zu 127 Bit ANSI-Text (nur Englisch) übertragen.

Hinzugefügt

Bleibt noch, PostMessage mit Einzahlung an Quickie über LUA zu senden.

Hat jemand PostMessage von Quick (LUA) ausprobiert?

Dies ist für EBS-Konten erforderlich.

 
prostotrader:

Alles funktioniert.

Können Sie mir mehr darüber sagen, wie man es benutzt und was man tun muss?

 
Aleksey Vyazmikin:

Können Sie mir mehr darüber sagen, wie ich das verwenden kann und was zu tun ist?

Alle diese "Gadgets" werden für den Handel über Quick auf EBS-Konten (oder für die Echtzeitanalyse von Daten außerhalb von MT5) benötigt.

Die Datenausgabe an meine Anwendung aus dem langsamen KVIK über DDE ist sehr langsam,

Die Daten werden also von MT5 übernommen, und die Handelsaufträge werden über deren API (trans2quik.dll) an Kvik gesendet.

Der Mechanismus ist

MT5 --> Eigene Anwendung <--> trans2quik.dll <--> Schnell

Hier ein Beispiel für den Handel mit Quick-Futures im Vergleich zu Aktien


Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Типы торговых операций
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Типы торговых операций
  • www.mql5.com
Типы торговых операций - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
prostotrader:

Alle diese "Gadgets" werden benötigt, um über QuickBooks auf EBS-Konten zu handeln (oder für die Echtzeitanalyse von Daten außerhalb von MT5).

Die Datenausgabe an Ihre Anwendung vom langsamen Quik über DDE ist sehr langsam,

Die Daten werden also von MT5 übernommen, und die Handelsaufträge werden über deren API (trans2quik.dll) an Kvik gesendet.

Der Mechanismus ist

MT5 --> Eigene Anwendung <--> trans2quik.dll <--> Schnell

Hier ist ein Beispiel für den Handel in Kvik für Futures und Aktien


Ist es nicht einfacher, das zweite MT5-Terminal auf den Aktienmarkt zu setzen und die Informationen zwischen den beiden Terminals über den PIPE-Kanal für diese spezielle Aufgabe zu übertragen?

Ich werde dieses Jahr nach diesem Schema an die Börse gehen.

 
Dmi3:

Ist es nicht einfacher, ein zweites MT5-Terminal an der Börse zu platzieren und Informationen zwischen den beiden Terminals über den PIPE-Kanal für diese spezielle Aufgabe zu übertragen?

Ich werde in diesem Jahr den Aktienmarkt nach diesem Schema bearbeiten.

Sie schlagen ein noch größeres "Durcheinander" vor. Das EBS-Konto ist gut, weil das Geld nicht in Abschnitte aufgeteilt ist.

Was Sie im Video gesehen haben, funktioniert, aber sehr langsam!

Schnell --> DDE --> Mein Block <--> trans2quik.dl <--> Schnell

Ich habe Quick --> DDE --> durch MT5 --> PostMessage --> ersetzt.

Es wurde viel schneller.

Das heißt, 2 Zeilen Code und keine Belastung für das Terminal und das System.

Senden von Nachrichten

//+------------------------------------------------------------------+
//| OnBookvent function                                              |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol())
  {
    GetBook(Symbol(), book_data);
    if((book_data.ask_vol > 0) && (book_data.bid_vol > 0))
    {
      lPar = 0;
      wPar = 0;
      long a_vol = book_data.ask_vol;
      wPar += a_vol<<=8;
      long a_val = long(MathPow(10, double(s_digits)));
      lPar = long(NormalizeDouble((book_data.ask * a_val), 0));
      wPar += ulong(s_digits);
      bool result = PostMessageW(Wnd, WM_PR_ASK, wPar, lPar);
      lPar = 0;
      wPar = 0;
      a_vol = book_data.bid_vol;
      wPar += a_vol<<=8;
      a_val = long(MathPow(10, double(s_digits)));
      lPar = long(NormalizeDouble((book_data.bid * a_val), 0));
      wPar += ulong(s_digits);
      result = PostMessageW(Wnd, WM_PR_BID, wPar, lPar);
      lPar = 0;
      wPar = 0;
      double last = NormalizeDouble(SymbolInfoDouble(Symbol(), SYMBOL_LAST), s_digits);
      a_val = long(MathPow(10, double(s_digits)));
      lPar = long(NormalizeDouble(last * a_val, 0));
      wPar += ulong(s_digits);
      result = PostMessageW(Wnd, WM_LAST, wPar, lPar);
      lPar = 0;
      wPar = 0;
      double f_money = NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE), 2);
      a_val = long(MathPow(10, double(2)));
      lPar = long(NormalizeDouble(f_money * a_val, 0));
      wPar += 2;
      result = PostMessageW(Wnd, WM_FREE_MONEY, wPar, lPar);
    }
  }  
} 

Empfang von Nachrichten

procedure TForm1.AppMessages;
var
  a_value: double;
  s: string;
  i: Integer;
  val, m_val, a_vol: int64;
  is_comma: boolean;
begin
  if(Msg.message = WM_EBS_MONEY) then
  begin
    //beep;
  end else
  begin
    if(Msg.hwnd = Handle) then      //Check message handle
    case Msg.message of
      WM_NAME:
        begin
          is_comma:= false;
          s:= '';
          for i := 0 to 7 do
          begin
            val:= Msg.wParam;
            val:= (val shr (56 - i*8) and 255);
            if(val = 46) then is_comma:= true;
            if((val >= 45) and (val <= 122)) then
              s:= s + string(AnsiChar(val)) else
              if((val > 0) and (is_comma = false)) then s:= s + IntToStr(val) else
                if(is_comma = true) then s:= s + IntToStr(val);
          end;
          Label1.Caption:= 'Name: ' + s;
          Label1.Update();
        end;
        WM_SPOT_NAME:
        begin
          s:= '';
          if(Msg.wParam > 0) then
          for i := 0 to 7 do
          begin
            val:= Msg.wParam;
            val:= (val shr (56 - i*8) and 255);
            if((val >= 45) and (val <= 122)) then
              s:= s + string(AnsiChar(val));
          end;
          if(Msg.lParam > 0) then
          for i := 0 to 7 do
          begin
            val:= Msg.lParam;
            val:= (val shr (56 - i*8) and 255);
            if((val >= 45) and (val <= 122)) then
              s:= s + string(AnsiChar(val));
          end;
          Label4.Caption:= 'SPOT Name: ' + s;
          Label4.Update();
        end;
      WM_PR_ASK:
        begin
          m_val:= Msg.WParam;
          m_val:= m_val and 255;
          a_vol:= Msg.WParam;
          a_vol:= (a_vol shr 8) and $FFFF;
          if(m_val > 0) then
          begin
            a_value:= IntPower(10, integer(m_val));
            a_value:= Msg.lParam/a_value;
          end else a_value:= Msg.lParam;
          Label2.Caption:= 'Ask: ' + FloatToStr(a_value) + ' Volume: ' + IntToStr(a_vol);
          Label2.Update();
        end;
      WM_PR_BID:
        begin
          m_val:= Msg.WParam;
          m_val:= m_val and 255;
          a_vol:= Msg.WParam;
          a_vol:= (a_vol shr 8) and $FFFF;
          if(m_val > 0) then
          begin
            a_value:= IntPower(10, integer(m_val));
            a_value:= Msg.lParam/a_value;
          end else a_value:= Msg.lParam;
          Label3.Caption:= 'Bid: ' + FloatToStr(a_value) + ' Volume: ' + IntToStr(a_vol);
          Label3.Update();
        end;
      WM_LAST:
        begin
          m_val:= Msg.WParam;
          m_val:= m_val and 255;
          if(m_val > 0) then
          begin
            a_value:= IntPower(10, integer(m_val));
            a_value:= Msg.lParam/a_value;
          end else a_value:= Msg.lParam;
          Label5.Caption:= 'Last: ' + FloatToStr(a_value);
          Label5.Update();
        end;
      WM_FREE_MONEY:
        begin
          m_val:= Msg.WParam;
          m_val:= m_val and 255;
          if(m_val > 0) then
          begin
            a_value:= IntPower(10, integer(m_val));
            a_value:= Msg.lParam/a_value;
          end else a_value:= Msg.lParam;
          Label6.Caption:= 'Free money: ' + FloatToStr(a_value);
          Label6.Update();
        end;
    end;
  end;
end;