記事"トレーダーのハック: 定義と ForEach のブレンド (#define)"についてのディスカッション - ページ 6

 

どのように記事を想像しますか?私はKBからソースコードを取り出し、なぜこの場所にマクロを適用することにしたのか、なぜこのような形になったのかを記事に書き始める。

KBの各作品にはディスカッションスレッドがある。そこでソースに関する質問をすることができます。

 
fxsaber:

どのような記事を想像しますか?KBからソースコードを取り出し、なぜこの場所にマクロを適用することにしたのか、なぜこうなのかを記事に書き始める。

KBの各作品にはディスカッションスレッドがあります。そこでソースに関する質問をすることができる。

例えば、ここではホローを全く打ち落とさない)。

#define  MT4_ORDERFUNCTION(NAME,T,A,B,C)                               \
  static T MT4Order##NAME( void )                                     \
  {                                                                   \
    return(POSITION_ORDER((T)(A), (T)(B), MT4ORDERS::Order.NAME, C)); \
  }

こういったことを説明するのも悪くないでしょう!

 
Vitaly Muzichenko:

例えば、ここで私は全く空洞化しない)

こういったことを記述するのはいいことだろう!

これは5つの入力パラメータを持つ複数行のマクロです。どのパラメータで呼び出されるのか、テキストを見てください。

MT4OrderTicket、MT4OrderClosePriceなどという名前の対応するメソッドが作成されます。メソッドは95%テキストが同じで、その数も多い。膨大なコピペをすることで、簡単にエラーが発生しないように、マクロを作成しました。すべてがコンパクトで、すぐにわかる。

さらに、このコードは機能が95%同じであることを強調している。つまり、読めばすぐに気づく。しかし、もしあなたが古典的に書くとしたら、20のメソッド(非常に多くのメソッドがある)のコードを読んで分析することでしか、そのような結論を下すことはできないだろう。そしてこれは大きな頭痛の種だ。そこで、20のメソッドすべてが1つの画面に表示され、メソッドがほぼ一致していることが強調されている。そして、マクロの入力パラメーターだけが違いを教えてくれる。読むときは、この違いに注意を払うのであって、飾りには注意を払わない。つまり、コードは一度に主要なもの、つまりコアを示し、ありふれたシェルを示さない。

 
Vasiliy Sokolov:

彼がやっていることは既成概念にとらわれないもので、それは一般大衆と共有されるべき貴重な知識だ!

まあ、彼はそれを共有している。彼の投稿やKBのコードの説明のいくつかは、ここの記事の半分よりも有益だ。

また、すべての質問に対する彼の生の回答があるのなら、なぜ人為的な参考書があるのか理解できない。

Renatが厳しい発言のたびに彼をBANする癖を直せばもっと良くなるだろう。

 

開発者は、エディターの「コンパイル」ボタンに「ファイルのコピーを作成し、コンパイルせずにマクロを置き換えてファイルを開く」コマンドを追加してくれないでしょうか。特にfxsaberからマクロを勉強するために。

または、コンテキストメニューのコマンドを使うこともできます。マクロ呼び出しの上にマウスを置いてコマンドを選択すると、マクロ置換後に得られたコードがバッファにコピーされます。

 

一般的に、マクロは次のように理解できる:

1.マクロ名とその値を分離する必要がある。行の最初に#define、その後にスペース、その後にマクロ名(パラメータ付きも可)、さらにスペース、または改行 し、マクロの値を記述する。

2.マクロがコードの中でどのように呼び出されるのか、パラメータは何なのかを確認する。マクロの値をコピーし、コードのどこかで呼び出されるパラメータに置き換える。

3.マクロがコード内で呼び出されている箇所を、ステップ2で得たものに置き換える。

だいたいこんな感じ。

知っておかなければならないことがあります:\ は行のつながりです。
 
私が最も頻繁に使用するマクロ

取引、自動取引システム、取引戦略のテストに関するフォーラム

mql5言語の特徴、仕事の機微とテクニック

fxsaber, 2017.12.05 11:39 pm.

デバッグモードでは、関数や式が返す値を知ることはできません。

例えば

void OnStart()
{
  double Angle = 1;
  double d = MathSin(Angle / 2) * MathSin(Angle * 2);
}

例えばハイライトした関数が何を返したか


私は(デバッグモードに限らず)このように使っています。

template <typename T>
T MyPrint( const T Value, const string Str )
{
  static const bool IsDebug = MQLInfoInteger(MQL_DEBUG);

// if (IsDebug)
  {
// DebugBreak(); // デバッグ手段で確認したい場合

    Print(Str + " = " + (string)Value);
  }
  
  return(Value);
}

#define _P(A) MyPrint(A, __FUNCSIG__ ", Line = " + (string)__LINE__ + ": " + #A)

void OnStart()
{
  double Angle = 1;
  double d = _P(MathSin(Angle / 2)) * _P(MathSin(Angle * 2));
}


結果

void OnStart(), Line = 21: MathSin(Angle/2) = 0.479425538604203
void OnStart(), Line = 21: MathSin(Angle*2) = 0.9092974268256817

mqhとフォーマットしています。

クロスプラットフォームのスクリプトの例

#include <MT4Orders.mqh>

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  // 買いポジションをオープン、クローズする。
  if (OrderSelect(OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0), SELECT_BY_TICKET))
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
}


このコードでOrderClosePrice()が何を返すかを知りたいとしよう。次のようにしてみましょう。

OrderClose(OrderTicket(), OrderLots(), _P(OrderClosePrice()), 100);


そして、もしあなたがほとんどすべてを知りたければ、ここにコードがあります(自分や他人のコードのどこに問題があるのかまったく理解できないときに起こります)。

#include <MT4Orders.mqh>

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#include <Debug.mqh> //https://c.mql5.com/3/173/Debug.mqh

void OnStart()
{
  // 買いポジションをオープン、クローズする。
  if (_P(OrderSelect(_P(OrderSend(_P(_Symbol), _P(OP_BUY), 1, _P(Ask), 100, 0, 0)), _P(SELECT_BY_TICKET))))
    _P(OrderClose(_P(OrderTicket()), _P(OrderLots()), _P(OrderClosePrice()), 100));
}

つまり、あなたが見たい値を_P()に入れる。その結果

void OnStart(), Line = 10: SELECT_BY_TICKET = 1
void OnStart(), Line = 10: Ask = 1.16688
void OnStart(), Line = 10: OP_BUY = 0
void OnStart(), Line = 10: _Symbol = EURUSD
void OnStart(), Line = 10: OrderSend(_P(_Symbol),_P(OP_BUY),1,_P(Ask),100,0,0) = 293785198
void OnStart(), Line = 10: OrderSelect(_P(OrderSend(_P(_Symbol),_P(OP_BUY),1,_P(Ask),100,0,0)),_P(SELECT_BY_TICKET)) = true
void OnStart(), Line = 11: OrderClosePrice() = 1.16678
void OnStart(), Line = 11: OrderLots() = 1.0
void OnStart(), Line = 11: OrderTicket() = 293785198
void OnStart(), Line = 11: OrderClose(_P(OrderTicket()),_P(OrderLots()),_P(OrderClosePrice()),100) = true


例えば、次のような式がある。

void OnStart()
{
  int a = 137;
  double b = 1.37;
  
  int Num = ((a = (int)(a / b)) << 1) * a; // 19602
}

なぜ19602が出力されるのかを素早く突き止める必要がある。素早く見つけたい部分をマクロに入れる

int Num = _P(_P(((a = _P((int)(_P(a / b)))) << 1)) * _P(a));


そして、ステップ・バイ・ステップで計算結果を見ることができる

void OnStart(), Line = 8: a/b = 99.99999999999999
void OnStart(), Line = 8: (int)(_P(a/b)) = 99
void OnStart(), Line = 8: ((a=_P((int)(_P(a/b))))<<1) = 198
void OnStart(), Line = 8: a = 99
void OnStart(), Line = 8: _P(((a=_P((int)(_P(a/b))))<<1))*_P(a) = 19602


ZY 記事の代わりに...

 
#define  ForEachSymbol(s,i)  string s=SymbolName(0,true); int os_total=SymbolsTotal(true); for(int i=1;i<os_total;i++,s=SymbolName(i,true))

バグがあります。最初のシンボル処理はposition_index 0で、次のシンボル処理はposition_index 2です。position_index 1が欠落しているため、ループはos_total-1回しか実行されない。

#define  ForEachOrder(ticket,i)    HistorySelect(0,TimeCurrent());  ulong ticket=OrderGetTicket(0); int or_total=OrdersTotal();   for(int i=1;i<or_total;i++,ticket=OrderGetTicket(i))
//+------------------------------------------------------------------+
//| スクリプト・プログラム開始機能|
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   ForEachOrder(orderticket,index)
     {
      Print(index,": #",orderticket," ",OrderGetString(ORDER_SYMBOL)," ",
            EnumToString((ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE)));
     }
/* サンプル出力
 1: 13965457 CADJPY ORDER_TYPE_SELL_LIMIT
 2: 14246567 AUDNZD ORDER_TYPE_SELL_LIMIT
*/ 
  }

これには以前と同じバグがあります。

さらに、未決済注文と履歴選択を処理する関数が混在しています。もし、未決済の注文を扱うつもりなら、HistorySelect()を使う必要はありません。


ところで、これらのバグはマクロを使わない場合の問題をよく示しています。デバッグは困難か不可能です。

The most strongest criticism of using #define is the fact that macro substitutions do not allow for code debugging. I agree with this, although, as fxsaber says, "A reliably fixed patient requires no anesthesia debugged macro requires no debugging".

これで読むのをやめました。

 
mql4のために2つの定義、OrderCalcProfit()とOrderCalcMargin()を追加することを検討されたかもしれません。
 
daengrani #:
mql4用の2つの定義、OrderCalcProfit()とOrderCalcMargin()を追加することを検討されましたか?
古いターミナルは長い間サポートされていません。