MT5 and trans2quik.dll - page 15

 
Konstantin Nikitin:

Well, you can send the necessary information from QUIK through a file, as an option.

Yes tsu has been written for a long time for quickie, but it doesn't work fast,

I wanted to make it faster...

 
prostotrader:

Yes tsu I wrote everything a long time ago for the quickie, but it doesn't work fast,

I wanted to make it faster...

You can just throw in another script in the Quicksilver and let it continuously feed the information you need into the file. And what is written, let it work as it is, if it suits you.

 
prostotrader:

There is nothing to explain yet, there is a problem with pending orders, there are no callbacks in MT5.

I want to have pending orders in my arsenal.

Greetings local regulars. You can try the programming templates(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
I am also interested in the connection of several markets, I want to ask about your connection. As far as I understood from the example, all information is obtained from MT5 and the quick view is used only for opening orders via Trans2Quick dll, right?

Or will you try to use another way to receive data from the broker? As I remember it is better to use lua to get data from the Quicksilver, but you have to increase the connection with the terminal...

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

Greetings from local regulars. You may try to use programming templates(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
I am also interested in the issue of linking several markets, I would like to ask about your linking. As far as I understood from the example, all information is obtained from MT5 and the quick view is used only for opening orders via Trans2Quick dll, right?

Or will you try to use another way to receive data from the broker? As I remember it is better to use lua to receive data from the Quicksilver, but you have to increase the connection with the terminal...

I already wrote that I wrote everything by DDE - My program - trans2quik.dll

But this combination does not work fast enough (by eye you can see how quik lags behind MT5 in the stack).

I wanted to receive market-data via MT5 and send orders via trans2quik.dll,

But I forgot about the depo, it can only be obtained from the quick view.

I don't want to go further.

 

A "window" appeared in construction and I decided to continue exporting data from MT5 in real time.

I have implemented postMessageW export, it works fast enough, but sometimes data gets "stuck".

Expert Advisor code

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

Application code (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.

At first I thought it was a division error, to get DOUBLE, but MT5 multiplies number by 10 to the power of n,

and in the app the resulting number is divided by 10 to the power of n.

There shouldn't be an error.

Maybe I'm doing something wrong?

(compiled appendix attached)

Added by

Is it because of this?


Files:
Mess_test.zip  997 kb
 

Everything works



Advantages of

1 Export works very fast and does not load the terminal or the system

2. Minimal code.

3. No DLL needed.

Disadvantages

1. You can only transfer LONG, ULONG, DOUBLE (with number value limitation) and up to 127 bits of ANSI text (English only)

Added

Remains to send PostMessage with deposit to Quickie via LUA.

Has anyone tried PostMessage from Quick (LUA)?

This is needed for EBS accounts.

 
prostotrader:

Everything works.

Can you tell me more about how to use it, what to do?

 
Aleksey Vyazmikin:

Can you tell me more about how to use this and what to do?

All these "gadgets" are needed for trading via Quick on EBS accounts (or for real-time analysis of data outside MT5).

The data output to my application from slow KVIK via DDE is very slow,

so data is taken from MT5, and trading orders are sent to Kvik via their API (trans2quik.dll).

Mechanism is

MT5 --> Own Application <--> trans2quik.dll <--> Quick

Here is an example of trading in Quick futures vs stocks


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

All these "gadgets" are needed to trade via QuickBooks on EBS accounts (or for real-time analysis of data outside MT5).

The data output to your application from the slow Quik via DDE is very slow,

so data is taken from MT5, and trading orders are sent to Kvik via their API (trans2quik.dll).

Mechanism is

MT5 --> Own Application <--> trans2quik.dll <--> Quick

Here is an example of trading in Quick futures vs stocks


Isn't it easier to put the second MT5 terminal to the stock market and pass the information between two terminals via PIPE channel for this specific task?

I'm going to do stock market this year according to this scheme.

 
Dmi3:

Isn't it easier to put a second MT5 terminal on the stock market and transfer information between the two terminals via a PIPE channel for this specific task?

I'm going to do the stock market this year according to this scheme.

You are proposing an even bigger "mess", EBS account is good because the money is not divided into sections.

What you have seen in the video works, but very slowly!

Quick --> DDE --> My pad <--> trans2quik.dl <--> Quick

I replaced Quick --> DDE --> with MT5 --> PostMessage -->.

It became much faster.

That said, 2 lines of code and no load on the terminal and system.

Message sending

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

Message Receiving

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;
Reason: