Hi, Dear Coders
Edited: the core question is how to manually move a line freely like takeprofit stoploss lines in MT4. This line is already generated by my EA.
I am desperately seeking for your help. But the issue may be incredibly simple to you.
In my EA, I need to drag an existing horizontal line to a new level X, and the new level X may be taken by the EA for later use. I also need the line staying at the new level X.
In my attached code, the 'UpdateDragAlertLvL()' is the sub that i used to spot the dragging and taking the new level X.
In the code, I try to use var <DragLonglvl> to contain 'X', and object <LongTickets[0] + " L-APL"> is the existing line to be dragged.
I used ObjectSet, and ObjectDelete/Create for new level 'X', but when EA really runs, I simply cannot make the line stay at the new level X, the line will always jump back to its previous level. The EA won't take the new level 'X' value too.
Truly appreciate if you can help me on this issue, either a tip, or a sample code will be wonderful. I guess my way to capture a drag is first thing going wrong.
the EA's purpose is for a trader to set a level (horizontal line) at <AlertLvL4LONG>, if price reaches that level, the EA will do a BE for the existing long positions. What I need is the ability to directly move that horizontal line instead of input the values everytime. The logic is very simple.
Edited: the core question is how to manually move a line freely like takeprofit stoploss lines in MT4. This line is already generated by my EA.
I am desperately seeking for your help. But the issue may be incredibly simple to you.
In my EA, I need to drag an existing horizontal line to a new level X, and the new level X may be taken by the EA for later use. I also need the line staying at the new level X.
In my attached code, the 'UpdateDragAlertLvL()' is the sub that i used to spot the dragging and taking the new level X.
In the code, I try to use var <DragLonglvl> to contain 'X', and object <LongTickets[0] + " L-APL"> is the existing line to be dragged.
I used ObjectSet, and ObjectDelete/Create for new level 'X', but when EA really runs, I simply cannot make the line stay at the new level X, the line will always jump back to its previous level. The EA won't take the new level 'X' value too.
Truly appreciate if you can help me on this issue, either a tip, or a sample code will be wonderful. I guess my way to capture a drag is first thing going wrong.
the EA's purpose is for a trader to set a level (horizontal line) at <AlertLvL4LONG>, if price reaches that level, the EA will do a BE for the existing long positions. What I need is the ability to directly move that horizontal line instead of input the values everytime. The logic is very simple.
Inserted Code
extern double AlertLvL4LONG = 0; extern double AlertLvL4SHOT = 10000; extern double deftTP = 0; extern double deftSL = 0; extern int BEoffset = 2; extern string SpecRstring = "1,2,3,5,8,13,21,34,55, 90,160,250"; // after base level, 12 additional levels! extern string SpecTPstring = "1,1,2,2,3, 3, 4, 5, 7, 9, 12, 15"; extern string OrderCMT = ""; extern int Slippage = 2; extern int SpreadCap = 10; extern string ClearanceNote = "must larger than BEoffset"; extern int Clearance = 10; extern int ScreenCorner = 1; extern bool UsePresetAlert = false; extern int MagicBase = 100; extern string UserNote = "Support MAX 6 Positions"; //+------------------------------------------------------------------+ //| Internal Variables | //+------------------------------------------------------------------+ int MagicNumber, i, pairdigits, NumBuys, NumSels, TotalTrades, StartPos, EnteringDIR; double pairpoint, baseBuyAt, baseSelAt, HiBound, LoBound, allBuyLots, allSelLots, UseLots, NetExposure; double EAPL, DDpeak, EQpeak, BuyPL, SelPL, TPgoal; double LongAPL = 0; //{0,0,0,0,0,0}; double ShotAPL = 0; //{0,0,0,0,0,0}; int LongTickets[] = {0,0,0,0,0,0}; int ShotTickets[] = {0,0,0,0,0,0}; double BuyPosTP, BuyPosSL, SelPosTP, SelPosSL; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ int init() { //MagicNumber = GetMagic4(Symbol()); //Alert(WindowExpertName() +" price is " + EnteringDIR); //FreeRunner() if ( Digits == 3 || Digits == 5 ) { Slippage = Slippage*10; SpreadCap = SpreadCap*10; } pairdigits = MarketInfo(Symbol(), MODE_DIGITS); // pairpoint is traditional pip from 2 or 4 digits pairs. if (pairdigits < 4) pairpoint = 0.01; else pairpoint = 0.0001; if (Symbol() == "XAUUSD") { Slippage = 1; SpreadCap = 1; pairpoint = 0.1; } LongAPL = AlertLvL4LONG; ShotAPL = AlertLvL4SHOT; Alert(WindowExpertName() + " init LongAPL is " + LongAPL); return (0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ int start() { Count_Pos_Lots(); //Alert(WindowExpertName() + "1 LongAPL is " + LongAPL); NoPosReset(); //Alert(WindowExpertName() + "2 LongAPL is " + LongAPL); CheckAPL(); //Alert(WindowExpertName() + "3 LongAPL is " + LongAPL); PrintChartComments(); //Alert(WindowExpertName() + "4 LongAPL is " + LongAPL); UpdateDragAlertLvL(); //Alert(WindowExpertName() + "5 LongAPL is " + LongAPL); return(0); } //+------------------------------------------------------------------+ // Start() finish. All supporting routines FromBelow. //+------------------------------------------------------------------+ void Count_Pos_Lots() { NumBuys = 0; BuyPL = 0.0; allBuyLots = 0.0; NumSels = 0; SelPL = 0.0; allSelLots = 0.0; BuyPosTP = 0; BuyPosSL = 0; SelPosTP = 0; SelPosSL = 0; int m = 0; int n = 0; for (i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol() && OrderType() == OP_BUY && OrderComment() == OrderCMT ) { BuyPL += OrderProfit() + OrderSwap() + OrderCommission(); allBuyLots += OrderLots(); NumBuys++; BuyPosTP = OrderTakeProfit(); BuyPosSL = OrderStopLoss(); LongTickets[m] = OrderTicket(); m = m + 1; ObjectDelete(LongTickets[m-1] + " L-APL"); if (ObjectCreate(LongTickets[m-1] + " L-APL", OBJ_HLINE, 0, 0, LongAPL)) { ObjectSet(LongTickets[m-1] + " L-APL", OBJPROP_STYLE, STYLE_DASHDOT); ObjectSet(LongTickets[m-1] + " L-APL", OBJPROP_BACK, True); ObjectSet(LongTickets[m-1] + " L-APL", OBJPROP_COLOR, Lime); ObjectSet(LongTickets[m-1] + " L-APL", OBJPROP_WIDTH, 1); } else Alert(WindowExpertName() + " Fail to draw LAPL " ); } if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && OrderComment() == OrderCMT) { SelPL += OrderProfit() + OrderSwap() + OrderCommission(); allSelLots += OrderLots(); NumSels++; SelPosTP = OrderTakeProfit(); SelPosSL = OrderStopLoss(); ShotTickets[n] = OrderTicket(); n = n + 1; ObjectDelete(ShotTickets[n-1] + " S-APL"); if(ObjectCreate(ShotTickets[n-1] + " S-APL", OBJ_HLINE, 0, 0, ShotAPL)) { ObjectSet(ShotTickets[n-1] + " S-APL", OBJPROP_STYLE, STYLE_DASHDOT); ObjectSet(ShotTickets[n-1] + " S-APL", OBJPROP_BACK, True); ObjectSet(ShotTickets[n-1] + " S-APL", OBJPROP_COLOR, Red); ObjectSet(ShotTickets[n-1] + " S-APL", OBJPROP_WIDTH, 1); } else Alert(WindowExpertName() + " Fail to draw SAPL " ); } } NetExposure = MathAbs(allSelLots - allBuyLots); TotalTrades = NumBuys + NumSels; return(0); } void CheckAPL() // this sub examine if NOW is good time to start a trading sequence. { for (i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if ( OrderType() == OP_BUY && MarketInfo(Symbol(), MODE_BID) < LongAPL && OrderComment() == OrderCMT ) { //Alert(WindowExpertName() + "CHCK LongAPL is " + LongAPL); //Alert(WindowExpertName() + "CHCK Bid is " + MarketInfo(Symbol(), MODE_BID)); JumpTP(); } if ( OrderType() == OP_SELL && MarketInfo(Symbol(), MODE_BID) > ShotAPL && OrderComment() == OrderCMT ) { JumpTP(); } } } void JumpTP() { bool BE; for(int n=0; n<OrdersTotal();n++) { OrderSelect(n, SELECT_BY_POS, MODE_TRADES); if (OrderComment() == OrderCMT && OrderSymbol()==Symbol()) { if ( OrderType() == OP_BUY && (OrderTakeProfit() > (OrderOpenPrice() + Clearance * pairpoint) || OrderTakeProfit() == 0) ) { BE = OrderModify(OrderTicket(),OrderOpenPrice(),0, NormalizeDouble(OrderOpenPrice()+BEoffset*pairpoint, MarketInfo(Symbol(), MODE_DIGITS)), 0,Green); if (BE) { Alert(WindowExpertName() + " BE a " + Symbol() + " pos, @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES)); Print(WindowExpertName() + " BE a " + Symbol() + " pos, @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES)); } else { Alert(WindowExpertName() + " Failed to BE a " + Symbol() + " @ " + OrderOpenPrice() + ", @" + TimeToStr(TimeCurrent(),TIME_MINUTES) + " due to error " + GetLastError()); Print(WindowExpertName() + " Failed to BE a " + Symbol() + " @ " + OrderOpenPrice() + ", @" + TimeToStr(TimeCurrent(),TIME_MINUTES) + " due to error " + GetLastError()); } } if ( OrderType() == OP_SELL && (OrderTakeProfit() < (OrderOpenPrice() - Clearance * pairpoint) || OrderTakeProfit() == 0) ) { BE = OrderModify(OrderTicket(),OrderOpenPrice(),0,NormalizeDouble(OrderOpenPrice()-BEoffset*pairpoint, MarketInfo(Symbol(), MODE_DIGITS)), 0,Green); if (BE) { Alert(WindowExpertName() + " BE a " + Symbol() + " pos, @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES)); Print(WindowExpertName() + " BE a " + Symbol() + " pos, @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES)); } else { Alert(WindowExpertName() + " Failed to BE a " + Symbol() + " @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES) + " due to error " + GetLastError()); Print(WindowExpertName() + " Failed to BE a " + Symbol() + " @ " + OrderOpenPrice() + ", @ " + TimeToStr(TimeCurrent(),TIME_MINUTES) + " due to error " + GetLastError()); } } } } } void NoPosReset() // if no positions, but variables are used (after exiting a previous pos), reinit arrays, delete existing lines { if (ArraySize(LongTickets) > 0 && NumBuys == 0) { for (int i = ArraySize(LongTickets)-1;i>0;i--) { ObjectDelete(LongTickets[i-1] + " L-APL"); } ArrayResize(LongTickets,0); } if (ArraySize(ShotTickets) > 0 && NumSels == 0) { for (i = ArraySize(ShotTickets)-1;i>0;i--) { ObjectDelete(ShotTickets[i-1] + " S-APL"); } ArrayResize(ShotTickets, 0); } return(0); } void UpdateDragAlertLvL() { double DragLonglvl, DragShotlvl; if (NumBuys > 0) { for(int i=ArraySize(LongTickets)-1;i>0;i--) { OrderSelect(LongTickets[i],SELECT_BY_TICKET); if (OrderSymbol() == Symbol() && OrderType() == OP_BUY && OrderComment() == OrderCMT ) { DragLonglvl = NormalizeDouble(ObjectGet(LongTickets[i]+"-LONGapl",OBJPROP_PRICE1),MarketInfo(Symbol(), MODE_DIGITS)); if(DragLonglvl != LongAPL) { //ObjectDelete(LongTickets[0] + " L-APL"); //ObjectCreate(LongTickets[0] + " L-APL", OBJ_HLINE, 0, 0, DragLonglvl); ObjectSet(LongTickets[0] + " L-APL", OBJPROP_PRICE1, DragLonglvl); LongAPL = DragLonglvl; } } } } if (NumSels > 0) { for (i=ArraySize(ShotTickets)-1;i>0;i--) { OrderSelect(ShotTickets[i],SELECT_BY_TICKET); if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && OrderComment() == OrderCMT ) { DragShotlvl = NormalizeDouble(ObjectGet(ShotTickets[i]+"-SHOTapl",OBJPROP_PRICE1),MarketInfo(Symbol(), MODE_DIGITS)); if(DragShotlvl != ShotAPL) ShotAPL = DragShotlvl; } } } return(0); } void PrintChartComments() { string commentStr; int PipDist2Long, PipDist2Short; if (LongAPL > 0) PipDist2Long = (-LongAPL + MarketInfo(Symbol(), MODE_BID))/pairpoint; if (ShotAPL > 0) PipDist2Short = (ShotAPL - MarketInfo(Symbol(), MODE_BID))/pairpoint; commentStr = Symbol() + "L: Lot: " + DoubleToStr(allBuyLots,2) + "; APL: " + DoubleToStr(LongAPL, MarketInfo(Symbol(), MODE_DIGITS)) + "; from Bid: " + PipDist2Long + "; TP: " + DoubleToStr(BuyPosTP,MarketInfo(Symbol(), MODE_DIGITS)) + ";"; if (NumBuys > 0) printComment_l(commentStr, 2, 40, 1); commentStr = Symbol() + "S: Lot: " + DoubleToStr(allSelLots,2) + "; APL: " + DoubleToStr(ShotAPL, MarketInfo(Symbol(), MODE_DIGITS)) + "; from Bid: " + PipDist2Short + "; TP: " + DoubleToStr(SelPosTP,MarketInfo(Symbol(), MODE_DIGITS)) + ";"; if (NumSels > 0) printComment_l(commentStr, 3, 65, 3); } void printComment_l(string commentStr, int i, int j, int colorcode) { ObjectCreate("TradeComment"+i,OBJ_LABEL,0,0,0); ObjectSet("TradeComment"+i,OBJPROP_CORNER,ScreenCorner); ObjectSet("TradeComment"+i,OBJPROP_XDISTANCE,5); ObjectSet("TradeComment"+i,OBJPROP_YDISTANCE,j); if (colorcode == 1) ObjectSetText("TradeComment"+i,commentStr,12,"Courier New Bold",Lime); if (colorcode == 2) ObjectSetText("TradeComment"+i,commentStr,12,"Courier New Bold",DeepSkyBlue); if (colorcode == 3) ObjectSetText("TradeComment"+i,commentStr,12,"Courier New Bold",DeepPink); }