MT5 e trans2quik.dll - pagina 13

 
BillionerClub:

E il codice C++ completo senza il LUA?

Così nel filmato sopra, senza LUA, solo non C++ ma Pascal (Delphi XE4)

 
prostotrader:

Così nel filmato sopra, senza il LUA, solo che non è C++ ma Pascal (Delphi XE4)

I freni non interferiscono?

Forum sul trading, sistemi di trading automatico e test di strategie di trading

MT5 e trans2quik.dll

prostotrader, 2019.02.15 18:42

Per quanto riguarda il trading via Quick, potete dimenticarlo come un brutto sogno.

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

I freni sono d'intralcio?


Il video è una versione modificata.

Ho ottimizzato un po' l'algoritmo.

Per sincronizzare il DDE e i collage della DLL, ho usato sezioni critiche.

L'inserimento dell'ordine di "risposta" è stato eseguito all'interno della sezione critica(la funzione di elaborazione dei datisi chiama

e l'invio di un ordineOnTrade()) e ora questa funzione è chiamata da PosMessage che ha ridotto notevolmente i ritardi.

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

Ma molto lontano in termini di velocità da MT5 :(

 
prostotrader:

Ma lontano da MT5 in termini di velocità :(

Ho ancora "fregato" il collegamento rapido a MT5, ma non riesco a vedere la differenza tra l'uscita dal collegamento rapido e l'uscita dal collegamento rapido via DDE.

Se qualcuno è interessato a sapere come si fa, sto incollando il codice.

Il consulente esperto

Cosa fa?

Raccoglie tutti i ciswalls attuali (fetches) che sono specificati nell'enumerazione (Variables.mqh)

e li aggiunge alla struttura dell'array.

Cerca uno SPOT corrispondente per questi simboli e li aggiunge anche al

struttura dell'array.

Le pile vengono aggiunte per tutti i futures trovati.

Quando uno stack viene attivato, prende gli aski e i bit dei futures e degli spot e li invia alla 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 invia semplicemente i dati secondo il collare impostato

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:

Ho ancora "avvitato" il quickdraw a MT5, ma non vedo alcun miglioramento rispetto all'uscita dal quickdraw via DDE.

Se qualcuno è interessato a sapere come si fa, vi incollo il codice.

Il consigliere esperto

Cosa fa?


Questo design permette di ricevere dati da Quickquote a MT5 e dare ordini per la gestione delle posizioni da MT5 a Quickquote?

Interessato a lavorare con opzioni solo...
 
Aleksey Vyazmikin:

Questo progetto permette di ricevere dati da Quickquick a MT5 e dare ordini di controllo delle posizioni da MT5 a Quickquick?

Interessato a lavorare con opzioni solo...

No, i dati sono presi da MT5 e trasferiti al tuo programma (terminale), che

Trans2quik.dll invia ordini a Kwik (MT5 non ha opzioni)

 
prostotrader:

No, i dati sono presi da MT5 e trasmessi al suo programma (terminale), che

invia ordini a Kwik tramite trans2quik.dll (MT5 non ha opzioni)

Peccato. Pensavo che fosse possibile controllare gli ordini del Kvik, che ha delle opzioni.

 
Aleksey Vyazmikin:

Peccato. Pensavo che fosse possibile controllare gli ordini di Quick, che hanno delle opzioni.

Conosci Delphi?

 
prostotrader:

Conosci Delphi?

Ahimè, no :(

 
Aleksey Vyazmikin:

Ahimè, no :(

Allora aspetta che io entri nelle opzioni...

In questo momento li scambio solo con le mani (in attesa di notizie)