MT5 and trans2quik.dll - page 13

 
BillionerClub:

What about full C++ code without the LUA?

So in the movie above, without LUA, only not C++ but Pascal (Delphi XE4)

 
prostotrader:

So in the movie above, without the LUA, only not C++ but Pascal (Delphi XE4)

Do the brakes not interfere?

Forum on trading, automated trading systems and trading strategy testing

MT5 and trans2quik.dll

prostotrader, 2019.02.15 18:42

About trading via Quick, you can just forget about it like a bad dream.

Ордер SRH9 отправлен: 15.02.19 20:30:12
Ордер SRH9 исполнился: 15.02.19 20:30:12 (62 мс)
Ордер SBER отправлен: 15.02.19 20:30:12
Ордер SBER исполнился: 15.02.19 20:30:13 (562 мс)

Ордер SRH9 отправлен: 15.02.19 20:30:13
Ордер SRH9 исполнился: 15.02.19 20:30:13 (250 мс)
Ордер SBER отправлен: 15.02.19 20:30:13
Ордер SBER исполнился: 15.02.19 20:30:14 (561 мс)

Ордер SRH9 отправлен: 15.02.19 20:30:14
Ордер SRH9 исполнился: 15.02.19 20:30:14 (125 мс)
Ордер SBER отправлен: 15.02.19 20:30:14
Ордер SBER исполнился: 15.02.19 20:30:15 (749 мс)

Ордер SRH9 отправлен: 15.02.19 20:30:16
Ордер SRH9 исполнился: 15.02.19 20:30:16 (124 мс)
Ордер SBER отправлен: 15.02.19 20:30:16
Ордер SBER исполнился: 15.02.19 20:30:17 (999 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:23
Ордер SRH9 исполнился: 15.02.19 20:31:23 (125 мс)
Ордер SBER отправлен: 15.02.19 20:31:23
Ордер SBER исполнился: 15.02.19 20:31:24 (1560 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:27
Ордер SRH9 исполнился: 15.02.19 20:31:27 (109 мс)
Ордер SBER отправлен: 15.02.19 20:31:27
Ордер SBER исполнился: 15.02.19 20:31:28 (1014 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:29
Ордер SRH9 исполнился: 15.02.19 20:31:29 (187 мс)
Ордер SBER отправлен: 15.02.19 20:31:29
Ордер SBER исполнился: 15.02.19 20:31:30 (1202 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:31
Ордер SRH9 исполнился: 15.02.19 20:31:31 (202 мс)
Ордер SBER отправлен: 15.02.19 20:31:31
Ордер SBER исполнился: 15.02.19 20:31:32 (796 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:32
Ордер SRH9 исполнился: 15.02.19 20:31:33 (109 мс)
Ордер SBER отправлен: 15.02.19 20:31:33
Ордер SBER исполнился: 15.02.19 20:31:34 (1435 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:36
Ордер SRH9 исполнился: 15.02.19 20:31:36 (203 мс)
Ордер SBER отправлен: 15.02.19 20:31:36
Ордер SBER исполнился: 15.02.19 20:31:37 (437 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:41
Ордер SRH9 исполнился: 15.02.19 20:31:41 (125 мс)
Ордер SBER отправлен: 15.02.19 20:31:41
Ордер SBER исполнился: 15.02.19 20:31:42 (873 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:42
Ордер SRH9 исполнился: 15.02.19 20:31:42 (109 мс)
Ордер SBER отправлен: 15.02.19 20:31:42
Ордер SBER исполнился: 15.02.19 20:31:43 (687 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:51
Ордер SRH9 исполнился: 15.02.19 20:31:51 (140 мс)
Ордер SBER отправлен: 15.02.19 20:31:51
Ордер SBER исполнился: 15.02.19 20:31:51 (312 мс)

Ордер SRH9 отправлен: 15.02.19 20:31:56
Ордер SRH9 исполнился: 15.02.19 20:31:56 (109 мс)
Ордер SBER отправлен: 15.02.19 20:31:56
Ордер SBER исполнился: 15.02.19 20:31:57 (1186 мс)

 
Sergey Chalyshev:

Are the brakes in the way?


The video is a tweaked version.

I've optimized the algorithm a bit.

To synchronize the DDE and the collabs from the DLL, I used critical sections.

The placing of "reply" order was performed inside of critical section( data processingfunction was called

and sending an orderOnTrade()) and now this function is called by PosMessage which has reduced delays greatly.

if(string(SecCode) = Child.Expert.ExpData.FutData.SecCode) then //future
              begin
                case nStatus of
                  1: {active};
                  2: begin
                       if(StartQty = nBalance) then                   //Canceled
                       begin
                         Child.Expert.FOrder:= 0;
                         Child.Expert.FTransID:= 0;
                         Child.Expert.FTransBusy:= false;
                       end else
                       begin
                         case nIsSell of
                           0: Child.Expert.FFutVol:= Child.Expert.FFutVol + (StartQty - nBalance);
                           else Child.Expert.FFutVol:= Child.Expert.FFutVol - (StartQty - nBalance);
                         end;
                           Child.Expert.FVolume:= StartQty - nBalance;
                           Child.Expert.FaSell:= nIsSell;
                           Child.Expert.FOrder:= 0;
                           PostMessage(Child.Expert.Handle, WM_ON_TRADE,
                                            NativeUint(Child.Expert.Handle), 0);
                        // Child.Expert.OnTrade(); //TODO DEBUG
                       end;
                     end;
                  else begin                                 //Future order Done
                    case nIsSell of
                      0: Child.Expert.FFutVol:= Child.Expert.FFutVol + (StartQty - nBalance);
                      else Child.Expert.FFutVol:= Child.Expert.FFutVol - (StartQty - nBalance);
                    end;
                      Child.Expert.FVolume:= StartQty - nBalance;
                      Child.Expert.FaSell:= nIsSell;
                      Child.Expert.FOrder:= 0;
                      PostMessage(Child.Expert.Handle, WM_ON_TRADE,
                                            NativeUint(Child.Expert.Handle), 0);
                   // Child.Expert.OnTrade(); //TODO DEBUG
                  end;
                end;
                break;
              end else
              if(string(SecCode) = Child.Expert.ExpData.SpotData.SecCode) then  //spot

But far away in terms of speed from MT5 :(

 
prostotrader:

But far from MT5 in terms of speed :(

I still "screwed" the quick link to MT5, but I can't see the difference between the output from the quick link and the output from the quick link via DDE.

If someone is interested in how it is done, I am pasting the code.

The Expert Advisor

What does it do?

Gathers all current ciswalls (fetches) that are specified in enumeration (Variables.mqh)

and adds them to the array structure.

Looks for a matching SPOT for these symbols and also adds them to the

array structure.

Stacks are added for all found futures.

When a stack is triggered, it takes the aski and bits of the futures and spot and sends them to the DLL (MT5Client.dll)

//+------------------------------------------------------------------+
//|                                                    Variables.mqh |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
//---
enum TIKERS
{
  AFLT, 
  ALRS,
  CHMF,
  FEES, 
  GAZR,
  GMKR,
  HYDR,
  LKOH,
  MAGN,
  MGNT,
  MOEX,
  MTSI,
  NLMK,
  NOTK,
  PLZL,
  ROSN,
  RTKM,
  SBPR,
  SBRF,
  SNGP,
  SNGR,
  TATN,
  TRNF,
  VTBR   
};
//
struct QFS_DATA
{
  string base_tiker;
  string tiker;
  double fut_sell_price;
  double fut_buy_price;
  double spot_sell_price;
  double spot_buy_price;
  bool book_add;
};
const TIKERS enum_tikers[] = {AFLT, 
  ALRS,
  CHMF,
  FEES, 
  GAZR,
  GMKR,
  HYDR,
  LKOH,
  MAGN,
  MGNT,
  MOEX,
  MTSI,
  NLMK,
  NOTK,
  PLZL,
  ROSN,
  RTKM,
  SBPR,
  SBRF,
  SNGP,
  SNGR,
  TATN,
  TRNF,
  VTBR};

QFS_DATA qfs_data[];


//+------------------------------------------------------------------+
//|                                                    Functions.mqh |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
//---
#include   "Variables.mqh"

//+------------------------------------------------------------------+
//| Check terminal  function                                         |
//+------------------------------------------------------------------+
bool CheckTerminal()
{
  return(true);
}
//+------------------------------------------------------------------+
//| Get Expiration  function                                         |
//+------------------------------------------------------------------+
ulong GetExpiration(const string a_symb)
{
  return(ulong(SymbolInfoInteger(a_symb, SYMBOL_EXPIRATION_TIME)));
}
//+------------------------------------------------------------------+
//| Get SPOT function                                                |
//+------------------------------------------------------------------+
string GetSpot(const string a_name)
{
  if(a_name == "GAZR") {return("GAZP");} else
  if(a_name == "SBRF") {return("SBER");} else
  if(a_name == "SBPR") {return("SBERP");} else
  if(a_name == "TRNF") {return("TRNFP");} else
  if(a_name == "NOTK") {return("NVTK");} else
  if(a_name == "MTSI") {return("MTSS");} else
  if(a_name == "GMKR") {return("GMKN");} else
  if(a_name == "SNGR") {return("SNGS");} else
  if(a_name == "SNGP") {return("SNGSP");} else
  return(a_name);

}
//+------------------------------------------------------------------+
//| Set Tickers  function                                            |
//+------------------------------------------------------------------+
bool SetTickers()
{
  int s_total = SymbolsTotal(false);
  if(s_total > 0)
  {
    int s_cnt = 0;
    ulong fut_exp;
    string fut_name = "";
    string t_name = "";
    string spot_name;
    ulong cur_time = ulong(TimeTradeServer());
    for(int i = 0; i < s_total;i++)
    {
      fut_name = SymbolName(i, false);
      for(int j = 0; j < ArraySize(enum_tikers);j++)
      {
        t_name = EnumToString(enum_tikers[j]);
        if(t_name != "")
        {
          fut_exp = GetExpiration(fut_name);
          if(fut_exp > ulong(cur_time))
          {
            if(StringFind(fut_name, t_name) > -1)
            {
              spot_name = GetSpot(t_name);
              if(spot_name != "")
              {
                s_cnt++;
                ArrayResize(qfs_data, s_cnt);
                qfs_data[s_cnt - 1].tiker = fut_name;
                qfs_data[s_cnt - 1].base_tiker = spot_name;
                if(SymbolSelect(fut_name, true) != true) return(false);
                if(SymbolSelect(spot_name, true) != true) return(false);
                break;
              }  
            }
          }
        }
      }
    }
    if(s_cnt > 0) return(true);
  }
  return(false);
}


//+------------------------------------------------------------------+
//|                                                     Quik_out.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
#include   "Quik\Functions.mqh"
//
int a_size = 0;
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
#import "MT5Client.dll"
  void SendData(QFS_DATA &a_data);
#import
//---
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  if(CheckTerminal() == false) return(INIT_FAILED);
  if(SetTickers() == true)
  {
    a_size = ArraySize(qfs_data);
    if(a_size > 0)
    {
      for(int i = 0; i < a_size;i++)
      {
        qfs_data[i].book_add = MarketBookAdd(qfs_data[i].tiker);
      }
    }  
  }
  else return(INIT_FAILED);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(a_size > 0)
  {
    for(int i = 0; i < a_size;i++)
    {
      if(qfs_data[i].book_add == true) MarketBookRelease(qfs_data[i].tiker);
    }
  }
}

//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  for(int i = 0; i< a_size;i++)
  {
    if(symbol == qfs_data[i].tiker)
    {
      qfs_data[i].fut_sell_price = SymbolInfoDouble(qfs_data[i].tiker, SYMBOL_ASK);
      qfs_data[i].fut_buy_price = SymbolInfoDouble(qfs_data[i].tiker, SYMBOL_BID);
      qfs_data[i].spot_sell_price = SymbolInfoDouble(qfs_data[i].base_tiker, SYMBOL_ASK);
      qfs_data[i].spot_buy_price = SymbolInfoDouble(qfs_data[i].base_tiker, SYMBOL_BID);
      SendData(qfs_data[i]);
      break;
    }
  }   
}
//+------------------------------------------------------------------+

MT5Client.dll simply sends data according to the set collar

unit MT5Types;

interface

type
  PData = ^TData;
  TData = packed record
    base_tiker: string;
    tiker: string;
    fut_sell_price: double;
    fut_buy_price: double;
    spot_sell_price: double;
    spot_buy_price: double;
    book_add: boolean;
  end;

  TCallBack = function(Data: PData): boolean;
var
  OutData: TCallBack;

implementation


end.


library MT5Client;

uses
  System.Sharemem,
  WinApi.Windows,
  MT5Types in 'MT5Types.pas';

//--- Exports ---
procedure SetCallBack(CallBack: TCallBack); stdcall;
begin
  OutData:= CallBack;
end;

procedure SendData(aData: PData); stdcall;
begin
  if(Assigned(OutData)) then OutData(aData);
end;

{$R *.res}

exports
  SetCallBack,
  SendData;

begin
  //
end.
 
prostotrader:

But I still "bolted" the quickdraw to MT5, but I can't see any improvement compared to the output from the quickdraw via DDE.

If anyone is interested in how it is done, I am pasting the code.

The Expert Advisor

What it does?


This design allows you to receive data from Quickquote to MT5 and give orders for position management from MT5 to Quickquote?

Interested in working with options just...
 
Aleksey Vyazmikin:

Does this design allow you to receive data from Quickquick to MT5 and give position control orders from MT5 to Quickquick?

Interested in working with options just...

No, data is taken from MT5 and transferred to your program (terminal), which

Trans2quik.dll sends orders to Kwik (MT5 has no options)

 
prostotrader:

No, the data is taken from MT5 and transmitted to its program (terminal), which

sends orders to Kwik via trans2quik.dll (MT5 has no options)

Pity. I thought it was possible to control the orders of the Kvik, which has options in it.

 
Aleksey Vyazmikin:

Pity. I thought it was possible to control Quick's orders, which have options in them.

Do you know Delphi?

 
prostotrader:

Do you know Delphi?

Alas, no :(

 
Aleksey Vyazmikin:

Alas, no :(

Then wait for me to get into options...

Right now I trade them with my hands only (waiting for news)