記事"MQL5オブジェクト指向のプログラミングアプローチを使ったExpert Advisorのプログラミング"についてのディスカッション - ページ 2

削除済み  
Yedelkin:
オープニングのビッドが1.2695の場合、すでに5ピプスの損失が自動的に発生します。同時に、開発者の考えに従ってSLが50ピップスだとすると、それがトリガーされる前に、さらに45ピップスが不利な方向に通過しなければなりません。つまり、ストップロスがトリガーされるとき、ビッドは1.2645ではなく1.2650に、アスクはそれぞれ1.2655にあるはずです。

1.オープニングでの5ピプスの損失について。

損失についてはおっしゃるとおり で、同じ瞬間にポジションをクローズすれば(条件付きで)、スプレッド分、まさに5pipsの損失が発生します。

ロングはビッド(カウンター)価格で決済されるからです。

少なくともこの場合、論理的にはこの損失を得るはずです(そしてそれは正しい)。

これはカウンター注文で決済する場合にも当てはまります。カウンター注文が1.2695(現在Bidがある価格)でトリガーされた場合、どのような結果になると思いますか?

まさか、ショートポジションの始値がAskであるとは言わないでしょうね?

2.BUクローズについて説明します。

私たちは1.27で買いポジションを建てたことを覚えています(この価格は現在、私たちにとってBUレベルです)。

BUクローズは、Bid価格が1.27に達した場合(つまり、ちょうど5ピップス上昇した場合)に発生すると考えるのが妥当です。

カウンター注文を使ってCUでクローズすることで、私たちのステートメントを確認してみましょう。このようなポジションの始値は1.27であるべきで、ご存知のように売り注文はビッドで発注されます。現在、ビッドは1.2695である。したがって、BUでクローズするには5ピップスを通過する必要があり、計算に間違いはなく、このステートメントは正しい。

3. SLとTPについて

ここでは2つのステートメントがルールです:

а.ロングはアスクでオープンし、ビッドでクローズする。ショートはビッドでオープンし、アスクでクローズする。

б.TPとSLまでの距離はオープンプライスから計算され、計算にはポジションの方向性が 考慮されます。


2番目のステートメントに従って、この例でSLとTPの価格を決定します。始値1.27の場合、SL = 1.2650、TP = 1.28とします(上記の条件による)。

最初のステートメントによると、Askが1.27に等しい(Bidが1.2695に等しい、5pipsのスプレッドに基づく)という条件でLONG(例ではLONG)がオープンします。

4.次に、SLとTPがどのような条件でトリガーされるかを決定します。

いずれかの条件が満たされると、ポジションは決済されます(他の要因がない場合):

TPの場合 - Bidが1.28(1.27から100ピプス)に達した場合、この時点のAskは1.2805になります(最初のステートメントと、ここでのスプレッドのサイズルール)。

カウンターポジションを使用してTPで決済して、ステートメントを確認してみましょう。 このようなポジションの始値は1.28であるべきで、ご存知のように売り注文はビッドで発注されます。現在、ビッドは1.2695です。したがって、TPで決済するには、5ピップス(スプレッドの損失をカバーするため)+100ピップスを渡して利益を確定する必要があります。

SLの場合 - 価格がSLレベルに達した場合。


では、どの価格になるかを理解しましょう。論理的には、ビッド価格(カウンター注文の開始価格に相当)になるはずです。

現在(ポジションの開始条件によると)Bidは1.2695である。したがって、SLが発動する前に価格が45ピップス通過する必要があります。

したがって、スプレッド(5ピップス)+SLが発動するまでに価格が通過する時間(45ピップス)に相当する損失を計上することになります。

この観点からは、あなたは正しい。

カウンターポジションを使用してSLで決済することで、当社のステートメントを確認してみましょう。 このようなポジションの始値は1.2650であるべきで、ご存知のように売り注文はビッドで始まります。現在、ビッドは1.2695である。したがって、SLでクローズするには、45ピップを通過する必要があります。SLがトリガーされると、50ピプスの損失が記録されます(スプレッドの5ピプス + 反対の動きの45ピプス)。

追記

しかし、この観点からすると、MQL4のこの例は私にはよくわかりません。

int ticket;

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25)
    {
     ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green);
     if(ticket<0)
       {
        Print("OrderSend failed with error #",GetLastError());
        return(0);
       }
    }

より正確には、どのようなロジックに基づき、どのようなステートメントに基づいてSLとそれだけが考慮されるのか、私にはよくわかりません。

しかし、この例に基づいて(そしてこの例からのみ)、私は以下のことを得ました。

//基本的な例
ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,SL = Bid-Loss*Point,TP = Ask+Profit*Point,"My order #"+counter,16384,0,Green);
//マーケット・ポジションのオープン注文
ticket=OrderSend(Symbol(),OP_BUY,1,1.27,3,1.2645 = 1.2695-50*Point,1.28 = 1.27+100*Point);

