MT5 y trans2quik.dll - página 13

 
BillionerClub:

¿Qué pasa con el código C++ completo sin el LUA?

Así que en la película de arriba, sin LUA, sólo que no C++ sino Pascal (Delphi XE4)

 
prostotrader:

Así que en la película de arriba, sin el LUA, sólo que no C++ sino Pascal (Delphi XE4)

¿No interfieren los frenos?

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

MT5 y trans2quik.dll

prostotrader, 2019.02.15 18:42

Sobre el comercio a través de Quick, puedes olvidarte de él como de un mal sueño.

Ордер 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:

¿Los frenos estorban?


El vídeo es una versión modificada.

He optimizado un poco el algoritmo.

Para sincronizar el DDE y los collabs de la DLL, he utilizado secciones críticas.

La colocación de la orden de "respuesta" se realizó dentro de la sección crítica(se llamó a la función de procesamiento de datos

y el envío de una ordenOnTrade()) y ahora esta función es llamada por PosMessage, lo que ha reducido mucho los retrasos.

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

Pero muy lejos en términos de velocidad de MT5 :(

 
prostotrader:

Pero muy lejos de MT5 en términos de velocidad :(

Sigo "atornillando" el quicklink a MT5, pero no veo la diferencia entre la salida del quicklink y la salida del quicklink vía DDE.

Si alguien está interesado en cómo se hace, pego el código.

El asesor experto

¿Qué hace?

Recoge todos los ciswalls actuales (fetches) que se especifican en la enumeración (Variables.mqh)

y los añade a la estructura del array.

Busca un SPOT que coincida con estos símbolos y también los añade al

estructura de matriz.

Se añaden pilas para todos los futuros encontrados.

Cuando se dispara una pila, toma el aski y los bits de los futuros y del spot y los envía a la 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 simplemente envía los datos al collarín del conjunto

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:

Pero aún así "atornillé" el quickdraw a MT5, pero no puedo ver ninguna mejora en comparación con la salida del quickdraw a través de DDE.

Si alguien está interesado en cómo se hace, pego el código.

El asesor experto

¿Qué hace?


Este diseño permite recibir datos de Quickquote a MT5 y dar órdenes para la gestión de posiciones desde MT5 a Quickquote?

Interesado en trabajar con opciones sólo...
 
Aleksey Vyazmikin:

¿Este diseño permite recibir datos de Quickquick a MT5 y dar órdenes de control de posición de MT5 a Quickquick?

Interesado en trabajar con opciones sólo...

No, los datos se toman de MT5 y se transfieren a su programa (terminal), que

Trans2quik.dll envía órdenes a Kwik (MT5 no tiene opciones)

 
prostotrader:

No, los datos se toman de MT5 y se transmiten a su programa (terminal), que

envía órdenes a Kwik a través de trans2quik.dll (MT5 no tiene opciones)

Lástima. Pensé que era posible controlar las órdenes del Kvik que tiene opciones en él.

 
Aleksey Vyazmikin:

Lástima. Pensé que era posible controlar las órdenes de Quick, que tienen opciones.

¿Conoces Delphi?

 
prostotrader:

¿Conoces Delphi?

Por desgracia, no :(

 
Aleksey Vyazmikin:

Por desgracia, no :(

Entonces espera a que entre en las opciones...

Ahora mismo las comercio sólo con las manos (a la espera de noticias)