MT5とtrans2quik.dll。 - ページ 15

 
Konstantin Nikitin:

まあ、オプションでQUIKから必要な情報をファイルで送ることもできるんですけどね。

はいtsu とっくに全部クイックに書きましたが、速効性はないです。

もっと速くしたかったんですが...。

 
prostotrader:

たしかにtsuは昔からクイックに書かれていますが、速効性はないですね。

もっと速くしたかったんですが...。

Quicksilverに別のスクリプトを放り込んで、必要な情報を継続的にファイルに送り込ませればいいんです。そして、書かれていることは、自分に合っていればそのまま通用させればいいのです。

 
prostotrader:

まだ説明することはありません、保留中の注文に 問題があります、MT5にはコールバックがありません。

保留を武器にしたい。

地元の常連さんにご挨拶。プログラミングテンプレート(http://cpp-reference.ru/patterns/behavioral-patterns/observer/) をお試しください。
また、いくつかの市場のつながりに興味があるので、そちらのつながりについてもお聞きしたいです。例を見る限り、全ての情報はMT5から取得し、クイックビューはTrans2Quick dll経由の注文を開くときのみ使用する、という理解でよろしいでしょうか?

それとも、ブローカーからデータを受け取るために別の方法を使おうとするのでしょうか?確かQuicksilverからデータを取得するにはluaを使った方が良いのですが、ターミナルとの接続を増やさなければならないので...。

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

地元の常連さんからのご挨拶。プログラミング・テンプレート(http://cpp-reference.ru/patterns/behavioral-patterns/observer/) を使ってみてもいいかもしれません。
また、複数の市場をリンクさせるという問題にも興味がありますので、リンクについてお伺いしたいと思います。例を見る限り、全ての情報はMT5から取得し、クイックビューはTrans2Quick dll経由の注文を開くときのみ使用する、という理解でよろしいでしょうか。

それとも、ブローカーからデータを受け取るために別の方法を使おうとするのでしょうか?確かQuicksilverからのデータ受信はluaを使った方が良いのですが、ターミナルとの接続を増やさなければならないので...。

DDEで全て書き込んだことは既に書きました - 私のプログラム - trans2quik.dll

しかし、この組み合わせでは十分に速く動作しません(目で見て、quikがスタックでMT5より遅れていることがわかります)。

MT5でマーケットデータを受信し、trans2quik.dllで注文を出したいのですが、どうすればいいですか?

でも、デポのことは忘れていました、クイックビューからしか取得できないんです。

それ以上は望まない。

 

工事中の「窓」が現れ、MT5からリアルタイムでデータをエクスポートし続けることにしました。

postMessageWのエクスポートを実装したところ、十分に高速に動作するのですが、時々データが "stuck "することがあります。

Expert Advisor コード

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

アプリケーションコード (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.

最初はDOUBLEを得るための除算ミスかと思いましたが、MT5では10のn乗で計算されます。

で、アプリ内では結果の数値が10のn乗で割られる。

エラーは出ないはずです。

もしかして、私のやり方が悪いのか?

(編集後添付資料)

によって追加されました。

そのせいでしょうか?


ファイル:
Mess_test.zip  997 kb
 

すべてがうまくいく



のメリット

1 エクスポートは非常に高速 に動作し、端末やシステムに負荷をかける ことはない

2.最小限のコード

3.DLLは必要ありません。

デメリット

1.転送できるのはLONG、ULONG、DOUBLE(数値制限あり)、最大127ビットのANSIテキスト(英語のみ)のみです

追加

LUAでQuickieに入金したPostMessageを送信するために残っています。

クイック(LUA)からのPostMessageを試された方はいらっしゃいますか?

EBSアカウントに必要です。

 
prostotrader:

すべてがうまくいく。

使い方や注意点など、詳しく教えてください。

 
Aleksey Vyazmikin:

使い方や注意点など、詳しく教えてください。

これらの「ガジェット」はすべて、EBS口座のQuick経由の取引(またはMT5以外のデータのリアルタイム分析)に必要なものです。

DDE経由で遅いKVIKから私のアプリケーションに出力されるデータが非常に遅い

ので、データはMT5から取得し、取引注文は 同社のAPI(trans2quik.dll)を介してKvikに送信されます。

仕組みは

MT5 --> 自作アプリ <--> trans2quik.dll <--> Quick

以下は、Quick先物と株式の取引例です。


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

これらの「ガジェット」はすべて、EBSアカウントでQuickBooksを介して取引するために(あるいはMT5以外のデータのリアルタイム分析に)必要なものである。

遅いQuikからDDE経由でアプリケーションに出力されるデータは非常に遅い。

ので、データはMT5から取得し、取引注文は 同社のAPI(trans2quik.dll)を介してKvikに送信されます。

仕組みは

MT5 --> 自作アプリ <--> trans2quik.dll <--> Quick

以下は、Kvikで先物取引と株式取引を行う場合の例です。


この特定のタスクのために2番目のMT5端末を株式市場に置き、PIPEチャネルを介して2つの端末間で情報を転送することは容易ではありませんか?

今年はこのスキームで株をやろうと思っています。

 
Dmi3:

この特定のタスクのために、株式市場に2番目のMT5端末を置き、PIPEチャネルを介して2つの端末間で情報を転送することは簡単ではありませんか?

このスキームにしたがって、今年は株をやろうと思っています。

さらに大きな「混乱」を提案していますね。EBSアカウントは、お金が分割されないからいいんです。

ビデオでご覧になったものは動作しますが、非常にゆっくりとした 動きです。

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

Quick --> DDE --> MT5 --> PostMessage --> に置き換えてみました。

より高速になりました。

とはいえ、2行のコードで、端末やシステムには負荷がかからない。

メッセージ送信

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

メッセージの受信

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;
理由: