MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 31

 
Vitalie Postolache:
エラーはコードの上の方、注文を選択する部分のどこかにあります。
それ以外には手を出さない。
 
spoiltboy:
他は触らない。
いずれにせよ、条件行だけでなく、前後のコードも見る必要があります。
 
Artyom Trishkin:
いずれにせよ、条件行だけでなく、前後のコードも見る必要があります。
extern int pointsl=100, pointtp=100, MagicB=111111, MagicS=2222, bars=10; extern double lotB=0.1, lotS=0.1。
double slB, tpB, slS, tpS; double x=0, z=0;


void OnTick()
{
double maxpr1=9999; double minpr1=9999;

for(int shift1=0; shift1<bars; shift1++)
{double i=iHigh(Symbol(),PERIOD_CURRENT, shift1);
if (i>maxpr1){maxpr1=i;}}.

for(int shiftA1=0; shiftA1<bars; shiftA1++)
{double y=iLow(Symbol(), PERIOD_CURRENT, shiftA1);
if (y<minpr1) {minpr1=y;}}とする。

if (BuyLimitCount()==0 && BuyCount()==0){。
slB=NormalizeDouble(minpr1-pointsl*Point,5)とする。
tpB=NormalizeDouble(minpr1+pointsl*Point,5)とする。
int ticketUP=OrderSend(Symbol(), OP_BUYLIMIT, lotB, minpr1, 3, slB, tpB, "", MagicB, 0, Red)です。
if (ticketUP==-1) Print("ERROR OP_BUY"); else Print("OP_BUY OK");}.

if (SellLimitCount()==0 && SellCount() ==0){。
slS=NormalizeDouble(maxpr1+pointsl*Point,5)となります。
tpS=NormalizeDouble(maxpr1+pointsl*Point,5)。
int ticketD=OrderSend(Symbol(), OP_SELLLIMIT, lotS, maxpr1, 3, slS, tpS, "", MagicS, 0, Blue)です。
if (ticketD==-1) Print("ERROR OP_SELL"); else Print("OP_SELL OK");}.

if (x!=maxpr1){x=maxpr1; OrderDelete(ticketD);}.
if (z!=minpr1){z=minpr1; OrderDelete(ticketUP);}.


double maxpr=-9999; double minpr=9999;

for(int shift=0; shift<bars; shift++)
{double e=iHigh(Symbol(), PERIOD_CURRENT, shift);
if (e>maxpr){maxpr=e;}}.

for(int shiftA=0; shiftA<bars; shiftA++)
{double r=iLow(Symbol(), PERIOD_CURRENT, shiftA)とする。
if (r<minpr) {minpr=r;}}.

の文字列を入力します。
if(bars==1)a="bar:"。
else a= IntegerToString(bars,1) + " bars: ";
Comment("Last ", a, "max ", DoubleToStr(maxpr, 5), ", min ", DoubleToStr(minpr, 5),");
}

int BuyLimitCount(){。
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--){。
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){。
if(OrderMagicNumber()==MagicB){。
if(OrderType()==OP_BUYLIMIT)
count++;}}return(count);}。

int BuyCount(){。
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--){。
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){。
if(OrderMagicNumber()==MagicB){。
if(OrderType()==OP_BUY)
count++;}}return(count);}}etc.

int SellLimitCount(){。
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--){。
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){。
if(OrderMagicNumber()==MagicS){。
if(OrderType()==OP_SELLLIMIT)
count++;}}return(count);}}etc.

int SellCount(){。
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--){。
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){。
if(OrderMagicNumber()==MagicS){。
if(オーダータイプ()==OP_SELL)
count++;}}return(count);}}etc.
 
spoiltboy:
...
とにかく、この、すみません、不気味なコードで何をしようとしてるんですか?
 
spoiltboy:

コードをきれいにして、SRCを使って 、きちんと貼り付けますか?

削除を試みる前にOrderSelectを適用してみては いかがでしょうか。

 
spoiltboy:
...

注文 数やポジション数など、必要な構造フィールドは1つで記入できるのに、なぜそこで多くのループが必要なのかわかりません。

不要なものは削除し、削除も削除しました。チケット単位で削除する必要はなく(それでも削除前に知る必要がある)、ループの中でインデックスによる正しい順序を見つけ、削除することができます。

そこで、注文を検索して削除するための関数がもう一つ必要 で、それは条件がある場合に呼ばれるはずですが、どのような条件なのか - あなたのコードに目を通していてもすぐには理解できませんでしたし、目を通している暇もありませんでした。必要な条件を言葉で 表現していただければ、削除の方法をお伝えします。

見ずに勝手に書いたので、注文数やポジション数を構造体に記入する関数に間違いがあるかもしれません - チェックしていません。

//--- input variables
input    double   LotB=0.1;      // Лот Buy
input    double   LotS=0.1;      // Лот Sell
input    int      Pointsl=100;   // StopLoss в пунктах
input    int      Pointtp=100;   // TakeProfit в пунктах
input    int      NumBars=10;    // Количество баров для поиска Max/Min
input    int      Magic=100500;  // Magic

//--- global variables
struct DataNumOrders
  {
   int buy;          // Количество позиций Buy
   int sell;         // Количество позиций Sell
   int buy_limit;    // Количество ордеров BuyLimit
   int buy_stop;     // Количество ордеров BuyStop
   int sell_limit;   // Количество ордеров SellLimit
   int sell_stop;    // Количество ордеров SellStop
  };
