Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 31

 
Vitalie Postolache:
Ошибка где-то выше по коду, в районе  выбора ордера.
Да остальное то не трогаю.
 
spoiltboy:
Да остальное то не трогаю.
В любом случае нужно видеть предшествующий и последующий код, а не только строки с условиями.
 
Artyom Trishkin:
В любом случае нужно видеть предшествующий и последующий код, а не только строки с условиями.
extern int pointsl=100, pointtp=100, MagicB=1111, 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+pointtp*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-pointtp*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;}} 

string a;
if(bars==1)a="bar: ";
else a= IntegerToString(bars,1) + " bar's: ";
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);}

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

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(OrderType()==OP_SELL)
count++;}}}return(count);}
 
spoiltboy:
...
А вообще, что вы пытаетесь сделать этим, простите, жутким кодом?
 
spoiltboy:

Код причесать и вставить нормально, с помощью SRC - не судьба?

Почему перед попыткой удаления не применяете OrderSelect

 
spoiltboy:
...

Не понятно зачем вам там столько циклов, когда можно в одном заполнить нужные поля структуры о количестве ордеров и позиций.

Убрал лишнее, и удаление тоже убрал. Вам нужно не по тикету удалять (его ещё нужно знать перед удалением), а в цикле найти нужный ордер по индексу, и удалить его.

Значит, нужна ещё одна функция для поиска и удаления ордеров, которую нужно вызывать при наступлении условия, а вот какого - я не понял сразу, глядя в ваш код, да и особо разбираться некогда было. Опишите нужные условия словами, и подскажем вам как нужно удалять.

Писал на коленке, не глядя, так что в функции заполнения структуры с количеством ордеров и позиций могут быть косяки - не проверял.

//--- 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:
А вообще, что вы пытаетесь сделать этим, простите, жутким кодом?
Советник считает min и max за последние Х бар и выставляет по ним ордера. Далее, при уменьшении максимума или увеличении минимума нужно удалить соотв ордер и открыть по новым данным.


 

как прописать следующее :

Если цена изменилась на 1 %   скажем OPEN дня больше Сlose дня на 1 %

 
Movlat Baghiyev:

как прописать следующее :

Если цена изменилась на 1 %   скажем OPEN дня больше Сlose дня на 1 %

Ну вот, другое дело, теперь понятно, относительно чего 1% ;)

if(Open[x] > Close[x]+Open[x]*0.01) {code}
 
spoiltboy:
Советник считает min и max за последние Х бар и выставляет по ним ордера. Далее, при уменьшении максимума или увеличении минимума нужно удалить соотв ордер и открыть по новым данным.


Зачем удалять, если можно модифицировать цену установки и стоп с тейком относительно нового уровня? Ведь у вас выставляются отложки только при их отсутствии и отсутствии рыночных позиций. Значит: если в рынке есть отложенный ордер, и нет соответствующей рыночной позиции, то нужно просто модифицировать цены у отложенного ордера - цену установки на новый уровень, а его стоп-приказы - соответственно новому уровню.

Каждый раз запоминайте найденные цены Max и Min. Если текущая найденная цена Max меньше прошлой, то модифицируем отложенный BuyLimit и запоминаем новую цену Max. Для цены Min - зеркально.

Причина обращения: