I was wondering if there are people familiar with writing code in MQL4 that could help me out. I'm new to programming and I'm trying to write an EA that will have two parameters before trading. The first parameter is to define a day as 9am GMT to 9am GMT. This way I can define the day starting at London's open. The second parameter is to check if profit for the day is greater than a set number of pips...example 20 pips. The idea is to allow the EA to trade starting at 9am GMT and keep trading until >=20 pips is reached. Then the profit is reset to 0 for the next day. Thanks in advance for any help.
For the timing problem not sure the following is an optimal solution but it's an idea that might be useful: if (TimeDay(Time - TimeZone*3600)!=TimeDay(Time[i+1] - TimeZone*3600)) with TimeZone being an external variable determining the offset. You'll probably need to account for weekends though so something like if ( (TimeDayOfWeek(Time - TimeZone*3600)==0) || (TimeDayOfWeek(Time + TimeZone*3600)==0) ) might need to be another condition that needs to precede the previous one.
this should give you a good idea... to define parameters the user can enter when applying your strategy to a MT chart, you do like this outside of the start() function, eg: Code: [color=blue] extern double PipsTarget = 0; int start() { // strategy code here return 0; } [/color] to check for profits, this is sort of messy in MQL. First you have to use OrderSelect to select the right order or position that you want profit data for.... here's profit by position: Code: [color=blue] // previously you've saved order id somewhere, whenever you sent order // you could also get the last order number using OrderTicket(); int myordernumber = OrderSend(..); // then when we check for profit on the position later, we use the same order to identify which position double profit = 0; if (OrderSelect(myordernumber, SELECT_BY_POS)==true) profit = OpenProfit(); // this is gross profit before commissions, not pips, you could calculate back to pips using the OpenLots() functions to figure out per contract/share profit double perconprofit = 0; if (OrderSelect(myordernumber,SELECT_BY_POS)==true) perconprofit = OpenLots() !=0 ? profit / OpenLots() : 0; // then do whatever you want to do when the profit is reached, eg close position if (perconprofit>PipsTarget) OrderClose(myordernumber,OrderLots(),(OrderType()==OP_BUY) ? Ask : Bid,0); [/color]
Thanks for the tips. I see the logic of getting the ticket ID. Does that work for multiple closed trades? I'm not sure how to store the values when there may be up to 30 trades per day and I need to add them all up without declaring 30 separate variables. Is it possible to store each ticket's profit in an array and then add them all up? Or is just a counter a better solution?
yes you could store each ticker in a running total. I find this particular aspect of MQL very strange, how they account for trades... it's a bit cumbersome but I can tell you've got the right idea.
For the time zone, I'll add some code for that since I wrote it just yesterday. int timeServer = TimeCurrent(); // Server time in seconds, right now int timeDifference_seconds = 3600.0 * MathRound((timeServer - TimeLocal()) / 3600.0); // How many seconds the server is ahead of us, rounded to the nearest hour This way you don't have to hard code your time difference. Two things to think about with time are: 1. Daylight Savings Time. Oh, how I HATE thee. To make matters worse, my broker (FXPro) is on European DST and Canadians decided to, like sheep, follow our wayward American brethren into changing our DST times. So now for most of the year my broker is 7 hours ahead of me but for part they are 6 hours ahead. Not to mention how this messes with New York exchange times as well. 2. In backtesting, Metatrader assumes your local time to be the same as the server time. Therefore you either have to check for that condition using IsTesting() and/or IsOptimization(), or just use your broker's time and forget about your local time zone. - Andrew.
Yes, DST is troublesome. I do have the timezone offset hardcoded right now. I intended to manually change it and recompile when we go on/off DST. I'm still having trouble with the addition of profitable trades. I'm not sure how to write the next line of code to either store profits of each ticket or just add them to a counter. Any thoughts? PHP: for (int i=0;i<OrdersHistoryTotal();i++) //Counter up until it hits the total trades in history { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true) //Getting all closed trades { if(closetime>=startofday && closetime<endofday) //Specifying only within day trades //code here to use OrderProfit?, OrderTicket?, or somehow write a counter to add the previous profits?
double totalProfit; [...] totalProfit = totalProfit + OrderProfit() - OrderCommission(); The other things you'll want to add in there are OrderMagicNumber() and Symbol(). You'll want OrderMagicNumber() because you may eventually be running multiple EAs on one symbol. You'll want Symbol() because you might be running this EA on mutiple symbols. If you do either of these on one account with your broker, looping through all the orders in OrdersHistoryTotal() will have you calculating profit for orders that weren't placed by this EA on this symbol. Also, you might want to change your code to loop through the orders backwards. That way when you're out of your zone you can break out of the loop and not waste time checking the last 60 days, or whatever, of orders for yesterday's orders. So try something like this instead: Code: [color=blue] double totalProfit = 0.0; int ordersHistoryTotal = OrdersHistoryTotal(); int magicNumber = 123456; // put something here for (int i=ordersHistoryTotal;i<=0;i--) //Counter down until it hits the total trades in history { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) //Getting all closed trades { closetime = OrderCloseTime(); // I presume this is what you want if (closetime < startofday) break; // Stop processing if we've gone too far back in time if ((magicNumber == OrderMagicNumber()) && (Symbol() == OrderSymbol()) && closetime>=startofday && closetime < endofday) totalProfit = totalProfit + OrderProfit() - OrderCommission(); // Specifying only within day trades } else { // Add some error handling here. } // if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) } // for (int i=ordersHistoryTotal;i<=0;i--) [/color] I haven't tested this but it seems to be about what you're looking for. - Andrew.