Open = 1.27、SL = 1.2645、TP = 1.28という値に基づいて、私は次のように理解します:

1.1.アスクが1.27に達したときにポジションがオープンされる;

2.2.BUレベルは1.27の価格に位置し、その上でクローズするには、シンボル(私たちの場合はEUR)のレートがスプレッドサイズ(私たちの場合は5ピップス)だけ拡大する必要があります;

3.3.オープンした時点で、スプレッド分の損失が即座に発生します(ポジションを即座に決済した場合)。MQL4のコードでは、このような操作は以下のようになります。

//基本的な例
ticket=OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0);
//市場でのポジションを反対注文で決済する。
ticket=OrderSend(Symbol(),OP_SELL,1,1.2695,3,0,0);

4.カウンター注文はこの価格でオープンされているため、論理的には、これはビッド価格であるべきである(ビッド価格が1.28の値に達したときに取引が実行される)。これに基づいて、MQL4コードのクロージングは以下のようになります。

//TPポジションを成行注文(カウンター注文)で決済する。
ticket=OrderSend(Symbol(),OP_SELL,1,1.28,3,0,0);
//リミッター注文でポジションを決済する。
ticket=OrderSend(Symbol(),OP_SELLLIMIT,1,1.28,3,0,0);

5.取引されているシンボル(ここではEUR)のレートが開始時点から50ピップス下落した後、SLがトリガーされます。


さて、最も興味深いのは

MQL4のヘルプにある同じ例(おそらく何千人もの人が使っている典型的な例)に基づいて、マーケットポジションのオープンをチェックしてみましょう。

このコードを使って確認してみましょう。

//+------------------------------------------------------------------+
double PriceOpen,PriceSL,PriceTP;
int ticket;
//+------------------------------------------------------------------+
//注文の価格を設定する
PriceOpen = Ask;
PriceSL   = Bid-500*Point;
PriceTP   = PriceOpen+1000*Point;
//マーケット・ポジションのオープン注文
ticket = OrderSend(Symbol(),OP_BUY,0.10,PriceOpen,5,PriceSL,PriceTP);
//+------------------------------------------------------------------+

このコードをアルパリのサーバーで実行すると(実際の相場を使用して)、次のような結果が得られます。

2010.08.24 09:12:47 '******': instant order buy 0.10 EURUSD at 1.26292 sl: 1.25776 tp: 1.27292

この場合、SL = 516 (または4桁で51ピップス) TP = 1000 (または4桁で100ピップス)となります。

PPS

MQL4のヘルプを見て みましょう:

パラメータを見てみましょう:
シンボル - 取引操作が実行される金融商品の名前。
cmd - 取引操作。取引操作の 値のいずれかを指定できます。
数量 - ロット数。
価格 - 始値。
スリッページ - 成行注文(買いまたは売り注文)の最大許容価格偏差。
ストップロス - 損失レベルに達したときのポジションの終値(損失レベルがない場合は0)。
テイクプロフィット - 利益水準に達した時のポジションの終値(利益水準がない場合は0)。
コメント - 注文コメントのテキスト。コメントの最後の部分は、取引サーバーで変更できます。
マジック - 注文のマジック番号。ユーザー定義の識別子として使用できます。
満了 - 未決注文の有効期限。
arrow_colour - チャート上の始値矢印の色。このパラメータがない場合、または値がCLR_NONEの場合、始値矢印はチャートに表示されません。
  int ticket; if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25) { ticket=OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point, "My order #"+counter,16384,0,Green); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } } }

"真実はどこにあるのか教えてくれ"...?

OrderSend - Документация на MQL4
  • docs.mql4.com
OrderSend - Документация на MQL4
削除済み  
Yedelkin:

コードの以下の部分が理解できません:

// 直前のバー(バー1)の終値を、対応するExpert Advisor変数にコピーする。
   Cexpert.setCloseprice(mrate[1].close);  // バー1の終値
//--- 買いポジションがあるかどうかをチェックする
   if (Cexpert.checkBuy()==true)
   {
      if (Buy_opened) 
         {
            Alert("すでに買うポジションがある!"); 
            return;    // ロング・ポジションに追加しない
         }
      double aprice = NormalizeDouble(latest_price.ask,_Digits);
      double stl    = NormalizeDouble(latest_price.ask - STP*_Point,_Digits);
      double tkp    = NormalizeDouble(latest_price.ask + TKP*_Point,_Digits);
      int    mdev   = 100;
      // 注文する
      Cexpert.openBuy(ORDER_TYPE_BUY,Lot,aprice,stl,tkp,mdev);
   }
買いポジションを建てる場合、latest_price.ask 価格に注目すべきですが、そのようなポジションのストップロスとテイクプロフィットを設定する場合、latest_price.bid 価格に注目すべきです。これは正しいですか?なぜストップロスとテイクプロフィットはコードテキスト内の売値に基づいて設定されるのですか?これは誤植なのでしょうか、それとも特定のストラテジーの特殊性なのでしょうか。

コードのこの部分は、以下の記述に基づいて理解する必要があります:

а.ロング - アスクで建玉し、ビッドで決済。ショート - ビッドで建玉し、アスクで決済;

б.ポジションは反対注文で決済される;

в.BUレベルはオープンプライス;

г.TPとSLまでの距離は建値(CUレベル)から計算される;

д.TPは、ビッド価格がオープン価格+プロフィットサイズに等しいレベルに達したときにトリガーされます;

e.SLは、セキュリティが建値-損失サイズに等しいビッドレベルに達したときにトリガされます。

Expert Advisorの作者は、同じような記述に導かれた可能性が高い。できるだけわかりやすくするために、次の画面(赤い四角形に注目)を使って上記のことを説明します。


 
Interesting:

e.SLはBidがOpen Price - Loss sizeに等しいレベルに達したときに発動する。

ありがとうございます。しかし、「e」によると、ストップロスがトリガーされるとき、Bidは1.2645ではなく1.2650に、Askはそれぞれ1.2655にあるはずです。

削除済み  
Yedelkin:

ありがとうございます。しかし、ポイント「e」によると、ストップロスがトリガーされたとき、Bidは1.2645ではなく1.2650に、Askはそれぞれ1.2655になるはずです。

そうかもしれないので、市場によってストップロスがトリガーされたときに正確に何が起こるかを確認する必要があります(あるいは、利用可能なすべての終値の可能性を考慮してマトリックスモデルを調整する必要があります)。


e "については(私の理解では)。

オープン(アスク)からカウントする場合、私の理解が正しければ、1.27-50 = 1.2650(価格は45ピップスを通過し、ポーズはクローズする)となります。この場合、SLはBid 1.2650とAsk 1.2655で機能すると思います。

もう一つ、Bidから計算すると、1.2695-50 - 1.2645となります。SLをBidから計算すると、1.27-1.2645 = 55 pipsとなります(これは私たちの計画にはなかったと理解しています)。

追記

少なくとも、このモデルによって、建値からSLとTPのレベルを正しくブレイクすることができます(私の意見では正しい)。

もちろん、価格が現実にどのように計算されるべきか(SLとTPだけでなく)についての開発者の公式見解を聞くのは興味深いことです。

 

質問


100グリーンバックはルーブルですか?;)

 
を消すと約束した。
 
Jager:

質問


100グリーンバックはルーブルですか?;)

これはミリ秒単位のタイムアウト値です。このパラメータはすでにすべての取引機能から削除されています。
 

ありがとう。

しかし、これは正しいのでしょうか?

EAでは、各新しいバーの開始時に取引機会をチェックしています。

クラスの関数getbuffers()では、現在のバー0から始まる過去3バーのデータを取得します。

void MyExpert::getBuffers()
{
i f(CopyBuffer(ADX_handle,0,0,3,ADX_val)<0|| CopyBuffer(ADX_handle,1,0,3,plus_DI)<0 || CopyBuffer(ADX_handle,1,0,3,plus_DI)<00
|| CopyBuffer(ADX_handle,2,0,3,minus_DI)<0 || CopyBuffer(MA_handle,0,0,3,MA_val)<0)

ポジション1から始まる過去3バーのインジケータデータを取得すべきではありませんか?

サンクス

 

素晴らしい記事

貴重な記事をありがとうございます、

この記事に基づいて、IsNewBarやBuy_openedのような関数を クラスに組み込み、EAから呼び出せばよいのですね。

ありがとうございました、

また記事を楽しみにしています、

ハメッド

 

分からないことがあるので教えてください:

EAの一番最初に関数が呼び出されます

  Cexpert.doInit(ADX_Period,MA_Period);
при этом для ее корректного выполнения требуются уже установленные параметры symbol  и period :
//+-----------------------------------------------------------------------+
// クラスのパブリック関数 
//+-----------------------------------------------------------------------+
/*
 
 の初期化 */
void MyExpert::doInit(int adx_period,int ma_period)
{
   //--- ADXインジケータのハンドルを取得する
   ADX_handle=iADX(symbol,period,adx_period);
  //--- 移動平均インジケータのハンドルを取得する
   MA_handle=iMA(symbol,period,ma_period,0,MODE_EMA,PRICE_CLOSE);
однако, заполнение этих параметров конкретными значениями происходит позже, уже после Cexpert.doInit :
//--- 初期化関数を開始する。
   Cexpert.doInit(ADX_Period,MA_Period);
//--- クラスオブジェクトに必要なすべての変数を設定する
   Cexpert.setPeriod(_Period);     // ピリオドを設定する
   Cexpert.setSymbol(_Symbol);     // シンボル(通貨ペア)を指定
   
   Никак не пойму, как может правильно выполниться Cexpert.doInit, если переменной symbol пока не присвоено
значение (или как-то присвоено ?) Застрял тут и дальше никак . Спасибо.