Ustawienie TakeProfit

O jezykach programowania w platformach i nie tylko.
Kris82
Stały bywalec
Stały bywalec
Posty: 34
Rejestracja: 11 lip 2012, 00:27

Ustawienie TakeProfit

Nieprzeczytany post autor: Kris82 »

Witam serdecznie,

Mam pytanie odnośnie ustawienia TakeProfit, dokładnie rozchodzi mi się o w jaki sposób mogę go ustawić tak aby był na poziomie najwyższego zlecenia.

Przykładowo mam otwarte trzy zlecenia Buy

Pierwsze 1.14320
Drugie 1.50015
Trzecie 1.5256

Moje pytanie jest następujące, w jaki sposób mogę posortować zlecenia i ustawić TakeProfit na poziomie 1.5276 czyli zlecenie trzecie plus 20 pipsów

Dziękuję za wszelką pomoc

-rookie-
Maniak
Maniak
Posty: 2307
Rejestracja: 13 kwie 2015, 19:00

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: -rookie- »

Nie wiem czy ogarniesz ten kod bo sam miałem problem z rozwiązaniem tego problemu, ale to już nie moja sprawa co z tym zrobisz. W skrócie, najpierw musisz sprawdzić w pętli tablice OrdersTotal() i wyodrębnić z tego OrderOpenPrice() następnie przypisać do nowej tablicy te wartości. Ja zrobiłem tablice double arrBuy[10] oraz double arrSell[10] które są jako globalne zmienne na początku kodu. I sprawdza to funkcja test(). I właśnie potem miałem największy problem bo samo sortowanie ArraySort powodowało znikanie indeksów albo wartości z tablicy, sam nie wiem, dlatego w funkcji doSort() na samym początku kopiujesz główne tablice za każdym razem i dopiero te skopiowane tablice sortujesz, czyli najpierw robisz kopie tej tablicy a dopiero na tych kopiach sortowanie. Dzięki temu nie ma błędów. Więc to rozwiązanie powinieneś zastosować w swoim kodzie raczej. To są tablice double _copyBuyArray[] oraz double _copySellArray[] czyli te kopie i potem funkcja doSort() to obrabia. Z tego wyciągasz wartości MathMin oraz MathMax dla Buy i Sell. Jeszcze teraz wróćmy do funkcji test(), ponieważ tam jest wywołanie doSort() oraz obliczenie Take Profit czyli to będą fragmenty gdzie są takie kody double takeprofit0 = NormalizeDouble(max+minstoplevel_TP0*Point,Digits); i potem to jest wysłane w funkcji addTakeProfitForBuy_test2(takeprofit0); która zmienia take profit w OrderModify. Sama funkcja test() jest wstawiona w onTick() czyli każdy tick ją aktualizuje, dlatego pewnie są te problemy z ArraySort() i dopiero skopiowanie tablicy rozwiązuje problem...

Opis wygląda dość skomplikowanie, ale dałem guziki BUY i SELL i wywołałem automatycznie sortowanie przez onTick, zamiast ręcznego naciskania guzika (to było do testów) . Możesz sprawdzić że jeśli będziesz grał zgodnie z trendem i otwierał np SELL to do póki nie otworzysz kolejnego zlecenia niżej TP nie zostanie przesunięty niżej o 20 pipsów od tego zlecenia. https://images92.fotosik.pl/52/b24ab680a880ac5e.png

KOD

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                        EA08102018_moveTpTest.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern int MagicNumber = 100;
extern int Slippage = 3;
extern double LotSize = 0.01;
int counter = 0; // maunual opened order counter

double arrBuy[10] = {}; // default size 10
double arrSell[10] = {}; // default size 10

//double arrTest[] = {1.23234, 1.2357, 1.562, 1.7424, 1.290};

double max = 0;
double min = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

      //_sort(arrTest);
      
      //ArraySort(arrTest);
      //for (int i=0; i<ArraySize(arrTest); i++) {
      //Print( arrTest[i] );
      //}
         
      createBUYButton();
      createSELLButton();
      createCLOSEButton();
      createSortButton();

      createEquityInfoLabel();   
      
      //OrderSend(Symbol(), OP_SELLLIMIT, LotSize, Bid + (100*Point()), Slippage, 0, 0,"Sell[" + 1 +"]", MagicNumber, 0, clrNONE);
      //OrderSend(Symbol(), OP_SELLLIMIT, LotSize, Bid + (200*Point()), Slippage, 0, 0,"Sell[" + 2 +"]", MagicNumber, 0, clrNONE);
      //OrderSend(Symbol(), OP_SELLLIMIT, LotSize, Bid + (300*Point()), Slippage, 0, 0,"Sell[" + 3 +"]", MagicNumber, 0, clrNONE);        
      //OrderSend(Symbol(), OP_BUYLIMIT, LotSize, Ask - (100*Point()), Slippage, 0, 0,"Buy[" + 4 +"]", MagicNumber, 0, clrNONE);
      //OrderSend(Symbol(), OP_BUYLIMIT, LotSize, Ask - (200*Point()), Slippage, 0, 0,"Buy[" + 5 +"]", MagicNumber, 0, clrNONE);
      //OrderSend(Symbol(), OP_BUYLIMIT, LotSize, Ask - (300*Point()), Slippage, 0, 0,"Buy[" + 6 +"]", MagicNumber, 0, clrNONE);  
      
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
      ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
      
      //sortOrderAndChangeTakeProfitForAll();
      
      //if (OrdersTotal() > 0) {
         test();
      //}
      
      if (IsTesting()) {
         if(ObjectGetInteger(ChartID(),"btnBUY",OBJPROP_STATE)==true) {
            sendBuyOrder();
            ObjectSetInteger(ChartID(),"btnBUY",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnSELL",OBJPROP_STATE)==true) {
            sendSellOrder();
            ObjectSetInteger(ChartID(),"btnSELL",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE)==true) {
            manuallyCloseOrder();
            ObjectSetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE,false);
         }
         if (ObjectGetInteger(ChartID(), "btnSort", OBJPROP_STATE)==true) {
            doSort();
            ObjectSetInteger(ChartID(), "btnSort", OBJPROP_STATE, false);
         }
      }
      
  }
//+------------------------------------------------------------------+

//double arrBuy[10] = {}; // default size 10
//double arrSell[10] = {}; // default size 

//double arrTest[10] = {1.23234, 1.2357, 1.562, 1.7424, 1.290};

void test() {
   for(int i=0; i<=OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            ArrayResize(arrBuy, OrdersTotal()+1, 0);
            arrBuy[calcForBuy()] = OrderOpenPrice();
         } else if (OrderType() == 1) {
            ArrayResize(arrSell, OrdersTotal()+1, 0);
            arrSell[calcForSell()] = OrderOpenPrice();
         }
      }
   }
   //.
   
   //ArraySort(arrBuy);  
   
   //for (int o=0; o<ArraySize(arrBuy); o++) {
      //Print( arrBuy[o] );
   //}
   
   //Print( 1 );
   
   //_sort(arrTest);
   
   //for (int o=0; o<ArraySize(arrBuy); o++) {
   //ArraySord(arrBuy);
   //ArraySort(arrBuy,WHOLE_ARRAY,0,MODE_DESCEND);
   //Print( " object " + o + " --> " + arrBuy[o] );
   //Print( ArraySize(arrBuy) + " " + calcForBuy() ); 
   //Print( arrBuy[1] + " " + arrBuy[calcForBuy()] ); 
   //}
   //. 
   //for (int o=0; o<ArraySize(arrSell); o++) {
   //ArraySort(arrSell);
   //ArraySort(arrSell,WHOLE_ARRAY,0,MODE_DESCEND);
   //Print( " object " + o + " --> " + arrSell[o] );
   //Print( ArraySize(arrSell) + " " + calcForSell() ); 
   //Print( arrSell[1] + " " + arrSell[calcForSell()] ); 
   //}
   //
   
   doSort();
   
   //double tp0 = MathMax(arrBuy[1], arrBuy[calcForBuy()]);   
   double minstoplevel_TP0 = MarketInfo(Symbol(),MODE_STOPLEVEL)+20*10;
   double takeprofit0 = NormalizeDouble(max+minstoplevel_TP0*Point,Digits);
   //Print( takeprofit0 > 0.01 );
   if (takeprofit0 > 0.01) {
   addTakeProfitForBuy_test2(takeprofit0);
   }
   
   //double tp1 = MathMax(arrSell[1], arrSell[calcForSell()]);   
   double minstoplevel_TP1 = MarketInfo(Symbol(),MODE_STOPLEVEL)+20*10;
   double takeprofit1 = NormalizeDouble(min-minstoplevel_TP1*Point,Digits);
   if (takeprofit1 > 0.01) {
   addTakeProfitForSell_test2(takeprofit1);
   }
   
   /* Dobre ale jeszcze nie to trzeba bylo zrobic min max jako sortowanie reczne
   double tp0 = MathMax(arrBuy[1], arrBuy[calcForBuy()]);   
   double minstoplevel_TP0 = MarketInfo(Symbol(),MODE_STOPLEVEL)+20*10;
   double takeprofit0 = NormalizeDouble(tp0+minstoplevel_TP0*Point,Digits);
   //addTakeProfitForBuy_test2(takeprofit0);
   
   double tp1 = MathMax(arrSell[1], arrSell[calcForSell()]);   
   double minstoplevel_TP1 = MarketInfo(Symbol(),MODE_STOPLEVEL)+20*10;
   double takeprofit1 = NormalizeDouble(tp1-minstoplevel_TP1*Point,Digits);
   //addTakeProfitForSell_test2(takeprofit1);
   */
   
   /* to też jest dobre ale przesuwa za zleceniem nizej jesli usredniam BUY
   double tp = MathMax(arrBuy[1], arrBuy[calcForBuy()]);   
   double minstoplevel_TP = MarketInfo(Symbol(),MODE_STOPLEVEL)+20*10;
   double takeprofit = NormalizeDouble(tp+minstoplevel_TP*Point,Digits);
   addTakeProfitForSell_test2(takeprofit);
   */
   
   /*
    * to jest dobre, zabezpieczanie zysków na piramidowaniu przez EA po 20 pipsach
    *
   double distance = NormalizeDouble(((MathMin(arrSell[1], arrSell[calcForSell()]) - Bid) * getSymbolScale()), 2);
   
   Print( distance );
   if (distance >= 20) {
      double tp = MathMin(arrSell[1], arrSell[calcForSell()]);   
      //tp = tp - (10*Point());
      //
      double minstoplevel_TP = MarketInfo(Symbol(),MODE_STOPLEVEL)*10;
      double takeprofit = NormalizeDouble(tp-minstoplevel_TP*Point,Digits);
      //Print( "t p " + tp );
      addTakeProfitForSell(takeprofit);
   }
   */
}

/*
 * http://www.java2novice.com/java-sorting-algorithms/bubble-sort/
 */

void _sort(double & arr[]) {
   int n = ArraySize(arr); 
   int k;
   for (int a=n; a>=0; a--) {
      for (int b=0; b<n-1; b++) {
         k = b + 1;
         
         if (arr[b] > arr[k]) {
            _swapNumbers(b,k,arr);
         }
      }
      _printNumbers( arr );
   }
}

void _swapNumbers(int x, int y, double & array[]) {
   int tmp;
   tmp = array[x];
   array[x] = array[y];
   array[y] = tmp;
}

void _printNumbers(double & arr[]) {
   for (int i=0; i<ArraySize(arr); i++) {
      Print( arr[ i ] );
   }
}

int calcForBuy(){int x=0;for(int i=0;i<=OrdersTotal();i++){if(OrderSelect(i,SELECT_BY_POS)==true){if(OrderType()==0){x=x+1;}}}return x;}

int calcForSell(){int x=0;for(int i=0;i<=OrdersTotal();i++){if(OrderSelect(i,SELECT_BY_POS)==true){if(OrderType()==1){x=x+1;}}}return x;}

void addTakeProfitForSell(double sl) {
   for(int i=0; i<OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 1) {      
            if (OrderTakeProfit() == sl) return; 
            //( tp );
            OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(), 0, clrNONE);
            //Print( " tp " + OrderTakeProfit() );
         }
      }
   }
}

void addTakeProfitForBuy_test2(double tp) {
   for(int i=0; i<OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {      
            //if (OrderTakeProfit() == tp) return; 
            //Print( tp );
            //Print( tp );
            if (OrderTakeProfit() != tp) {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
            //Print( " tp " + OrderTakeProfit() );
         }
      }
   }
}

void addTakeProfitForSell_test2(double tp) {
   for(int i=0; i<OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 1) {      
            if (OrderTakeProfit() != tp) {
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
            Print( " tp " + OrderTakeProfit() );
         }
      }
   }
}


/*
double arrBuy[100] = {}; // default size 100
double arrSell[100] = {}; // default size 100

void sortOrderAndChangeTakeProfitForAll() {
   if (OrdersTotal() == 0) return;
   bool getAccessForBuyCalc = false;
   bool blt;
   bool slt;
   //. set
   for(int i=0; i<=OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            ArrayResize(arrBuy, OrdersTotal(), 0);
            //Print( calcForBuy() + " " + ArraySize(arrBuy) );
            arrBuy[calcForBuy()-1] = OrderOpenPrice();
         } else if (OrderType() == 1) {
            ArrayResize(arrSell, OrdersTotal(), 0);
            arrSell[calcForSell()] = OrderOpenPrice();
         }
         //.
         blt = (OrderType() == OP_BUYLIMIT) ? true : false; 
         slt = (OrderType() == OP_SELLLIMIT) ? true : false; 
      }
   }
   //. min buy
   if (!blt) {
      //. test
      for (int o=0; o<ArraySize(arrBuy); o++) {
         Print( " object " + o + " --> " + arrBuy[o] );
         Print( ArraySize(arrBuy) + " " + calcForBuy() ); 
         Print( arrBuy[1] + " " + arrBuy[calcForBuy()] ); 
      }   
      //.
      //Print( arrBuy[1] + " " + arrBuy[calcForBuy()] ); 
      double first = arrBuy[1];
      double last  = arrBuy[calcForBuy()];
      double distance = NormalizeDouble(((Bid - MathMin(first,last)) * getSymbolScale()), 2);
      if (distance <= -20) {
         addTakeProfitForBuy(MathMin(first,last));
      }
   }
   //. max sell
   if (!slt) {
      for (int o=0; o<ArraySize(arrSell); o++) {
         //Print( " object " + o + " --> " + arrSell[o] );
         //Print( ArraySize(arrSell) + " " + calcForSell() ); 
         //Print( arrSell[1] + " " + arrSell[calcForSell()] ); 
      }   
      //.
      //Print( arrSell[1] + " " + arrSell[calcForSell()] ); 
      double first = arrSell[1];
      double last  = arrSell[calcForSell()];
      double distance = NormalizeDouble(((Ask - MathMax(first,last)) * getSymbolScale()), 2);
      if (distance >= 20) {
         addTakeProfitForSell(MathMax(first,last));
      }
   }
}

void addTakeProfitForBuy(double tp) {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {      
            if (OrderTakeProfit() == tp) return; 
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            //Print( " tp " + OrderTakeProfit() );
         }
      }
   }
}

void addTakeProfitForSell(double tp) {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 1) {      
            if (OrderTakeProfit() == tp) return; 
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            //Print( " tp " + OrderTakeProfit() );
         }
      }
   }
}

int calcForBuy() {
   int x = 0;
   for(int i=0; i<=OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            x = x + 1;
         }
      }
   }
   return x;
}

int calcForSell() {
   int x = 0;
   for(int i=0; i<=OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 1) {
            x = x + 1;
         }
      }
   }
   return x;
}
*/

double getSymbolScale() {
   double res = 0;
   if (Point == 0.00001) { // EURUSD, GBPUSD etc
      res = 10000; // ok
   } else if (Point == 0.001) { // USDJPPY etc
      res = 1000; // ?? do sprawdzenia
   } else if (Point == 0.01) { // DAX
      res = 100; // ?? do sprawdzenia
   }
   return res;
}

void createBUYButton() {
   ObjectCreate(ChartID(), "btnBUY", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_XDISTANCE,25);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnBUY",OBJPROP_TEXT,"buy");
}

void createSELLButton() {
   ObjectCreate(ChartID(), "btnSELL", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_XDISTANCE,100);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnSELL",OBJPROP_TEXT,"sell");
}

void createCLOSEButton() {
   ObjectCreate(ChartID(), "btnCLOSE", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_XDISTANCE,65);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_YDISTANCE,80);
   ObjectSetString(ChartID(), "btnCLOSE",OBJPROP_TEXT,"CLOSE");
}

void createSortButton() {
   ObjectCreate(ChartID(), "btnSort", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_XDISTANCE,120);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "btnSort",OBJPROP_TEXT,"Sort");
}

double _copyBuyArray[];
double _copySellArray[];

void doSort() {

   ArrayCopy(_copyBuyArray,arrBuy,0,0,WHOLE_ARRAY);
   ArrayCopy(_copySellArray,arrSell,0,0,WHOLE_ARRAY);
   
   // buy
   ArraySort(_copyBuyArray);   
   for (int o=0; o<ArraySize(_copyBuyArray); o++) {
      Print( o + " " + _copyBuyArray[o] );
   }
   Print( " max " + MathMax(_copyBuyArray[1],_copyBuyArray[ArraySize(_copyBuyArray)-1]));
   Print( " min " + MathMin(_copyBuyArray[1],_copyBuyArray[ArraySize(_copyBuyArray)-1]));
   max = MathMax(_copyBuyArray[1],_copyBuyArray[ArraySize(_copyBuyArray)-1]);
   // sell
   ArraySort(_copySellArray);
   min = MathMin(_copySellArray[1],_copySellArray[ArraySize(_copySellArray)-1]); 
   
   //_sort(arrBuy);
      
   //ArraySort(arrTest);
   //for (int i=0; i<ArraySize(arrBuy); i++) {
   //Print( arrBuy[i] );
   //}
   
}

void sendBuyOrder() {
   OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0,"Buy[" + counter +"]", MagicNumber, 0, clrGreen); 
   counter++;
}

void sendSellOrder() {
   OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0,"Sell[" + counter +"]", MagicNumber, 0, clrRed);
   counter++;
}

void manuallyCloseOrder() {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 0, clrNONE);
         } else if (OrderType() == 1) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 0, clrNONE);
         }
      }
   }
}

void createEquityInfoLabel() {
   ObjectCreate(ChartID(), "equityLabel", OBJ_LABEL, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_XDISTANCE,50);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_FONTSIZE, 14);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_COLOR, clrWhite);
}
Jest w tym kodzie sporo śmieci, sporo kodu jako komentarz, ale wrzucam tak jak jest też dla siebie żebym wiedział z czym się grzebałem i jak próbowałem rozwiązać problem kiedyś tam... Daj ustawienia testu na takie https://images89.fotosik.pl/51/14f44c07d6a3306d.png tempo na 26, włącz pause i wtedy będziesz przesuwał wykres co świece M5 naciskając klawisz F12.

Nie wiem co z tym zrobisz, czy to ogarniesz... ale z góry mówię że dalej nie będę tłumaczył jak nie rozumiesz tego albo nie chce Ci się posprawdzać jak to działa.

Kris82
Stały bywalec
Stały bywalec
Posty: 34
Rejestracja: 11 lip 2012, 00:27

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: Kris82 »

Bardzo dziękuje za szybką i tak dokładną odpowiedz. Zaraz zabieram się za przerabianie Ea.
Jeszcze raz dziękuje i pozdrawiam.

Kris82
Stały bywalec
Stały bywalec
Posty: 34
Rejestracja: 11 lip 2012, 00:27

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: Kris82 »

Faktycznie ciężko było mi to ogarnąć, nawet bym napisał że trącało mi to czarną magią :D
z względu na fakt iż nie jestem programistą, lecz mino wszystko napisałem kodzik który sortuje otwarte pozycje po OrderOpenPrice. Ku mojemu zaskoczeniu musiałem sortować dwa razy po wartości max. Zarówno zlecenia Buy (to oczywiste) ale także i Sell (tu się zdzieliłem) ponieważ i tak uzyskałem najmniejszą cenę.

Wszystko działa jak należy.

Kod: Zaznacz cały

double TablicaK[100] = {};
double TablicaS[100] = {};
 
for(int pos=0; pos<OrdersTotal(); pos++) 
if (OrderSelect(pos, SELECT_BY_POS))
{  
   if (OrderType()==OP_BUY)
   {
   TablicaK[pos]=OrderOpenPrice();
   ArrayResize(TablicaK, OrdersTotal()+1,0);
   int maxValueIdx = ArrayMaximum(TablicaK);
   Print( "Maksymalna wartość w tablicy to =", TablicaK[maxValueIdx]);
   }
   if (OrderType()==OP_SELL)
   {
   TablicaK[pos]=OrderOpenPrice();
   ArrayResize(TablicaS, OrdersTotal()+1,0);
   int minValueIdx = ArrayMaximum(TablicaS);
   Print( "Minimalna wartość w tablicy to =", TablicaK[minValueIdx]);
   } 
}   

-rookie-
Maniak
Maniak
Posty: 2307
Rejestracja: 13 kwie 2015, 19:00

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: -rookie- »

Nie wiedziałem o tym że jest taka funkcja ArrayMaximum. Rzeczywiście działa to jak trzeba. Ok, więc kod z tą funkcją będzie wyglądał tak. Działa to jak ten wyżej że bierze wartość najwyższą dla buy oraz najniższą dla sell. Jeśli wstawisz zlecenie pomiędzy tym ostatnim zleceniem a obecnym TP wtedy dla tego nowego zlecenia weźmie wartość i przesunie o 20 w stosunku do niego. Jeśli nie będzie kolejnego zlecenia wyżej / niżej zrealizuje TP. Twój kod jest w funkcji sort() i to jest wywołane w onTick(). Reszta to skopiowane z tego wyżej razem z guzikami żeby na testerze sprawdzić co i jak.

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                           12102018_EA_TPmove.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

double min = 0;
double max = 0;

// test
extern int MagicNumber = 100;
extern int Slippage = 3;
extern double LotSize = 0.01;
int counter = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

      createBUYButton();
      createSELLButton();
      createCLOSEButton();
      createSortButton();

      createEquityInfoLabel();
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

      updateActionForButtons();
      
      sort();

      double _max_d = MarketInfo(Symbol(), MODE_STOPLEVEL) + 20 * 10;
      double tpMax = NormalizeDouble(max + _max_d * Point, Digits);
      
      Print( max + " " + _max_d );
      
      //if (tpMax > 0.01) {
      addTakeProfitForBuy(tpMax);
      //}
      
      double _min_d = MarketInfo(Symbol(), MODE_STOPLEVEL) + 20 * 10;
      double tpMin = NormalizeDouble(min - _min_d * Point, Digits);
      //if (tpMin > 0.01) {
      addTakeProfitForSell(tpMin);
      //}
   
  }
//+------------------------------------------------------------------+

double TablicaK[100] = {};
double TablicaS[100] = {};

void sort() {    
    for(int pos=0; pos<OrdersTotal(); pos++)
    if (OrderSelect(pos, SELECT_BY_POS))
    { 
       if (OrderType()==OP_BUY)
       {
       TablicaK[pos]=OrderOpenPrice();
       ArrayResize(TablicaK, OrdersTotal()+1,0);
       int maxValueIdx = ArrayMaximum(TablicaK);
       Print( "Maksymalna wartość w tablicy to =", TablicaK[maxValueIdx]);
       max = TablicaK[maxValueIdx];
       Print( " test " + maxValueIdx + " " + TablicaK[maxValueIdx] );
       }
       if (OrderType()==OP_SELL)
       {
       TablicaK[pos]=OrderOpenPrice();
       ArrayResize(TablicaS, OrdersTotal()+1,0);
       int minValueIdx = ArrayMaximum(TablicaS);
       Print( "Minimalna wartość w tablicy to =", TablicaK[minValueIdx]);
       min = TablicaK[minValueIdx];
       }
    }   
}

void addTakeProfitForBuy(double tp) {
   for(int i=0; i<OrdersTotal(); i++) 
   {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if (OrderType() == 0) {      
            if (OrderTakeProfit() != tp) {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
         }
      }
   }
}

void addTakeProfitForSell(double tp) {
   for(int i=0; i<OrdersTotal(); i++) 
   {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if (OrderType() == 1) {      
            if (OrderTakeProfit() != tp) {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
         }
      }
   }
}

/*
 * 4 TEST
 */
void updateActionForButtons() {
   ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
   
      if (IsTesting()) {
         if(ObjectGetInteger(ChartID(),"btnBUY",OBJPROP_STATE)==true) {
            sendBuyOrder();
            ObjectSetInteger(ChartID(),"btnBUY",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnSELL",OBJPROP_STATE)==true) {
            sendSellOrder();
            ObjectSetInteger(ChartID(),"btnSELL",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE)==true) {
            manuallyCloseOrder();
            ObjectSetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE,false);
         }
         if (ObjectGetInteger(ChartID(), "btnSort", OBJPROP_STATE)==true) {
            sort();
            ObjectSetInteger(ChartID(), "btnSort", OBJPROP_STATE, false);
         }
      }
}

void createBUYButton() {
   ObjectCreate(ChartID(), "btnBUY", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_XDISTANCE,25);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnBUY",OBJPROP_TEXT,"buy");
}

void createSELLButton() {
   ObjectCreate(ChartID(), "btnSELL", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_XDISTANCE,100);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnSELL",OBJPROP_TEXT,"sell");
}

void createCLOSEButton() {
   ObjectCreate(ChartID(), "btnCLOSE", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_XDISTANCE,65);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_YDISTANCE,80);
   ObjectSetString(ChartID(), "btnCLOSE",OBJPROP_TEXT,"CLOSE");
}

void createSortButton() {
   ObjectCreate(ChartID(), "btnSort", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_XDISTANCE,120);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "btnSort",OBJPROP_TEXT,"Sort");
}

void createEquityInfoLabel() {
   ObjectCreate(ChartID(), "equityLabel", OBJ_LABEL, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_XDISTANCE,50);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_FONTSIZE, 14);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_COLOR, clrWhite);
}

void sendBuyOrder() {
   OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0,"Buy[" + counter +"]", MagicNumber, 0, clrGreen); 
   counter++;
}

void sendSellOrder() {
   OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0,"Sell[" + counter +"]", MagicNumber, 0, clrRed);
   counter++;
}

void manuallyCloseOrder() {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 0, clrNONE);
         } else if (OrderType() == 1) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 0, clrNONE);
         }
      }
   }
}
btw. Dzięki za info. z tym ArrayMaximum.

Kris82
Stały bywalec
Stały bywalec
Posty: 34
Rejestracja: 11 lip 2012, 00:27

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: Kris82 »

Dla mnie bomba, dziękuje za kod. Cała przyjemność po mojej strony że w jakiś sposób mogłem pomóc.
Jeszcze raz dziękuję i życzę udanego handlu :D

-rookie-
Maniak
Maniak
Posty: 2307
Rejestracja: 13 kwie 2015, 19:00

Re: Ustawienie TakeProfit

Nieprzeczytany post autor: -rookie- »

Tylko chyba coś jest nie tak, bo na BUY dobrze otwiera ale dla SELL nie liczy dolnej wartości, były źle tablice podstawione, zamiast do S zapisywało do K. To jeszcze tutaj poprawione. Ale dalej jest coś nie tak chyba jeszcze bo przy otwartych zleceniach w obie strony dla Buy przesuwa TP wyżej jak dokładam kolejne pozycje a dla Sell już nie aktualizuje niżej TP. No ale, jest lekko poprawione w tym kodzie Kris82 te tablice do zapisywania min i max

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                           12102018_EA_TPmove.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

double min = 0;
double max = 0;

// test
extern int MagicNumber = 100;
extern int Slippage = 3;
extern double LotSize = 0.01;
int counter = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

      createBUYButton();
      createSELLButton();
      createCLOSEButton();
      createSortButton();

      createEquityInfoLabel();
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

      updateActionForButtons();
     
      sort();

      double _max_d = MarketInfo(Symbol(), MODE_STOPLEVEL) + 20 * 10;
      double tpMax = NormalizeDouble(max + _max_d * Point, Digits);
     
      //Print( max + " " + _max_d );
     
      //if (tpMax > 0.01) {
      addTakeProfitForBuy(tpMax);
      //}
     
      double _min_d = MarketInfo(Symbol(), MODE_STOPLEVEL) + 20 * 10;
      double tpMin = NormalizeDouble(min -_min_d * Point, Digits);
      //Print( " 2222 " + tpMin + " " + min );
      //if (tpMin > 0.01) {
      addTakeProfitForSell(tpMin);
      //}
   
  }
//+------------------------------------------------------------------+

double TablicaK[100] = {};
double TablicaS[100] = {};