DataNumOrders numOrders;   // Количество ордеров
double lotB, lotS;
int    pointsl, pointtp, numBars;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   numBars=(NumBars<1?1:NumBars>Bars?Bars:NumBars);
   pointsl=(Pointsl<0?0:Pointsl);
   pointtp=(Pointtp<0?0:Pointtp);
   double minLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   double maxLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   lotB=(LotB<minLot?minLot:LotB>maxLot?maxLot:LotB);
   lotS=(LotS<minLot?minLot:LotS>maxLot?maxLot:LotS);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- заполним структуру количеством ордеров и позиций
   GetNumOrders(Symbol(),Magic,numOrders);
  
   //--- найдём максимальную и минимальную цены за bars свечей
   double maxPrice=0.0; double minPrice=DBL_MAX;
   for(int i=0; i<numBars; i++) {
      double max_i=iHigh(Symbol(),PERIOD_CURRENT,i);
      if(max_i>maxPrice) maxPrice=max_i;
      double min_i=iLow(Symbol(),PERIOD_CURRENT,i);
      if(min_i<minPrice) minPrice=min_i;
      }

   //--- выставим BuyLimit
   if(numOrders.buy_limit==0 && numOrders.buy==0) {
      double slB=(pointsl==0?0:NormalizeDouble(minPrice-pointsl*Point(),Digits()));
      double tpB=(pointtp==0?0:NormalizeDouble(minPrice+pointtp*Point(),Digits()));
      int ticketUP=OrderSend(Symbol(), OP_BUYLIMIT, lotB, minPrice, 3, slB, tpB, "", Magic, 0, clrRed);
      if(ticketUP==-1) Print("ERROR OP_BUY");
      else Print("OP_BUY OK");
      }
   //--- выставим SellLimit
   if(numOrders.buy_limit==0 && numOrders.sell==0) {
      double slS=(pointsl==0?0:NormalizeDouble(maxPrice+pointsl*Point(),Digits()));
      double tpS=(pointtp==0?0:NormalizeDouble(maxPrice-pointtp*Point(),Digits()));
      int ticketD=OrderSend(Symbol(), OP_SELLLIMIT, lotS, maxPrice, 3, slS, tpS, "", Magic, 0, clrBlue);
      if(ticketD==-1) Print("ERROR OP_SELL");
      else Print("OP_SELL OK");
      }

   //--- Тут должно быть удаление, но не понятно при каких условиях. Опишите их
  
  
   //---
   string a=(numBars==1)?"bar: ":IntegerToString(numBars,1)+" bar's: ";
   Comment("Last ", a, "max ", DoubleToStr(maxPrice, Digits()), ", min ", DoubleToStr(minPrice, Digits()),".");
  }
//+------------------------------------------------------------------+
//| Записывает в структуру количество позиций и отложенных ордеров   |
//+------------------------------------------------------------------+
void GetNumOrders(string symbol_name, int magic_number, DataNumOrders &number_of) {
   ZeroMemory(number_of);
   for(int i=OrdersTotal()-1; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS)) {
         if(OrderMagicNumber()!=magic_number) continue;
         if(OrderSymbol()!=symbol_name)       continue;
         if(OrderType()==OP_BUY)       number_of.buy++;
         if(OrderType()==OP_BUYLIMIT)  number_of.buy_limit++;
         if(OrderType()==OP_BUYSTOP)   number_of.buy_stop++;
         if(OrderType()==OP_SELL)      number_of.sell++;
         if(OrderType()==OP_SELLLIMIT) number_of.sell_limit++;
         if(OrderType()==OP_SELLSTOP)  number_of.sell_stop++;
         }
      }
}
//+------------------------------------------------------------------+
 
Artyom Trishkin:
一般的に、この、すみません、不気味なコードで何をしようとしているのでしょうか?
EAは過去X個のバーの最小値と最大値をカウントし、それらに注文を出します。そして、高値や安値が下がったり上がったりしたら、注文を削除して、新しいデータで開く必要があるのです。


 

の書き方を教えてください。

価格が 1%変動 した場合、例えばOPEN日がSlose日よりも1%多く変動している場合

 
Movlat Baghiyev:

の書き方を教えてください。

価格が1%変動した場合、OPEN日がSlose日よりも1%多いとします。

それは違う、今は1%が何に関連しているのかが明確になっている;)

if(Open[x] > Close[x]+Open[x]*0.01) {code}
 
spoiltboy:
Expert Advisor は、過去 X 本のバーの最小値と最大値をカウントし、その値で注文を出します。また、最大値の減少や最小値の増加があった場合は、該当する注文を削除し、新しいデータで開く必要があります。


設定価格とストップ、テイクアウトを新しいレベルに相対的に変更できるのに、なぜ削除するのですか?結局のところ、保留中の注文がなく、かつマーケットポジションがないときにのみ、保留中の注文を出すことになるのです。つまり、市場に保留中の注文が あり、対応する市場ポジションがない場合、保留中の注文の価格-設定価格を新しいレベルに、そのストップオーダー-をそれぞれ新しいレベルに変更すればよいのです。

毎回、MaxとMinの検出価格を覚えておく必要があります。もし現在見つかっているMaxの価格が以前のものより低ければ、保留中のBuyLimitを修正し、Maxの新しい価格を記憶させます。Min価格ならミラーリング。