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
Ustawienie TakeProfit
Re: Ustawienie TakeProfit
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
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.
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);
}
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.
Re: Ustawienie TakeProfit
Bardzo dziękuje za szybką i tak dokładną odpowiedz. Zaraz zabieram się za przerabianie Ea.
Jeszcze raz dziękuje i pozdrawiam.
Jeszcze raz dziękuje i pozdrawiam.
Re: Ustawienie TakeProfit
Faktycznie ciężko było mi to ogarnąć, nawet bym napisał że trącało mi to czarną magią
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.
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]);
}
}
Re: Ustawienie TakeProfit
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.
btw. Dzięki za info. z tym ArrayMaximum.
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);
}
}
}
}
Re: Ustawienie TakeProfit
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
Jeszcze raz dziękuję i życzę udanego handlu
Re: Ustawienie TakeProfit
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);
}
}
}
}