MT5 et trans2quik.dll - page 13

 
BillionerClub:

Qu'en est-il du code C++ complet sans LUA ?

Donc dans le film ci-dessus, sans LUA, seulement pas C++ mais Pascal (Delphi XE4)

 
prostotrader:

Donc dans le film ci-dessus, sans le LUA, seulement pas C++ mais Pascal (Delphi XE4)

Les freins n'interfèrent-ils pas ?

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

MT5 et trans2quik.dll

prostotrader, 2019.02.15 18:42

En ce qui concerne le commerce via Quick, vous pouvez l'oublier comme un mauvais rêve.

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

Les freins gênent-ils ?


La vidéo est une version modifiée.

J'ai optimisé l'algorithme un peu.

Pour synchroniser la DDE et les collabs de la DLL, j'ai utilisé des sections critiques.

Le placement de l'ordre "réponse" a été effectué à l'intérieur de la section critique(la fonction de traitement des donnéesest appelée

et l'envoi d'un ordreOnTrade()) et maintenant cette fonction est appelée par PosMessage ce qui a considérablement réduit les délais.

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

Mais très loin en termes de vitesse de MT5 :(

 
prostotrader:

Mais loin de MT5 en termes de vitesse :(

J'ai toujours "vissé" le lien rapide à MT5, mais je ne vois pas la différence entre la sortie du lien rapide et la sortie du lien rapide via DDE.

Si quelqu'un est intéressé par la façon dont cela est fait, je colle le code.

Le conseiller expert

Que fait-il ?

Rassemble tous les ciswalls (fetches) actuels qui sont spécifiés dans l'énumération (Variables.mqh)

et les ajoute à la structure du tableau.

Il recherche un SPOT correspondant à ces symboles et les ajoute également à la liste des symboles.

structure du tableau.

Les piles sont ajoutées pour tous les futures trouvés.

Lorsqu'une pile est déclenchée, elle prend les aski et les bits des futures et des spots et les envoie à 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 envoie simplement les données en fonction du collier défini.

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:

J'ai quand même "boulonné" la tireuse rapide à MT5, mais je ne vois pas d'amélioration par rapport à la sortie de la tireuse rapide via DDE.

Si quelqu'un est intéressé par la façon dont cela se fait, je colle le code.

Le conseiller expert

Ce qu'il fait ?


Cette conception vous permet de recevoir des données de Quickquote vers MT5 et de donner des ordres pour la gestion des positions de MT5 vers Quickquote ?

Intéressé à travailler avec des options juste...
 
Aleksey Vyazmikin:

Cette conception vous permet-elle de recevoir des données de Quickquick vers MT5 et de donner des ordres de contrôle de position de MT5 vers Quickquick ?

Intéressé à travailler avec des options juste...

Non, les données sont extraites de MT5 et envoyées à votre programme (terminal), qui...

Trans2quik.dll envoie les ordres à Kwik (MT5 n'a pas d'options)

 
prostotrader:

Non, les données sont extraites du MT5 et transmises à son programme (terminal), lequel

envoie les ordres à Kwik via trans2quik.dll (MT5 n'a pas d'options)

C'est dommage. Je pensais qu'il était possible de contrôler les ordres de la Kvik qui contient des options.

 
Aleksey Vyazmikin:

C'est dommage. Je pensais qu'il était possible de contrôler les ordres de Quick, qui comportent des options.

Connaissez-vous Delphi ?

 
prostotrader:

Connaissez-vous Delphi ?

Hélas, non :(

 
Aleksey Vyazmikin:

Hélas, non :(

Alors attendez que j'entre dans les options...

Pour l'instant, je les échange avec mes mains seulement (en attendant des nouvelles).

Raison: