MT5 e trans2quik.dll - pagina 15

 
Konstantin Nikitin:

Bene, è possibile inviare le informazioni necessarie da QUIK attraverso un file, come opzione.

Sì, tsu è stato scritto da molto tempo per le sveltine, ma non funziona velocemente,

Volevo renderlo più veloce...

 
prostotrader:

Sì, tsu è stato scritto da molto tempo per le sveltine, ma non funziona velocemente,

Volevo renderlo più veloce...

Potete semplicemente gettare un altro script in Quicksilver e lasciare che alimenti continuamente le informazioni di cui avete bisogno nel file. E ciò che è scritto, lasciatelo funzionare così com'è, se vi va bene.

 
prostotrader:

Non c'è ancora nulla da spiegare, c'è un problema con gli ordini pendenti, non ci sono callback in MT5.

Voglio avere ordini pendenti nel mio arsenale.

Saluti agli habitué locali. Potete provare i modelli di programmazione(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Sono anche interessato alla connessione di diversi mercati, voglio chiedere della vostra connessione. Per quanto ho capito dall'esempio, tutte le informazioni sono ottenute da MT5 e la vista rapida è usata solo per aprire gli ordini tramite Trans2Quick dll, giusto?

O cercherai di usare un altro modo per ricevere i dati dal broker? Se ricordo bene è meglio usare lua per ottenere dati dal Quicksilver, ma bisogna aumentare la connessione con il terminale...

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

Saluti dagli habitué locali. Si può provare a usare modelli di programmazione(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Sono anche interessato alla questione del collegamento di diversi mercati, vorrei chiedere del vostro collegamento. Per quanto ho capito dall'esempio, tutte le informazioni sono ottenute da MT5 e la vista rapida è usata solo per aprire gli ordini tramite Trans2Quick dll, giusto?

O cercherai di usare un altro modo per ricevere i dati dal broker? Se ricordo bene è meglio usare lua per ricevere dati dal Quicksilver, ma bisogna aumentare la connessione con il terminale...

Ho già scritto che ho scritto tutto tramite DDE - Il mio programma - trans2quik.dll

Ma questa combinazione non funziona abbastanza velocemente (a occhio si può vedere come quik rimane indietro rispetto a MT5 nello stack).

Volevo ricevere dati di mercato tramite MT5 e inviare ordini tramite trans2quik.dll,

Ma ho dimenticato il depo, può essere ottenuto solo dalla vista rapida.

Non voglio andare oltre.

 

Una "finestra" è apparsa nella costruzione e ho deciso di continuare ad esportare i dati da MT5 in tempo reale.

Ho implementato l'esportazione postMessageW, funziona abbastanza velocemente, ma a volte i dati si "bloccano".

Codice di Expert Advisor

//+------------------------------------------------------------------+
//|                                                     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);
  }  
//+------------------------------------------------------------------+

Codice dell'applicazione (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.

All'inizio ho pensato che fosse un errore di divisione, per ottenere il DOPPIO, ma MT5 moltiplica il numero per 10 alla potenza di n,

e nell'applicazione il numero risultante viene diviso per 10 alla potenza di n.

Non dovrebbe esserci un errore.

Forse sto facendo qualcosa di sbagliato?

(appendice compilata in allegato)

Aggiunto da

È per questo?


File:
Mess_test.zip  997 kb
 

Tutto funziona



Vantaggi di

1. le esportazioni lavorano molto rapidamente e non caricano il terminale o il sistema

2. Codice minimo.

3. Nessuna DLL necessaria.

Svantaggi

1. È possibile trasferire solo LONG, ULONG, DOUBLE (con limitazione del valore numerico) e fino a 127 bit di testo ANSI (solo in inglese)

Aggiunto

Resta da inviare PostMessage con deposito a Quickie via LUA.

Qualcuno ha provato PostMessage da Quick (LUA)?

Questo è necessario per gli account EBS.

 
prostotrader:

Tutto funziona.

Puoi dirmi di più su come usarlo, cosa fare?

 
Aleksey Vyazmikin:

Puoi dirmi di più su come usarlo e cosa fare?

Tutti questi "gadget" sono necessari per il trading via Quick sui conti EBS (o per l'analisi in tempo reale dei dati al di fuori della MT5).

L' uscita dei dati alla mia applicazione da KVIK lento via DDE è molto lenta,

quindi i dati sono presi da MT5, e gli ordini di trading sono inviati a Kvik tramite la loro API (trans2quik.dll).

Il meccanismo è

MT5 --> Applicazione propria <--> trans2quik.dll <--> Quick

Ecco un esempio di trading in futures veloci rispetto alle azioni


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

Tutti questi "gadget" sono necessari per fare trading tramite QuickBooks su conti EBS (o per l'analisi in tempo reale dei dati al di fuori della MT5).

L'uscita dei dati alla vostra applicazione dal Quik lento via DDE è molto lenta,

quindi i dati sono presi da MT5, e gli ordini di trading sono inviati a Kvik tramite la loro API (trans2quik.dll).

Il meccanismo è

MT5 --> Applicazione propria <--> trans2quik.dll <--> Quick

Ecco un esempio di trading in Kvik per i futures contro le azioni


Non è più facile mettere il secondo terminale MT5 al mercato azionario per questo compito specifico, e trasferire le informazioni tra due terminali tramite il canale PIPE?

Quest'anno farò il mercato azionario secondo questo schema.

 
Dmi3:

Non è più facile mettere un secondo terminale MT5 sul mercato azionario e trasferire le informazioni tra i due terminali tramite il canale PIPE per questo compito specifico?

Quest'anno farò il mercato azionario secondo questo schema.

Stai proponendo un "casino" ancora più grande, il conto EBS è buono perché il denaro non è diviso in sezioni.

Quello che avete visto nel video funziona, ma molto lentamente!

Quick --> DDE --> Il mio pad <--> trans2quik.dl <--> Quick

Ho sostituito Quick --> DDE --> con MT5 --> PostMessage -->.

È diventato molto più veloce.

Detto questo, 2 righe di codice e nessun carico sul terminale e sul sistema.

Invio di messaggi

//+------------------------------------------------------------------+
//| 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);
    }
  }  
} 

Ricezione di messaggi

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;