|
Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4. |
|
Themen-Optionen | Thema durchsuchen | Ansicht |
|
|||
Keine Order setzen wenn letzter trade Buy/Sell
Hallo Forengemeinde,
Ich habe eine Frage zu einem Befehl, den ich in meinen Expert Advisor einbauen will. Ich möchte dass mein Expert Advisor keine neue Buy Order setzt, wenn die letzte Order bereits eine Buy Order war und genau dasselbe mit den Sell Positionen. Also sowas wie: if (LastOrder == OP_BUY && tu>0.000000001 && tu<9999999 && LastOrder != 1) {NO NEW ORDER SEND} habt ihr eine Idee, wie man das Programmieren könnte ? Gruss akuh |
|
|||
Hi, so kann es gehen :
------------------------------------------------------------------ #include <stdlib.mqh> #include <WinUser32.mqh> // exported variables extern double BuyLots6 = 0.1; extern int BuyStoploss6 = 20; extern int BuyTakeprofit6 = 30; extern double SellLots7 = 0.1; extern int SellStoploss7 = 20; extern int SellTakeprofit7 = 30; // local variables double PipValue=1; // this variable is here to support 5-digit brokers bool Terminated = false; string LF = "\n"; // use this in custom or utility blocks where you need line feeds int NDigits = 4; // used mostly for NormalizeDouble in Flex type blocks int ObjCount = 0; // count of all objects created on the chart, allows creation of objects with unique names int current = 0; // current bar index, used by Cross Up, Cross Down and many other blocks int varylots[101]; // used by Buy Order Varying, Sell Order Varying and similar bool FirstTime2 = true; bool FirstTime4 = true; int init() { NDigits = Digits; if (false) ObjectsDeleteAll(); // clear the chart Comment(""); // clear the chart return (0); } // Expert start int start() { if (Bars < 10) { Comment("Not enough bars"); return (0); } if (Terminated == true) { Comment("EA Terminated."); return (0); } OnEveryTick1(); return (0); } void OnEveryTick1() { PipValue = 1; if (NDigits == 3 || NDigits == 5) PipValue = 10; CheckLastOrderType2(); CheckLastOrderType4(); } void CheckLastOrderType2() { int orderType = -1; int orderId = -1; datetime lastCloseTime = 0; int cnt = OrdersHistoryTotal(); for (int i=0; i < cnt; i++) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol() == Symbol() && lastCloseTime < OrderCloseTime() && orderId == 1) { lastCloseTime = OrderCloseTime(); orderType = OrderType(); orderId = OrderMagicNumber(); } } if (orderType == OP_SELL || FirstTime2) { FirstTime2 = false; BuyOrder6(); } } void BuyOrder6() { double SL = Ask - BuyStoploss6*PipValue*Point; if (BuyStoploss6 == 0) SL = 0; double TP = Ask + BuyTakeprofit6*PipValue*Point; if (BuyTakeprofit6 == 0) TP = 0; int ticket = -1; if (true) ticket = OrderSend(Symbol(), OP_BUY, BuyLots6, Ask, 4, 0, 0, "My Expert", 1, 0, Blue); else ticket = OrderSend(Symbol(), OP_BUY, BuyLots6, Ask, 4, SL, TP, "My Expert", 1, 0, Blue); if (ticket > -1) { if (true) { bool sel = OrderSelect(ticket, SELECT_BY_TICKET); bool ret = OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, Blue); if (ret == false) Print("OrderModify() error - ", ErrorDescription(GetLastError())); } } else { Print("OrderSend() error - ", ErrorDescription(GetLastError())); } } void CheckLastOrderType4() { int orderType = -1; int orderId = -1; datetime lastCloseTime = 0; int cnt = OrdersHistoryTotal(); for (int i=0; i < cnt; i++) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol() == Symbol() && lastCloseTime < OrderCloseTime() && orderId == 1) { lastCloseTime = OrderCloseTime(); orderType = OrderType(); orderId = OrderMagicNumber(); } } if (orderType == OP_BUY || FirstTime4) { FirstTime4 = false; SellOrder7(); } } void SellOrder7() { double SL = Bid + SellStoploss7*PipValue*Point; if (SellStoploss7 == 0) SL = 0; double TP = Bid - SellTakeprofit7*PipValue*Point; if (SellTakeprofit7 == 0) TP = 0; int ticket = -1; if (true) ticket = OrderSend(Symbol(), OP_SELL, SellLots7, Bid, 4, 0, 0, "My Expert", 1, 0, Red); else ticket = OrderSend(Symbol(), OP_SELL, SellLots7, Bid, 4, SL, TP, "My Expert", 1, 0, Red); if (ticket > -1) { if (true) { bool sel = OrderSelect(ticket, SELECT_BY_TICKET); bool ret = OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, Red); if (ret == false) Print("OrderModify() error - ", ErrorDescription(GetLastError())); } } else { Print("OrderSend() error - ", ErrorDescription(GetLastError())); } } int deinit() { if (false) ObjectsDeleteAll(); return (0); } ------------------------------------------------------------------ PS Code kommt aus meinem Generator. |
|
|||
Das geht ganz einfach über wenige Zeilen:
Code:
int CheckOrder() { for (int i = OrdersHistoryTotal()-1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber){ if (OrderType() == 0 || OrderType() == 1) return(OrderType()); } } return(-1); } Wenn keine MagicNumber vergeben wird, dann einfach die letzte Abfrage in Zeile 4 löschen. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Ich sehe zwischen Deiner bzw. den Generator-Funktionen keine großen Unterschiede. Die Generator-Funktion hat den Vorteil, dass man keine weiteren if/bool-Konditionen braucht, und man kann (weil es ja ein kompletter EA ist) auch problemlos testen. Ich hatte gedacht, das ist vielleicht etwas Anwender-freundlich :-)
|
|
|||
Zitat:
Gut, dann möchte ich Dir den gern aufzeigen: Mal abgesehen vom Schreibstil des Codes, der bei Dir extrem schwer zu lesen ist. Ich habe den mal aufgearbeitet, dann sieht man es auch besser. Code:
void CheckLastOrderType2() { int orderType = -1; int orderId = -1; datetime lastCloseTime = 0; int cnt = OrdersHistoryTotal(); for (int i = 0; i < cnt; i++) //8 { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol() == Symbol() && lastCloseTime < OrderCloseTime() && orderId == 1) //11 { lastCloseTime = OrderCloseTime(); //13 orderType = OrderType(); //14 orderId = OrderMagicNumber(); //15 } } if (orderType == OP_SELL || FirstTime2) //18 { FirstTime2 = false; //20 BuyOrder6(); //21 } } 1. In Zeile 8 wird die Historie vom Urschleim bis zur aktuell geschlossenen Order durchforstet. Das kostet ewig Zeit und ist unnötig, denn er wollte nur die letzte geschlossene Order haben und die liegt am Ende der OrdersHistory() und nicht am Anfang und daher for (int i = OrdersHistoryTotal()-1; i >= 0; i--) { 2. In Zeile 11 fehlt eigentlich die Abfrage nach der MagicNumber, sofern nicht auf eine expilizite Vergabe der MagicNumber verzichtet wird, also if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { 3. Und was soll das orderId == 1 eigentlich bewirken, außer dass der darunterstehende Klammerausdruck mit Zeile 13, 14 und 15 nie angesprungen wird, weil per se in der Funktionsdeklaration int orderID = -1 gesetzt wurde. 4. Damit bleibe auch lastCloseTime auf dem initialisierten Wert von 0 stehen, aber das würde dann eh keine Rolle mehr spielen, weil die Übergabe in Zeile 13 ja nicht angesprungen wird usw. usf. Was passiert nun wirklich in diesem Teil des EAs: 1. Der EA nimmt sich die Order mit der historischen Listennummer 0 2. Zeile 11 ergibt false, s.o. 3. Damit wird Zeile 13, 14 und 15 nicht angesprungen 4. Die for-Schleife rattert alls geschlossenen Orders durch - nix passiert 5. Nach Abschluß der for-Schleife wird geprüft, ob orderType == OP_SELL, also den Wert 1 hat, kann orderType aber nicht haben, weil immer noch der initialisierte Wert -1 in dieser Variablen steht (Zeile 14 wurde ja nicht angesprungen). 6. Da nun mit Installierung des EAs die Variable FirstTime2 auf true gesetzt wurde und in Zeile 18 eine ODER-Verknüpfung steht, ist die Abfrage in Zeile 18 true, wenigstens nur für den ersten Ansprung der Funktion CheckLastOrderType2(), denn in Zeile 20 wird diese Variable endgültig auf false gesetzt und nirgends im laufenden Programm wieder auf true. D.h. jedes weitere Anspringen dieser Funktion endet mit einem glatten Durchlauf der Funktion ohne Aktion! 7. Aber!!! Nur beim ersten! Durchlauf dieser Funktion wird die Funktion in Zeile 21 angesprungen und eine evtl. neue BuyOrder geöffnet. (Den Code habe ich mir nun nicht mehr angesehen) So, ich habe die Analyse mal etwas ausführlicher gestaltet, weil ich auch zeigen wollte, dass genau unter Verwendung irgendwelcher Generatoren ("PS Code kommt aus meinem Generator." - Zitat aus dem Post von @RetepM) nur Murks rauskommt, wenn man die Eingangsbedingungen nicht klar und eineindeutig beschreibt und am Ende den Code anscheinend auch nicht recht versteht und sich nur darauf verlässt. Wofür der Code auch immer generiert wurde, das Problem von @akuh löst er in keinster Weise. Viel Spass noch beim Erlernen von MQL4 auch im Jahre 2017. Prosit Neujahr! traderdoc PS. Sollte ich etwas übersehen haben, dann werde ich mich gern korrigieren.
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Hey
Erstmal Vielen Dank für die Antworten. Ich hab es mittlerweile folgendermassen gelöst: Code:
int LastOrderType() { datetime TicketTime = 0; for (int ix = 0; ix < OrdersHistoryTotal(); ix++) { if(OrderSelect(ix, SELECT_BY_POS, MODE_HISTORY) && OrderMagicNumber() == Magic && OrderSymbol() == Symbol()) { if (OrderCloseTime() > TicketTime) { TicketTime = OrderCloseTime(); //For testing TicketN = OrderTicket(); //For testing LastOT = OrderType(); } } else Print("OrderSelect returned the error of ",GetLastError()); } Print("Last closed order: ",TicketN," ",TicketTime," ",LastOT); //For testing return(LastOT); // Buy==0, Sell==1, Others==2 through 5 }// End Last Order Type Ich stehe aber mittlerweile vor einem neuen Problem, das ich nicht gelöst kriege. Ich möchte gerne eine Sellstop bzw. Buystop position eröffnen, sobald der ask bzw bid Wert des aktuellen Kurses, höher bzw. niedriger ist als der Wert des Super-trend indicators. Ich habe bereits einige Versuche unternommen, aber keiner War erfolgreich. Hier sieht ihr meinen Code für die Eröffnung von buy/sell und buystop/sellstop positionen: Code:
double up = iCustom(NULL,PERIOD_M5,"HalfTrend_1",4,1); // returns EMPTY_VALUE when no arrow occurs double down = iCustom(NULL,PERIOD_M5,"HalfTrend_1",5,1);// returns EMPTY_VALUE when no arrow occurs double tu = iCustom(NULL,0,"super-trend",Nbr_Periods,Multiplier,0,1); // returns EMPTY_VALUE in downtrends double td = iCustom(NULL,0,"super-trend",Nbr_Periods,Multiplier,1,1); // returns EMPTY_VALUE in uptrends double stup = iCustom(NULL,PERIOD_M15,"ST_MTEI",0,0); // returns EMPTY_VALUE when no arrow occurs double stdown = iCustom(NULL,PERIOD_M15,"ST_MTEI",1,0);// returns EMPTY_VALUE when no arrow occurs //Print("ST_MTEI:", up); //Print("ST_MTEI:", down); RefreshRates(); // RefreshRate() update Bid and Ask value. if ( ( Ask - Bid ) / Point < MaxSpread ) { // Checking, if spread is less than MaxSpread from inputs. If its Bigger, orders wont open // Replace 1 == 0 to your conditions to buy order. if ( up!=empty && stup!=empty && tu!=empty && down == empty && td==empty && stdown ==empty &&OrderType()==OP_SELL && LastOrder != 1 ) { // LastOrder!= 1 prevent script from making a lot of same buy orders Ticket = OrderSend ( Symbol(), OP_BUY, Lots, Ask, Slippage, Ask - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), NULL, Magic, 0, Green); LastOrder = 1; // It prevent script from making a lot of same buy orders } // Replace 1 == 0 to your conditions to buy order.&& LastOT==1 if ( Bid<tu && LastOrder != 1 ) { // LastOrder!= 1 prevent script from making a lot of same buystop orders Ticket = OrderSend ( Symbol(), OP_BUYSTOP, Lots, Ask + ( Pips * Point ), Slippage, Ask + ( Pips * Point ) - ( StopLoss * Point ), Ask - ( Pips * Point ) + ( TakeProfit * Point ), NULL, Magic, TimeCurrent() + ( 60 * Mins ), Green); LastOrder = 1; // It prevent script from making a lot of same buy orders } // Replace 1 == 0 to your conditions to sell order. if ( down!=empty && stdown!=empty && td!=empty && up==empty && tu==empty && stup==empty &&OrderType()==OP_BUY && LastOrder != 0 ) { // LastOrder!= 0 prevent script from making a lot of same sell orders Ticket = OrderSend ( Symbol(), OP_SELL, Lots, Bid, Slippage, Bid + ( StopLoss * Point ), Bid - ( TakeProfit * Point ), NULL, Magic, 0, Red); LastOrder = 0; // It prevent script from making a lot of same sell orders } // Replace 1 == 0 to your conditions to sell order.&& LastOT==0 if ( Ask>td && LastOrder != 0 ) { // LastOrder!= 0 prevent script from making a lot of same sellstop orders Ticket = OrderSend ( Symbol(), OP_SELLSTOP, Lots, Bid - ( Pips * Point ) , Slippage, Bid - ( Pips * Point ) + ( StopLoss * Point ), Bid + ( Pips * Point ) - ( TakeProfit * Point ), NULL, Magic, TimeCurrent() + ( 60 * Mins ), Red); LastOrder = 0; // It prevent script from making a lot of same sell orders } } return ( 0 ); } gruss akuh |
|
|||
Zitat:
Wenn eine Order nicht der OrderMagicNumber() und dem OrderSymbol() entspricht, wird jedesmal die Fehlermeldung geprintet. Da wird sich aber die Log-Datei freuen. Die wird dann richtig dick und fett und knabbert unaufhörlich an der Plattenkapazität. Weg damit! Und ob die letzte geschlossene Order eine Buy- oder Sell-Order ist, weiss ich auch nicht genau. Das könnte evtl. auch eine der evtl. gelöschten PendingOrders sein. Also man sollte schon sicherheitshalber nach den OrderType() == OP_BUY || OrderType() == OP_SELL fragen. traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis. |
|
|||
Hallo traderdoc
Ja du hast natürlich recht. Habe den Code schon geändert ! |
|
|||
keine neue sell Order wenn vorherige auf Sell war und umgekehrt
Hallo Zusammen,
ich habe in meinem aktuellen EA, das gleiche Problem, dass nachdem das Indicatorsignal über iCustom vom Expert ausgeführt wird und in den TakeProfit oder auch Stoploss läuft unmittelbar eine neue Order platziert wird ohne auf das Gegensignal zu warten. Ich habe obige Lösung von Traderdoc probiert, jedoch erfolglos. platziert habe ich das Skript am ende des Ea´s . nach dem compilen gab es auch keine Fehlermeldung. folglich gehe ich davon aus, dass alles ok ist. ist es egal wo das Script eingepflegt wird? vielleicht erreicht die Routine gar nicht erst das script und wird deshalb nicht ausgeführt. vielen Dank für Eure Unterstützung |
|
|||
hier zum evt.prüfen der EA:
extern string IS="---------------- Indicator Setting Heiken Ashi smoothed"; extern int MaMetod=2; extern int MaPeriod=6; extern int MaMetod2=3; extern int MaPeriod2=2; extern string LM="---------------- Money Management"; extern double Lots=0.01; extern bool MM=false; //money management extern double Risk=10; //risk in percentage extern string TSTB="---------------- TP SL TS BE"; bool RealSL_Enabled=false; int RealSL=5; //stop loss under 5 pîps bool RealTP_Enabled=false; int RealTP=10; //take profit under 10 pîps extern int SL=0; //stop loss extern int TP=0; //take profit extern int TS=0; //trailing stop extern int TS_Step=1; //trailing stop step extern int BE=0; //breakeven extern string EXT="---------------- Extras"; extern bool Reverse=false; extern bool Add_Positions=false; //positions cumulated extern int MaxOrders=1; //maximum number of orders extern int MagicNumber=09012017; int Slip=3;static int TL=0;double MML=0; // expert start function int start(){int j=0,limit=1;double BV=0,SV=0;BV=0;SV=0;double HA1,HA2; if(CntO(OP_BUY,MagicNumber)>0)TL=1;if(CntO(OP_SELL ,MagicNumber)>0)TL=-1;for(int i=1;i<=limit;i++){ HA1=iCustom(Symbol(),0,"Heiken_Ashi_Smoothed",MaMe tod,MaPeriod,MaMetod2,MaPeriod2,2,i); HA2=iCustom(Symbol(),0,"Heiken_Ashi_Smoothed",MaMe tod,MaPeriod,MaMetod2,MaPeriod2,3,i); if(HA2>HA1){if(Reverse)SV=1;else BV=1;break;} if(HA1>HA2){if(Reverse)BV=1;else SV=1;break;}} // expert money management if(MM){if(Risk<0.1||Risk>100){Comment("Invalid Risk Value.");return(0);} else{MML=MathFloor((AccountFreeMargin()*AccountLev erage()*Risk*Point*100)/(Ask*MarketInfo(Symbol(),MODE_LOTSIZE)*MarketInfo( Symbol(),MODE_MINLOT)))*MarketInfo(Symbol(),MODE_M INLOT);}} if(MM==false){MML=Lots;} // expert init positions int cnt=0,OP=0,OS=0,OB=0,CS=0,CB=0;OP=0;for(cnt=0;cnt< OrdersTotal();cnt++){OrderSelect(cnt,SELECT_BY_POS ,MODE_TRADES); if((OrderType()==OP_SELL||OrderType()==OP_BUY)&&Or derSymbol()==Symbol()&&((OrderMagicNumber()==Magic Number)||MagicNumber==0))OP=OP+1;} if(OP>=1){OS=0; OB=0;}OB=0;OS=0;CB=0;CS=0; // expert conditions to open position if(SV>0){OS=1;OB=0;}if(BV>0){OB=1;OS=0;} // expert conditions to close position if((SV>0)||(RealSL_Enabled&&(OrderOpenPrice()-Bid)/Point>=RealSL)||(RealTP_Enabled&&(Ask-OrderOpenPrice())/Point>=RealTP)){CB=1;} if((BV>0)||(RealSL_Enabled&&(Ask-OrderOpenPrice())/Point>=RealSL)||(RealTP_Enabled&&(OrderOpenPrice()-Bid)/Point>=RealTP)){CS=1;} for(cnt=0;cnt<OrdersTotal();cnt++){OrderSelect(cnt ,SELECT_BY_POS,MODE_TRADES); if(OrderType()==OP_BUY&&OrderSymbol()==Symbol()&&( (OrderMagicNumber()==MagicNumber)||MagicNumber==0) ){if(CB==1){OrderClose(OrderTicket(),OrderLots(),B id,Slip,Red);return(0);}} if(OrderType()==OP_SELL&&OrderSymbol()==Symbol()&& ((OrderMagicNumber()==MagicNumber)||MagicNumber==0 )){ if(CS==1){OrderClose(OrderTicket(),OrderLots(),Ask ,Slip,Red);return(0);}}}double SLI=0,TPI=0;int TK=0; // expert open position value if((AddP()&&Add_Positions&&OP<=MaxOrders)||(OP==0& &!Add_Positions)){ if(OS==1){if(TP==0)TPI=0;else TPI=Bid-TP*Point;if(SL==0)SLI=0;else SLI=Bid+SL*Point;TK=OrderSend(Symbol(),OP_SELL,MML ,Bid,Slip,SLI,TPI,OrSt,MagicNumber,0,Red);OS=0;ret urn(0);} if(OB==1){if(TP==0)TPI=0;else TPI=Ask+TP*Point;if(SL==0)SLI=0;else SLI=Ask-SL*Point;TK=OrderSend(Symbol(),OP_BUY,MML,Ask,Slip ,SLI,TPI,OrSt,MagicNumber,0,Lime);OB=0; return(0);}} for(j=0;j<OrdersTotal();j++){if(OrderSelect(j,SELE CT_BY_POS,MODE_TRADES)){if(OrderSymbol()==Symbol() &&((OrderMagicNumber()==MagicNumber)||MagicNumber= =0)){TrP();}}}return(0);} // expert number of orders int CntO(int Type,int Magic){int _CntO;_CntO=0; for(int j=0;j<OrdersTotal();j++){OrderSelect(j,SELECT_BY_P OS,MODE_TRADES);if(OrderSymbol()==Symbol()){if((Or derType()==Type&&(OrderMagicNumber()==Magic)||Magi c==0))_CntO++;}}return(_CntO);} //expert breakeven void TrP(){double pb,pa,pp;pp=MarketInfo(OrderSymbol(),MODE_POINT);i f(OrderType()==OP_BUY){pb=MarketInfo(OrderSymbol() ,MODE_BID); if(BE>0){if((pb-OrderOpenPrice())>BE*pp){if((OrderStopLoss()-OrderOpenPrice())<0){ModSL(OrderOpenPrice()+0*pp); }}} // expert trailing stop if(TS>0){if((pb-OrderOpenPrice())>TS*pp){if(OrderStopLoss()<pb-(TS+TS_Step-1)*pp){ModSL(pb-TS*pp);return;}}}} if(OrderType()==OP_SELL){pa=MarketInfo(OrderSymbol (),MODE_ASK);if(BE>0){if((OrderOpenPrice()-pa)>BE*pp){if((OrderOpenPrice()-OrderStopLoss())<0){ModSL(OrderOpenPrice()-0*pp);}}} if(TS>0){if(OrderOpenPrice()-pa>TS*pp){if(OrderStopLoss()>pa+(TS+TS_Step-1)*pp||OrderStopLoss()==0){ModSL(pa+TS*pp);return; }}}}} //expert stoploss void ModSL(double ldSL){bool fm;fm=OrderModify(OrderTicket(),OrderOpenPrice(),l dSL,OrderTakeProfit(),0,CLR_NONE);} //expert add positions function bool AddP(){int _num=0; int _ot=0; for (int j=0;j<OrdersTotal();j++){if(OrderSelect(j,SELECT_B Y_POS)==true && OrderSymbol()==Symbol()&&OrderType()<3&&((OrderMag icNumber()==MagicNumber)||MagicNumber==0)){ _num++;if(OrderOpenTime()>_ot) _ot=OrderOpenTime();}}if(_num==0) return(true);if(_num>0 && ((Time[0]-_ot))>0) return(true);else return(false);} // eine Order Script int CheckOrder () { for (int i = OrdersHistoryTotal () -1; i >=0; i--) { if ( !OrderSelect (i, SELECT_BY_POS, MODE_HISTORY)) continue; if (OrderSymbol () == Symbol () && OrderMagicNumber ()== MagicNumber) { if (OrderType () == 0 || OrderType () == 1) return(OrderType ()); } } return (-1); } |
Lesezeichen |
Stichworte |
befehl, keine order, mql4, programmierung, programmierung metatrader, programmierung mql4 |
|
|