MT5 et trans2quik.dll - page 15

 
Konstantin Nikitin:

Eh bien, vous pouvez envoyer les informations nécessaires de QUIK par le biais d'un fichier, en option.

Oui tsu a été écrit depuis longtemps pour le quickie, mais il ne fonctionne pas rapidement,

Je voulais le rendre plus rapide...

 
prostotrader:

Oui tsu a été écrit depuis longtemps pour le quickie, mais il ne fonctionne pas rapidement,

Je voulais que ce soit plus rapide...

Il suffit d'insérer un autre script dans le Quicksilver et de le laisser introduire en continu les informations dont vous avez besoin dans le fichier. Et ce qui est écrit, laissez-le fonctionner comme il est, si cela vous convient.

 
prostotrader:

Il n'y a rien à expliquer pour l'instant, il y a un problème avec les ordres en attente, il n'y a pas de callbacks dans MT5.

Je veux avoir des ordres en attente dans mon arsenal.

Salutations aux habitués locaux. Vous pouvez essayer les modèles de programmation(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Je m'intéresse également à la connexion de plusieurs marchés, je souhaite vous interroger sur votre connexion. D'après ce que j'ai compris de l'exemple, toutes les informations sont obtenues à partir de MT5 et la vue rapide n'est utilisée que pour ouvrir des ordres via la dll Trans2Quick, n'est-ce pas ?

Ou allez-vous essayer d'utiliser un autre moyen de recevoir les données du courtier ? Si je me souviens bien, il est préférable d'utiliser lua pour obtenir des données du Quicksilver, mais il faut augmenter la connexion avec le terminal...

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

Salutations des habitués locaux. Vous pouvez essayer d'utiliser des modèles de programmation(http://cpp-reference.ru/patterns/behavioral-patterns/observer/).
Je suis également intéressé par la question de la mise en relation de plusieurs marchés, j'aimerais vous interroger sur votre mise en relation. D'après ce que j'ai compris de l'exemple, toutes les informations sont obtenues à partir de MT5 et la vue rapide n'est utilisée que pour ouvrir des ordres via la dll Trans2Quick, n'est-ce pas ?

Ou allez-vous essayer d'utiliser un autre moyen pour recevoir les données du courtier ? Si je me souviens bien, il est préférable d'utiliser lua pour recevoir les données du Quicksilver, mais il faut augmenter la connexion avec le terminal...

J'ai déjà écrit que j'ai tout écrit par DDE - Mon programme - trans2quik.dll

Mais cette combinaison ne fonctionne pas assez rapidement (à l'œil, vous pouvez voir à quel point quik est en retard sur MT5 dans la pile).

Je voulais recevoir les données du marché via MT5 et envoyer des ordres via trans2quik.dll,

Mais j'ai oublié le dépo, il ne peut être obtenu qu'à partir de la vue rapide.

Je ne veux pas aller plus loin.

 

Une "fenêtre" est apparue en construction et j'ai décidé de continuer à exporter les données de MT5 en temps réel.

J'ai implémenté l'exportation postMessageW, cela fonctionne assez rapidement, mais parfois les données restent "bloquées".

Code du conseiller expert

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

Code d'application (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.

J'ai d'abord pensé qu'il s'agissait d'une erreur de division, pour obtenir DOUBLE, mais MT5 multiplie le nombre par 10 à la puissance de n,

et dans l'application, le nombre résultant est divisé par 10 à la puissance n.

Il ne devrait pas y avoir d'erreur.

Peut-être que je fais quelque chose de mal ?

(annexe compilée jointe)

Ajouté par

C'est à cause de ça ?


Dossiers :
Mess_test.zip  997 kb
 

Tout fonctionne



Avantages de

1 L'exportation fonctionne très rapidement et ne charge ni le terminal ni le système.

2. Code minimal.

3. pas de DLL nécessaire.

Inconvénients

1. Vous ne pouvez transférer que des fichiers LONG, ULONG, DOUBLE (avec une limitation de la valeur numérique) et jusqu'à 127 bits de texte ANSI (anglais uniquement).

Ajouté

Reste à envoyer le PostMessage avec le dépôt à Quickie via LUA.

Quelqu'un a-t-il essayé PostMessage à partir de Quick (LUA) ?

Ceci est nécessaire pour les comptes EBS.

 
prostotrader:

Tout fonctionne.

Pouvez-vous m'en dire plus sur la façon de l'utiliser, ce qu'il faut faire ?

 
Aleksey Vyazmikin:

Pouvez-vous m'en dire plus sur la façon de l'utiliser et sur ce qu'il faut faire ?

Tous ces "gadgets" sont nécessaires pour le trading via Quick sur les comptes EBS (ou pour l'analyse en temps réel des données en dehors de MT5).

La sortie des données vers mon application à partir de KVIK lent via DDE est très lente,

Ainsi, les données proviennent de MT5, et les ordres de trading sont envoyés à Kvik via leur API (trans2quik.dll).

Le mécanisme est

MT5 --> Application personnelle <--> trans2quik.dll <--> rapide

Voici un exemple de négociation de contrats à terme Quick par rapport aux actions.


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

Tous ces "gadgets" sont nécessaires pour effectuer des transactions via QuickBooks sur des comptes EBS (ou pour l'analyse en temps réel des données en dehors de MT5).

La sortie des données vers votre application à partir de la Quik lente via DDE est très lente,

Ainsi, les données proviennent de MT5, et les ordres de trading sont envoyés à Kvik via leur API (trans2quik.dll).

Le mécanisme est

MT5 --> Application personnelle <--> trans2quik.dll <--> rapide

Voici un exemple de négociation de contrats à terme Quick par rapport aux actions.


N'est-il pas plus simple de mettre le second terminal MT5 sur le marché boursier et de faire passer l'information entre les deux terminaux par le canal PIPE pour cette tâche spécifique ?

Je vais faire de la bourse cette année selon ce plan.

 
Dmi3:

N'est-il pas plus simple de mettre un deuxième terminal MT5 sur le marché boursier et de transférer les informations entre les deux terminaux via le canal PIPE pour cette tâche spécifique ?

Je vais faire de la bourse cette année selon ce schéma.

Vous proposez un "gâchis" encore plus grand, le compte EBS est bon car l'argent n'est pas divisé en sections.

Ce que vous avez vu dans la vidéo fonctionne, mais très lentement!

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

J'ai remplacé Quick --> DDE --> par MT5 --> PostMessage -->.

Il est devenu beaucoup plus rapide.

Cela dit, 2 lignes de code et aucune charge sur le terminal et le système.

Envoi de messages

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

Réception des messages

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;