void sort() {   
    for(int pos=0; pos<OrdersTotal(); pos++)
    if (OrderSelect(pos, SELECT_BY_POS))
    {
       if (OrderType()==OP_BUY)
       {
       TablicaK[pos]=OrderOpenPrice();
       ArrayResize(TablicaK, OrdersTotal(),0);
       int maxValueIdx = ArrayMaximum(TablicaK);
       Print( "Maksymalna wartość w tablicy to =", TablicaK[maxValueIdx]);
       max = TablicaK[maxValueIdx];
       Print( " test " + maxValueIdx + " " + TablicaK[maxValueIdx] );
       }
       if (OrderType()==OP_SELL)
       {
       /*
       TablicaK[pos]=OrderOpenPrice();
       ArrayResize(TablicaS, OrdersTotal()+1,0);
       int minValueIdx = ArrayMaximum(TablicaS);
       Print( "Minimalna wartość w tablicy to =", TablicaK[minValueIdx]);
       min = TablicaK[minValueIdx];
       */
       TablicaS[pos]=OrderOpenPrice();
       ArrayResize(TablicaS, OrdersTotal(),0);
       int minValueIdx = ArrayMinimum(TablicaS);
       Print( "Minimalna wartość w tablicy to =", TablicaS[minValueIdx]);
       Print( " test " + minValueIdx + " " + TablicaS[minValueIdx] );
       min = TablicaS[minValueIdx];
       }
    }   
}

void addTakeProfitForBuy(double tp) {
   for(int i=0; i<OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if (OrderType() == 0) {     
            if (OrderTakeProfit() != tp) {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
         }
      }
   }
}

void addTakeProfitForSell(double tp) {
   for(int i=0; i<OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if (OrderType() == 1) {     
            if (OrderTakeProfit() != tp) {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp, 0, clrNONE);
            }
         }
      }
   }
}

/*
 * 4 TEST
 */
void updateActionForButtons() {
   ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
   
      if (IsTesting()) {
         if(ObjectGetInteger(ChartID(),"btnBUY",OBJPROP_STATE)==true) {
            sendBuyOrder();
            ObjectSetInteger(ChartID(),"btnBUY",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnSELL",OBJPROP_STATE)==true) {
            sendSellOrder();
            ObjectSetInteger(ChartID(),"btnSELL",OBJPROP_STATE,false);
         }
         if(ObjectGetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE)==true) {
            manuallyCloseOrder();
            ObjectSetInteger(ChartID(),"btnCLOSE",OBJPROP_STATE,false);
         }
         if (ObjectGetInteger(ChartID(), "btnSort", OBJPROP_STATE)==true) {
            sort();
            ObjectSetInteger(ChartID(), "btnSort", OBJPROP_STATE, false);
         }
      }
}

void createBUYButton() {
   ObjectCreate(ChartID(), "btnBUY", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_XDISTANCE,25);
   ObjectSetInteger(ChartID(), "btnBUY",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnBUY",OBJPROP_TEXT,"buy");
}

void createSELLButton() {
   ObjectCreate(ChartID(), "btnSELL", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_XDISTANCE,100);
   ObjectSetInteger(ChartID(), "btnSELL",OBJPROP_YDISTANCE,50);
   ObjectSetString(ChartID(), "btnSELL",OBJPROP_TEXT,"sell");
}

void createCLOSEButton() {
   ObjectCreate(ChartID(), "btnCLOSE", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_XDISTANCE,65);
   ObjectSetInteger(ChartID(), "btnCLOSE",OBJPROP_YDISTANCE,80);
   ObjectSetString(ChartID(), "btnCLOSE",OBJPROP_TEXT,"CLOSE");
}

void createSortButton() {
   ObjectCreate(ChartID(), "btnSort", OBJ_BUTTON, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_XDISTANCE,120);
   ObjectSetInteger(ChartID(), "btnSort",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "btnSort",OBJPROP_TEXT,"Sort");
}

void createEquityInfoLabel() {
   ObjectCreate(ChartID(), "equityLabel", OBJ_LABEL, 0 ,0, 0);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_XDISTANCE,50);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_YDISTANCE,120);
   ObjectSetString(ChartID(), "equityLabel",OBJPROP_TEXT, DoubleToStr(AccountEquity(),2));
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_FONTSIZE, 14);
   ObjectSetInteger(ChartID(), "equityLabel",OBJPROP_COLOR, clrWhite);
}

void sendBuyOrder() {
   OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, 0, 0,"Buy[" + counter +"]", MagicNumber, 0, clrGreen);
   counter++;
}

void sendSellOrder() {
   OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, 0, 0,"Sell[" + counter +"]", MagicNumber, 0, clrRed);
   counter++;
}

void manuallyCloseOrder() {
   for(int i=OrdersTotal(); i>=0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)==true) {
         if (OrderType() == 0) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 0, clrNONE);
         } else if (OrderType() == 1) {
            OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 0, clrNONE);
         }
      }
   }
}

ODPOWIEDZ