グリッドメーカー 1.1 - ページ 4 123456 新しいコメント Forex Trader 2005.07.18 15:33 #31 申し訳ありません、コリ。私は、どのグリッドポジションにも1つのオーダーしか持っておらず、数週間にわたって、すべてのバリエーションをテストしてきました。 バックテストでこの問題が発生しますが、これはスクリプトの問題ではなく、MT4のバックテストの 問題です。 ありがとうございます、ありがとうございます。 Forex Trader 2005.07.18 18:34 #32 私はそれを発見しました。そして、私はそれを面白がっていません。 アドバイザーは私の指定したコメント "GridEURUSD "でグリッドを作成しています。このコメントは、注文が待機している間、コメント欄に表示されます。注文が起動されると、コメントは "activate/auto "に変わります。結局のところ、この動作が記述した問題につながることは明らかです。 私はAlpariで取引しています。彼らはデモ 口座でMT4をサポートしています。 この挙動を回避できるかどうか、つまり注文のマジックをグリッドの識別子として使用できるかどうかを確認し、結果をお知らせするつもりです。 このテストをしている間に、グリッドのクリーンアップ・スクリプトにも手を加えました。オープンオーダーをクローズする機能も追加しました。残念ながら、未決済注文を決済しようとすると、Order locked というエラー129が発生します。しかし、それは与えられたグリッドのすべての保留中の注文を削除します。 //+----------------------------------------------------------+ //| RemoveGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+----------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" extern string GridName = "Grid"; extern bool closeOpen = false; //+------------------------------------------------------------------------+ //| スクリプトプログラム開始関数 | //+--------------------------------------------------------+ int start() { #property show_inputs // パラメータを表示 - Slawaさんに感謝...。 //---- int total = OrdersTotal(); int i ; for(i=total-1; i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if ( OrderSymbol()==Symbol() && OrderComment() == GridName ) { bool result = false; switch(type) { case OP_BUY :if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Ask, 0, Blue ); } break; case OP_SELL :if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Bid, 0, Blue ); } break; //保留中の注文を閉じる case OP_BUYLIMIT : result = OrderDelete( OrderTicket() ); break; case OP_BUYSTOP :result = OrderDelete( OrderTicket() ); break; case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); break; case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); break; } if(result == false) { Print("Order " , OrderTicket() , " failed to close.Error:" , GetLastError() ); // Sleep(3000); }. } } //---- return(0); } //+-----------------------------------------------------------------------------+. コーリ MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 コーディングの方法は? Help me please about Forex Trader 2005.07.18 20:01 #33 OK、CORI、ありがとう。 ブローカーがそのような奇妙なことを行うことを知らなかったので、私は魔法を使用します。 ありがとう、そしてよろしく。 抱擁 Forex Trader 2005.07.18 21:09 #34 さて、あれです。 グリッドメーカーでコメントの代わりにOrderMagicNumberを使用するように変更しました。また、コメントの構築についても少し修正しました。 以下はその結果です。 //+----------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+----------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.4beta" // modified by cori.グリッドのトレードを識別するために OrderMagicNumber を使用 extern int uniqueGridMagic = 11111; // トレードのマジックナンバー。1; // extern double GridSize = 6; // グリッドまたはメッシュサイズの注文間のピップ数 extern double GridSteps = 12; // 注文する合計数 extern double TakeProfit = 6 ; // 利食いするティック数。通常=グリッドサイズだが、オーバーライドできる extern double StopLoss = 0; // もし、ストップロスを追加したい場合。通常のグリッドではストップロスを使用しない extern double UpdateInterval = 1; // x分ごとに注文を更新 extern bool wantLongs = true; // ロングポジションを取るかどうか extern bool wantShorts = true; // ショートポジションを取るかどうか extern bool wantBreakout = true; // extern bool wantCounter = true; // 価格より上にロング、下にショートしたい extern bool limitEMA34 = false; // EMAより上にロング、下にショートしたい // Coriによって修正されました。内部変数のみ double LastUpdate = 0; // 最終更新時刻を記録するためのカウンタ double GridMaxOpen = 0; // オープンポジションの最大数 string GridName = "Grid"; // グリッドを識別。複数のグリッドが共存できる //+----------------------------------------------------------------+ //|エキスパート初期化関数 | //+-------------------------------------------------------- int init() { //---- #property show_inputs //パラメータを見せる - Slawaに感謝。 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| atRateの領域にオープンポジションまたは注文があるかどうかテストする | //| checkLongsが真であればロングをチェックし、さもなければショートをチェックする | //+--------------------------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal(); for(int j=0;j<totalorders;j++) // すべてのオーダーとポジションをスキャンします。... { OrderSelect(j, SELECT_BY_POS); // Coriによって修正されました。OrderMagicNumber を使ってグリッドの取引を特定 if ( OrderSymbol()==Symbol() && OrderMagicNumber() == uniqueGridMagic ) // mygridとシンボルだけを見て... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // 正確な価格ではなく、価格の近さ(グリッドサイズより小さい)を探す { if ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) ) }; if ( チェックロングの数 && ( type == OP_BUY|op_buy)||type=OP_BUYSTOP)。 ||(!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } return(false); } //+------------------------------------------------------------------------+ //| スクリプトプログラム開始関数 | //+--------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // 最初に呼ばれた時と UpdateInterval 分毎に更新します { LastUpdate = CurTime().LastUpdate; // UpdateInterval 分毎に更新します { LastUpdate = CurTime()-LastUpdate*60) // UpdateInterval 分毎に更新します { LastUpdate = CurTime().LastUpdate; // UpdateInterval 分毎に更新します Print("Updating"); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // GridSizeで割り切れるティックの数に丸めます k = startrate ; k = k * GridSize; startrate = k * point - GridSize*GridSteps/2*point ; // 最低エントリーポイントを計算 double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs &&( !リミットEMA34 || traderate=i*point*GridSize); if ( wantLongs &&( !リミットEMA34 || traderate=i*point*GridSize); if (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false ) // 価格に近い未決済注文がないかをテスト:もしあれば、1つ付ける { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } } else { entermode = OP_BUYSTOP; } if ( traderate > Ask ) { myStopLoss = traderate-point*StopLoss ; } } else { myStopLoss = myStopLoss 但し、この場合、entermode = OP_BUYLIMIT ; }。 if ((traderate > Ask ) && (wantBreakout))| ((traderate <= Ask ) && (wantCounter)) ) { // coriさんによって修正されました。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),Entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( wantShorts && (!limitEMA34 || traderate < EMA34) ) { if (IsPosition(traderate,point*GridSize,false)== false ) // 価格に近い未決済注文がないかをテスト:もしあれば、1つ付ける { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } } if ( traderate > Bid ) { myStopLoss = traderate+point*StopLoss ; } } else { entermode = OP_Bid 但し、entermode = OP_SELLSTOP ; }. if ((取引レート < ビッド) && (wantBreakout))| ((取引レート >= Bid ) && (wantCounter)) ) { // coriさん修正。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } return(0); } //+---------------------------------------+... by regards, cori Grid maker 1.1 Help: How to write コーディングの方法は? Forex Trader 2005.07.19 00:11 #35 私はすでにいくつかの変更を自分自身で行っていたので、あなたの変更を新しいバージョンに統合しました。 私は1つの小さなバリエーションを行いました:私の現在のグリッドをアクティブに保つために、私はマジックOR gridnameにテストを置く... あなたは私がそれを正しく行ったかどうかをチェック することができますか? //+--------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+--------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.6beta" // modified by cori.S. // MakeGrid.mq4は、MakeGrid.mq4で作成されたものです。グリッドのトレードを識別するために OrderMagicNumber を使用 extern int uniqueGridMagic = 11111; // トレードのマジックナンバー。1; // extern double GridSize = 6; // 注文間のピップ数 - グリッドまたはメッシュサイズ extern double GridSteps = 12; // 注文の総数 extern double TakeProfit = 12 ; // 利食いするティック数。通常=グリッドサイズだが、オーバーライドできる extern double StopLoss = 0; // ストップロスを追加したい場合。通常のグリッドではストップロスを使用しない extern double UpdateInterval = 1; // x分ごとに注文を更新 extern bool wantLongs = true; // ロングポジションが欲しいかどうか extern bool wantShorts = false; // ショートポジションが欲しいかどうか extern bool wantBreakout = true; // extern bool wantCounter = true; // 価格より上にロング、下にショートしたい extern bool limitEMA34 = true; // EMAより上にロング、下にショートしたい extern double GridMaxOpen = 0; // オープンポジションの最大数:未実装。extern bool UseMACD = true; // trueの場合、ロングのみmacd >0を使用、ショートのみmacd >0を使用 // クロスオーバー時に、すべての保留中の注文をキャンセルします。extern bool CloseOpenPositions = false;// UseMACDの場合、オープンポジションも損切りするか? 内部変数のみ string GridName = "Grid"; // グリッドを特定する。複数のグリッドを共存させることができる double LastUpdate = 0; // 最終更新時刻を記録するためのカウンター //+------------------------------------------------------------------------------+ //|エキスパート初期化関数 | //+--------------------------------------------------------------------------+ int init() { //---- #property show_inputs //パラメータを表示 - Slawaに感謝...。 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- // 私のコリを追加し、hdbによって削除された!笑... ただ、オープングリッドと互換性を保つために... // GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| atRateの領域にオープンポジションまたはオーダーがあるかどうかをテストする | //| checkLongsが真であればロングをチェックする、それ以外はショートをチェックする | //+----------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal().Border; // /// } //+----------------------------------------+ //| checkLongsが真であればロングをチェックする。 for(int j=0;j<totalorders;j++) // すべての注文とポジションをスキャンします。... { OrderSelect(j, SELECT_BY_POS); // Coriによって修正されました。OrderMagicNumberを使ってグリッドの取引を識別 // hdbを追加、または互換性のためにgridnameを追加 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) ) // mygridとシンボルだけを見て... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // 正確な価格ではなく、価格の近さ(グリッドサイズより小さい)を探す { if ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) ) ) ||(!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } return(false); } //+--------------------------------------------------------+ //| すべての保留中の注文をキャンセルする | //+--------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // すべての注文と位置をスキャン... { OrderSelect(j, SELECT_BY_POS); // coriのように修正。グリッドの取引を識別するためにOrderMagicNumberを使用 // 互換性のためにhdbを追加またはグリッド名 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) ) // mygridとsymbolの場合のみ検索... {int type = OrderType(); bool result = false; switch(type) { case OP_BUY : result = true ; case OP_SELL : result = true ; //保留中の注文を決済する case OP_BUYLIMIT :result = OrderDelete( OrderTicket() ); case OP_BUYSTOP : result = OrderDelete( OrderTicket() ); case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); } } } } } } else return; } //+------------------------------------------------------------------------+ //| すべての保留中の注文をキャンセルし、オープンポジションをクローズする | //+--------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // Coriによって修正されました。OrderMagicNumberを使ってグリッドの取引を識別する // hdbを追加、または互換性のためにグリッド名を追加 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) ) // mygridとsymbolの場合のみ... {// Print("Closing 2 ",type); switch(type) { //オープンしたロングポジションをクローズする case OP_BUY : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ); break; //オープンしたショートポジションをクローズする case OP_SELL :result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); break; //未決済注文を決済する場合 case OP_BUYLIMIT : case OP_BUYSTOP : case OP_SELLLIMIT : case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); } } if(result == false) { // Alert("Order " , OrderTicket() , " failed to close.Error:" , GetLastError() ); // Sleep(3000); } } return; } // +------------------------------------------------------------------------------ // OrderDelete( OrderTicket()) } return; } //+------------------------------------------------------------------------+ //| スクリプトプログラム開始関数 | //+--------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // 最初に呼ばれた時と UpdateInterval 分毎に更新します { LastUpdate = CurTime(); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // GridSizeで割り切れるティックの数に丸めます k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ; // 最安値エントリーポイントを計算 double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // クロスアップ { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // cross down { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders();} } wantLongs = false; wantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0) // ゼロよりかなり上 { wantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2>0 )& Macd1<0 && Macd2<0) // ゼロよりかなり下 { wantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && ( !limitEMA34||traderate;limitEMA34);if(.traderrate;limitEMA34)if(!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false ) // 価格に近い未決済注文がないかをテスト:もしあれば、1つ付ける { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } } else { entermode = OP_BUYSTOP; } if ( traderate > Ask ) { myStopLoss = traderate-point*StopLoss; } } else { myStopLoss = myStopLoss 但し、この場合、entermode = OP_BUYLIMIT ; }。 if ((traderate > Ask ) && (wantBreakout))| ((traderate <= Ask ) && (wantCounter)) ) { // coriさんによって修正されました。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),Entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( wantShorts && (!limitEMA34 || traderate < EMA34) ) { if (IsPosition(traderate,point*GridSize,false)== false ) // 価格に近い未決済注文がないかをテスト:もしあれば、1つ付ける { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } }. 但し、entermode = OP_SELLSTOP ; }. if ((取引レート < ビッド) && (wantBreakout))| ((取引レート >= Bid ) && (wantCounter)) ) { // coriさん修正。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } return(0); } //+---------------------------------------+... Grid maker 1.1 コーディングの方法は? MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 Forex Trader 2005.07.19 07:59 #36 hdbさん、こんにちは。 はOKのようです。しかし、GridNameをexternで定義する必要があります。私はパラメータとして 必要なかったので、変更しました。 ご挨拶、coriさん。 Forex Trader 2005.07.20 22:03 #37 ATTENTION all users of GridMaker - IsPosition関数に バグがあります - その結果、すべてのグリッドスロットが埋まっていません。 if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // 正確な価格を探さないが、価格が近い (グリッドサイズより小さい) to if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9) )// 正確な価格を探すのではなく、価格の近さ(グリッドサイズより小さい)を探す - 浮動小数点のエラーのため0.9を追加 これで問題が修正されます。 ご迷惑をおかけして申し訳ありません... hugues Forex Trader 2005.07.20 23:09 #38 huguesさん、こんにちは。 この問題はすでにあるのでしょうか? 古いMQL2で似たようなものを見つけました。 この問題を回避する本当に確実な方法は、次のようなことです。 intOOP = MathRound( OrdeOpenPrice() / Point ); のようにすることです。そうすれば、int型変数がそのまま使えるので、不具合なく比較できます。 このように、わかりやすくするために、少し記述が増えますが、不具合は少なくなります。 よろしくお願いします。 コーリ Forex Trader 2005.07.21 12:51 #39 そうですね、その方がエレガントです。ただ、私は怠け者なので よろしくお願いします。 抱擁 Forex Trader 2005.07.29 11:33 #40 GridMaker EAのアップデートを紹介します。このバージョンで私は 1) UseMACD、wantLongs、wantShortsのロジックを変更しました。以前は、useMACDが設定されている場合、EAはwantLongsとwantShortsフラグに関係なく、ロングとショートを取っていました。現在、useMACDはこれらのフラグを上書きしないので、useMACDでロングのみ、またはショートのみにすることができます。 2) limitEMA34が設定されている場合、EMAの間違った側に未決済の注文がないことを確認するための追加チェックを追加しました。以前はEMAの上か下に注文がうまく入っていたのですが、数時間後にEMAが動いたので、EMAの両側に注文が入ってしまったのです。 3) OrderType()のswitchステートメントにバグがあるようです。私は単純にswitchステートメントを削除し、"if "に置き換えました...私はそれが好きではありませんが、それは動作します 4) EMAの期間を変数にしました...バックテストに 最適です...。 1) あるペアの未決済のオープンオーダーを削除する 2) すべてのペアのオープンオーダーを一度に削除する 3) すべてのポジションを決済し、オープンオーダーを削除する。 4) オープンポジションと履歴からグリッドの動作に関する簡単な統計情報を取得する。 以下はV1.08のコードです: //+------------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+----------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.8" // DISCLAIMER ***** IMPORTANT NOTE ***** READ BEFORE USING ***** // このエキスパートアドバイザーは実際の位置をオープン、クローズすることができ、したがって実際の取引を行い実際のお金を失うことがあります。 // これは「トレーディングシステム」ではなく、固定されたルールに従って取引を行うシンプルなロボットです。 // 作者はこのシステムの収益性を気取ることはなく、デモ口座でのテスト目的以外にこのEAの使用をお勧めしません。 // このシステムの使用は無料です - ただし転売はできません - そしていかなる目的に対してもその適合性を保証するものではありません。 // このプログラムを使用することにより、あなたはこのプログラムが何をするものかを理解し、 // 作者がいかなる損失に対しても責任を負わないことに暗黙のうちに同意するものとします。 // 使用する前に、彼のシステムがこの専門家に関連する最も頻繁な取引に適応しているかどうか、 // あなたの仲介者に確認してください。 // 1.8 変化 // wantLongs と wantShorts を局所変数にした。以前は、UseMACDをtrueに設定すると、 // ロングとショートを行い、単にwantLongsとwantShortsフラグを無視しました。 // limitEMA34 フラグが使用されているとき、EMA の上下に「不正な」オープンオーダーがあるかどうかをチェックするループを追加しました。これらは時間とともに蓄積され、決して取り除かれることはなく、EMAが動くことが原因です。 // 動作しないようなのでスイッチ命令を削除 - if文に置き換え // EMA期間を変数にしました // // coriによって修正。グリッドのトレードを識別するためにOrderMagicNumberを使用 extern int uniqueGridMagic = 11111; // トレイドのマジックナンバー。1; // extern double GridSize = 6; // グリッドまたはメッシュサイズの注文間のピップ数 extern double GridSteps = 12; // 注文する合計数 extern double TakeProfit = 12 ; // 利食いするティック数。通常=グリッドサイズだが、オーバーライドできる extern double StopLoss = 0; // もしストップロスを追加したい場合。通常のグリッドではストップロスを使用しない extern double UpdateInterval = 1; // x分ごとに注文を更新 extern bool wantLongs = true; // ロングポジションを希望するか extern bool wantShorts = true; // ショートポジションを希望するか extern bool wantBreakout = true; // extern bool wantCounter = true; // 価格より上にロング、下にショートしたい extern bool limitEMA = true; // EMAより上にロング、下にショートしたい extern int EMAperiod = 34; // EMAの長さを指定します。extern double GridMaxOpen = 0; // 最大オープンポジション数 : 未実装... extern bool UseMACD = true; // trueの場合、ロングのみmacd >0、ショートのみmacd >0を使用 // クロスオーバー時、すべての保留オーダーをキャンセルします。extern bool CloseOpenPositions = false;// UseMACDの場合、オープンポジションも損切りするか? extern bool doHouseKeeping = true; // 単なるテスト // coriによって修正された。内部変数のみ string GridName = "Grid"; // グリッドを特定する。複数のグリッドが共存できる double LastUpdate = 0; // 最終更新時刻を記録するためのカウンタ //+------------------------------------------------------------------------------+ //| 専門家の初期化関数 | //+--------------------------------------------------------------------------+ int init() { //---- #property show_inputs //パラメータを表示 - Slawaさんに感謝......。 //---- // 私のコリを追加し、hdbによって削除されました!笑...ただ、オープングリッドとの互換性を保つために... // GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| atRateの領域でオープンポジションまたはオーダーがあるかどうかをテストする | //| checkLongsが真ならロングをチェックする、それ以外はショートをチェックする | //+----------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal().Bool isPosition(double atRate, double inRange, bool checkLongs) { int totalorders = OrdersTotal(); for(int j=0;j<totalorders;j++) // すべての注文とポジションをスキャンします。... { OrderSelect(j, SELECT_BY_POS); // Coriによって修正されました。OrderMagicNumberを使ってグリッドの取引を識別 // hdbを追加、または互換性のためにgridnameを追加 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) ) // mygridとsymbolの場合のみ検索... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9))// 正確な価格を探すのではなく、価格の近接性(グリッドサイズより小さい)を探す - 浮動小数点誤差のため0.9を追加 { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) ) ) ||(!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } return(false); } //+--------------------------------------------------------+ //| すべての保留中の注文をキャンセルする | //+--------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // すべての注文とポジションをスキャン... { OrderSelect(j, SELECT_BY_POS); // Cori通りに修正しました。グリッドの取引を識別するためにOrderMagicNumberを使用 // 互換性のためにhdbを追加またはグリッド名 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) ) // mygridとsymbolの場合のみ検索... { int type = OrderType(); if ( type > 1 ) bool result = OrderDelete( OrderTicket() ); } } } }。 return; } //+------------------------------------------------------------------------+ //| すべての保留中の注文をキャンセルし、オープンポジションをクローズする | //+--------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // Coriによって修正されました。OrderMagicNumberを使ってグリッドの取引を識別する // hdbを追加、または互換性のためにグリッド名を追加 if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) ) // mygridとsymbolの場合のみ検索... { //Close open long positions if ( type == OP_BUY ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ); //ショートポジションを決済 if ( type == OP_SELL ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); //未決済注文を決済 if ( type > 1 ) result = OrderDelete( OrderTicket() ); } } return; } //+------------------------------------------------------------------------+ //| EMAの反対側にあるすべての未決済注文をキャンセルする| //+--------------------------------------------------------+ void CloseOrdersfromEMA( double theEMAValue ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // すべての注文とポジションをスキャンします。... { OrderSelect(j, SELECT_BY_POS); if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName) ) ) // mygridとsymbolの場合のみ検索... { int type = OrderType(); bool result = false; //if (type > 1) Print(type," ",theEMAValue," ",OrderOpenPrice()); if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_BUYSTOP && orderTicket() );// if ( type == OP_BUYSTOP && orderOpenPrice() <= theEMAValue )orderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } return; } //+------------------------------------------------------------------------+ //| スクリプトプログラム開始関数 | //+--------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- 設定パラメータ if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } bool myWantLongs = wantLongs.} // } bool myWantLorts = wantSize; // bool myWantLs = wantSize; // } bool myWantShorts = wantSize; // } bool myWantLongs = wantSize; // bool myWantShorts = wantSize bool myWantShorts = wantShorts; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // 最初に呼ばれたときと UpdateInterval 分ごとに更新します { LastUpdate = CurTime(); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // GridSizeで割り切れるティックの数に丸めます k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ; // 最安値のエントリーポイントを計算 double myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0); if (limitEMA) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA); } if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // クロスアップ { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // クロスダウン { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } myWantLongs = false; myWantShorts = false; if( Macd0>0 &&Macd1>0 &&Macd2>0 && wantLongs ) // ゼロよりかなり上 { myWantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0 && wantShorts ) // ゼロよりかなり低い { myWantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( myWantLongs && (!limitEMA || traderate > myEMA)) { if ( IsPosition(traderate,point*GridSize,true)==false)を満たすかどうか? // 価格に近い未決済注文がないかをテストする:もしあれば、1つ付ける { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } } else { entermode = OP_BUYSTOP; } if ( traderate * * * * * * * * * * * * * * * * * * * * * * * ** ) 但し、この場合、entermode = OP_BUYLIMIT ; }。 if ((traderate > Ask ) && (wantBreakout))| ((traderate <= Ask ) && (wantCounter)) ) { // coriさんによって修正されました。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),Entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } if ( myWantShorts && (!limitEMA || traderate < myEMA)) { if (IsPosition(traderate,point*GridSize,false)== false ) // このような場合、「entermode = OP_SELLLIMIT; }」とすることで、「entermode = OP_SELLLIMIT; }」とすることで、「entermode + Bid」とすることができます。 但し、entermode = OP_SELLSTOP ; }. if ((取引レート < ビッド) && (wantBreakout))| ((取引レート >= Bid ) && (wantCounter)) ) { // coriさん修正。OrderMagicNumberを使ってグリッドの取引を特定 ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } return(0); } //+---------------------------------------+... 123456 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
バックテストでこの問題が発生しますが、これはスクリプトの問題ではなく、MT4のバックテストの 問題です。
ありがとうございます、ありがとうございます。
アドバイザーは私の指定したコメント "GridEURUSD "でグリッドを作成しています。このコメントは、注文が待機している間、コメント欄に表示されます。注文が起動されると、コメントは "activate/auto "に変わります。結局のところ、この動作が記述した問題につながることは明らかです。
私はAlpariで取引しています。彼らはデモ 口座でMT4をサポートしています。
この挙動を回避できるかどうか、つまり注文のマジックをグリッドの識別子として使用できるかどうかを確認し、結果をお知らせするつもりです。
このテストをしている間に、グリッドのクリーンアップ・スクリプトにも手を加えました。オープンオーダーをクローズする機能も追加しました。残念ながら、未決済注文を決済しようとすると、Order locked というエラー129が発生します。しかし、それは与えられたグリッドのすべての保留中の注文を削除します。
コーリ
ブローカーがそのような奇妙なことを行うことを知らなかったので、私は魔法を使用します。
ありがとう、そしてよろしく。
抱擁
グリッドメーカーでコメントの代わりにOrderMagicNumberを使用するように変更しました。また、コメントの構築についても少し修正しました。
以下はその結果です。
by regards, cori
私は1つの小さなバリエーションを行いました:私の現在のグリッドをアクティブに保つために、私はマジックOR gridnameにテストを置く...
あなたは私がそれを正しく行ったかどうかをチェック することができますか?
はOKのようです。しかし、GridNameをexternで定義する必要があります。私はパラメータとして 必要なかったので、変更しました。
ご挨拶、coriさん。
if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // 正確な価格を探さないが、価格が近い (グリッドサイズより小さい)
to
if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9) )// 正確な価格を探すのではなく、価格の近さ(グリッドサイズより小さい)を探す - 浮動小数点のエラーのため0.9を追加
これで問題が修正されます。
ご迷惑をおかけして申し訳ありません...
hugues
この問題はすでにあるのでしょうか?
古いMQL2で似たようなものを見つけました。
この問題を回避する本当に確実な方法は、次のようなことです。
intOOP = MathRound( OrdeOpenPrice() / Point );
のようにすることです。そうすれば、int型変数がそのまま使えるので、不具合なく比較できます。
このように、わかりやすくするために、少し記述が増えますが、不具合は少なくなります。
よろしくお願いします。
コーリ
よろしくお願いします。
抱擁
1) UseMACD、wantLongs、wantShortsのロジックを変更しました。以前は、useMACDが設定されている場合、EAはwantLongsとwantShortsフラグに関係なく、ロングとショートを取っていました。現在、useMACDはこれらのフラグを上書きしないので、useMACDでロングのみ、またはショートのみにすることができます。
2) limitEMA34が設定されている場合、EMAの間違った側に未決済の注文がないことを確認するための追加チェックを追加しました。以前はEMAの上か下に注文がうまく入っていたのですが、数時間後にEMAが動いたので、EMAの両側に注文が入ってしまったのです。
3) OrderType()のswitchステートメントにバグがあるようです。私は単純にswitchステートメントを削除し、"if "に置き換えました...私はそれが好きではありませんが、それは動作します
4) EMAの期間を変数にしました...バックテストに 最適です...。
1) あるペアの未決済のオープンオーダーを削除する
2) すべてのペアのオープンオーダーを一度に削除する
3) すべてのポジションを決済し、オープンオーダーを削除する。
4) オープンポジションと履歴からグリッドの動作に関する簡単な統計情報を取得する。
以下はV1.08のコードです: