//+------------------------------------------------------------------+ //| Strategy: hasad2.mq4 | //| Created with EABuilder.com | //| https://www.eabuilder.com | //+------------------------------------------------------------------+ #property copyright "Created with EABuilder.com" #property link "https://www.eabuilder.com" #property version "1.00" #property description "" #include <stdlib.mqh> #include <stderror.mqh> extern double TP_Points = 30; extern double SL_Points = 30; int LotDigits; //initialized in OnInit extern int MagicNumber = 171858; extern int NextOpenTradeAfterDays = 1; //next open trade after time extern int TOD_From_Hour = 02; //time of the day (from hour) extern int TOD_From_Min = 00; //time of the day (from min) extern int TOD_To_Hour = 20; //time of the day (to hour) extern int TOD_To_Min = 00; //time of the day (to min) extern double MM_Martingale_Start = 0.01; double MM_Martingale_ProfitFactor = 1; extern double MM_Martingale_LossFactor = 2; extern bool MM_Martingale_RestartProfit = true; bool MM_Martingale_RestartLoss = false; extern int MM_Martingale_RestartLosses = 3; int MM_Martingale_RestartProfits = 1000; extern int MaxSlippage = 3; //adjusted in OnInit extern bool TradeMonday = true; extern bool TradeTuesday = true; extern bool TradeWednesday = true; extern bool TradeThursday = true; extern bool TradeFriday = true; bool TradeSaturday = false; bool TradeSunday = false; extern int MaxOpenTrades = 1; int MaxLongTrades = 1000; int MaxShortTrades = 1000; int MaxPendingOrders = 1000; int MaxLongPendingOrders = 1000; int MaxShortPendingOrders = 1000; bool Hedging = false; int OrderRetry = 5; //# of retries if sending order returns error int OrderWait = 5; //# of seconds to wait if sending order returns error double myPoint; //initialized in OnInit bool inTimeInterval(datetime t, int From_Hour, int From_Min, int To_Hour, int To_Min) { string TOD = TimeToString(t, TIME_MINUTES); string TOD_From = StringFormat("%02d", From_Hour)+":"+StringFormat("%02d", From_Min); string TOD_To = StringFormat("%02d", To_Hour)+":"+StringFormat("%02d", To_Min); return((StringCompare(TOD, TOD_From) >= 0 && StringCompare(TOD, TOD_To) <= 0) || (StringCompare(TOD_From, TOD_To) > 0 && ((StringCompare(TOD, TOD_From) >= 0 && StringCompare(TOD, "23:59") <= 0) || (StringCompare(TOD, "00:00") >= 0 && StringCompare(TOD, TOD_To) <= 0)))); } double MM_Size() //martingale / anti-martingale { double lots = MM_Martingale_Start; double MaxLot = MarketInfo(Symbol(), MODE_MAXLOT); double MinLot = MarketInfo(Symbol(), MODE_MINLOT); if(SelectLastHistoryTrade()) { double orderprofit = OrderProfit(); double orderlots = OrderLots(); double boprofit = BOProfit(OrderTicket()); if(orderprofit + boprofit > 0 && !MM_Martingale_RestartProfit) lots = orderlots * MM_Martingale_ProfitFactor; else if(orderprofit + boprofit < 0 && !MM_Martingale_RestartLoss) lots = orderlots * MM_Martingale_LossFactor; else if(orderprofit + boprofit == 0) lots = orderlots; } if(ConsecutivePL(false, MM_Martingale_RestartLosses)) lots = MM_Martingale_Start; if(ConsecutivePL(true, MM_Martingale_RestartProfits)) lots = MM_Martingale_Start; if(lots > MaxLot) lots = MaxLot; if(lots < MinLot) lots = MinLot; return(lots); } bool TradeDayOfWeek() { int day = DayOfWeek(); return((TradeMonday && day == 1) || (TradeTuesday && day == 2) || (TradeWednesday && day == 3) || (TradeThursday && day == 4) || (TradeFriday && day == 5) || (TradeSaturday && day == 6) || (TradeSunday && day == 0)); } void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | hasad2 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } } int TradesCount(int type) //returns # of open trades for order type, current symbol and magic number { int result = 0; int total = OrdersTotal(); for(int i = 0; i < total; i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue; if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol() || OrderType() != type) continue; result++; } return(result); } datetime LastOpenTradeTime() { datetime result = 0; for(int i = OrdersTotal()-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderType() > 1) continue; if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { result = OrderOpenTime(); break; } } return(result); } bool SelectLastHistoryTrade() { int lastOrder = -1; int total = OrdersHistoryTotal(); for(int i = total-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { lastOrder = i; break; } } return(lastOrder >= 0); } double BOProfit(int ticket) //Binary Options profit { int total = OrdersHistoryTotal(); for(int i = total-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(StringSubstr(OrderComment(), 0, 2) == "BO" && StringFind(OrderComment(), "#"+IntegerToString(ticket)+" ") >= 0) return OrderProfit(); } return 0; } bool ConsecutivePL(bool profits, int n) { int count = 0; int total = OrdersHistoryTotal(); for(int i = total-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { double orderprofit = OrderProfit(); double boprofit = BOProfit(OrderTicket()); if((!profits && orderprofit + boprofit >= 0) || (profits && orderprofit + boprofit <= 0)) break; count++; } } return(count >= n); } datetime LastOpenTime() { datetime opentime1 = 0, opentime2 = 0; if(SelectLastHistoryTrade()) opentime1 = OrderOpenTime(); opentime2 = LastOpenTradeTime(); if (opentime1 > opentime2) return opentime1; else return opentime2; } int myOrderSend(int type, double price, double volume, string ordername) //send order, return ticket ("price" is irrelevant for market orders) { if(!IsTradeAllowed()) return(-1); int ticket = -1; int retries = 0; int err = 0; int long_trades = TradesCount(OP_BUY); int short_trades = TradesCount(OP_SELL); int long_pending = TradesCount(OP_BUYLIMIT) + TradesCount(OP_BUYSTOP); int short_pending = TradesCount(OP_SELLLIMIT) + TradesCount(OP_SELLSTOP); string ordername_ = ordername; if(ordername != "") ordername_ = "("+ordername+")"; //test Hedging if(!Hedging && ((type % 2 == 0 && short_trades + short_pending > 0) || (type % 2 == 1 && long_trades + long_pending > 0))) { myAlert("print", "Order"+ordername_+" not sent, hedging not allowed"); return(-1); } //test maximum trades if((type % 2 == 0 && long_trades >= MaxLongTrades) || (type % 2 == 1 && short_trades >= MaxShortTrades) || (long_trades + short_trades >= MaxOpenTrades) || (type > 1 && type % 2 == 0 && long_pending >= MaxLongPendingOrders) || (type > 1 && type % 2 == 1 && short_pending >= MaxShortPendingOrders) || (type > 1 && long_pending + short_pending >= MaxPendingOrders) ) { myAlert("print", "Order"+ordername_+" not sent, maximum reached"); return(-1); } //prepare to send order while(IsTradeContextBusy()) Sleep(100); RefreshRates(); if(type == OP_BUY) price = Ask; else if(type == OP_SELL) price = Bid; else if(price < 0) //invalid price for pending order { myAlert("order", "Order"+ordername_+" not sent, invalid price for pending order"); return(-1); } int clr = (type % 2 == 1) ? clrRed : clrBlue; while(ticket < 0 && retries < OrderRetry+1) { ticket = OrderSend(Symbol(), type, NormalizeDouble(volume, LotDigits), NormalizeDouble(price, Digits()), MaxSlippage, 0, 0, ordername, MagicNumber, 0, clr); if(ticket < 0) { err = GetLastError(); myAlert("print", "OrderSend"+ordername_+" error #"+IntegerToString(err)+" "+ErrorDescription(err)); Sleep(OrderWait*1000); } retries++; } if(ticket < 0) { myAlert("error", "OrderSend"+ordername_+" failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err)+" "+ErrorDescription(err)); return(-1); } string typestr[6] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop"}; myAlert("order", "Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+IntegerToString(MagicNumber)); return(ticket); } int myOrderModifyRel(int ticket, double SL, double TP) //modify SL and TP (relative to open price), zero targets do not modify { if(!IsTradeAllowed()) return(-1); bool success = false; int retries = 0; int err = 0; SL = NormalizeDouble(SL, Digits()); TP = NormalizeDouble(TP, Digits()); if(SL < 0) SL = 0; if(TP < 0) TP = 0; //prepare to select order while(IsTradeContextBusy()) Sleep(100); if(!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) { err = GetLastError(); myAlert("error", "OrderSelect failed; error #"+IntegerToString(err)+" "+ErrorDescription(err)); return(-1); } //prepare to modify order while(IsTradeContextBusy()) Sleep(100); RefreshRates(); //convert relative to absolute if(OrderType() % 2 == 0) //buy { if(NormalizeDouble(SL, Digits()) != 0) SL = OrderOpenPrice() - SL; if(NormalizeDouble(TP, Digits()) != 0) TP = OrderOpenPrice() + TP; } else //sell { if(NormalizeDouble(SL, Digits()) != 0) SL = OrderOpenPrice() + SL; if(NormalizeDouble(TP, Digits()) != 0) TP = OrderOpenPrice() - TP; } if(CompareDoubles(SL, 0)) SL = OrderStopLoss(); //not to modify if(CompareDoubles(TP, 0)) TP = OrderTakeProfit(); //not to modify if(CompareDoubles(SL, OrderStopLoss()) && CompareDoubles(TP, OrderTakeProfit())) return(0); //nothing to do while(!success && retries < OrderRetry+1) { success = OrderModify(ticket, NormalizeDouble(OrderOpenPrice(), Digits()), NormalizeDouble(SL, Digits()), NormalizeDouble(TP, Digits()), OrderExpiration(), CLR_NONE); if(!success) { err = GetLastError(); myAlert("print", "OrderModify error #"+IntegerToString(err)+" "+ErrorDescription(err)); Sleep(OrderWait*1000); } retries++; } if(!success) { myAlert("error", "OrderModify failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err)+" "+ErrorDescription(err)); return(-1); } string alertstr = "Order modified: ticket="+IntegerToString(ticket); if(!CompareDoubles(SL, 0)) alertstr = alertstr+" SL="+DoubleToString(SL); if(!CompareDoubles(TP, 0)) alertstr = alertstr+" TP="+DoubleToString(TP); myAlert("modify", alertstr); return(0); } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; MaxSlippage *= 10; } //initialize LotDigits double LotStep = MarketInfo(Symbol(), MODE_LOTSTEP); if(NormalizeDouble(LotStep, 3) == round(LotStep)) LotDigits = 0; else if(NormalizeDouble(10*LotStep, 3) == round(10*LotStep)) LotDigits = 1; else if(NormalizeDouble(100*LotStep, 3) == round(100*LotStep)) LotDigits = 2; else LotDigits = 3; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { int ticket = -1; double price; double SL; double TP; //Open Buy Order if(true //no conditions! ) { RefreshRates(); price = Ask; SL = SL_Points * myPoint; //Stop Loss = value in points (relative to price) TP = TP_Points * myPoint; //Take Profit = value in points (relative to price) if(TimeCurrent() - LastOpenTime() < NextOpenTradeAfterDays * 86400) return; //next open trade after time after previous trade's open if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day if(!TradeDayOfWeek()) return; //open trades only on specific days of the week if(IsTradeAllowed()) { ticket = myOrderSend(OP_BUY, price, MM_Size(), ""); if(ticket <= 0) return; } else //not autotrading => only send alert myAlert("order", ""); myOrderModifyRel(ticket, 0, TP); myOrderModifyRel(ticket, SL, 0); } //Open Sell Order if(true //no conditions! ) { RefreshRates(); price = Bid; SL = SL_Points * myPoint; //Stop Loss = value in points (relative to price) TP = TP_Points * myPoint; //Take Profit = value in points (relative to price) if(TimeCurrent() - LastOpenTime() < NextOpenTradeAfterDays * 86400) return; //next open trade after time after previous trade's open if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day if(!TradeDayOfWeek()) return; //open trades only on specific days of the week if(IsTradeAllowed()) { ticket = myOrderSend(OP_SELL, price, MM_Size(), ""); if(ticket <= 0) return; } else //not autotrading => only send alert myAlert("order", ""); myOrderModifyRel(ticket, SL, 0); myOrderModifyRel(ticket, 0, TP); } } //+------------------------------------------------------------------+
-
//| Created with EABuilder.com |
EA builder, EA Builder Pro, EATree, Etasoft forex generator, Forex Strategy Builder, ForexEAdvisor STRATEGY BUILDER, ForexRobotAcademy.com, FX EA Builder, fxDreema, FxPro, Molanis, Octa-FX Meta Editor, Online Forex Expert Advisor Generator, Strategy Builder FX, Strategy Quant, Visual Trader Studio, MQL5 Wizard, etc., are all the same. You will get something quick, but then you will spend a much longer time trying to get it right, than if you learned the language up front, and then just wrote it.
-
Since you haven't learned MQL4/5, therefor there is no common language for us to communicate.
If we tell you what you need, you can't code it.
If we give you the code, you don't know how to integrate it into yours.
We are willing to HELP you when you post your attempt (using Code button) and state the nature of your problem, but we are not going to debug your hundreds of lines of code. You are essentially going to be on your own. -
EA builder makes bad code counting up while closing multiple orders.
EA builder makes bad code Bars is unreliable (Max bars in chart), volume is unreliable (miss ticks.) Always use time.
EA builder makes bad code, not adjusting for 4/5 digit brokers, TP/SL and slippage.
EA builder makes bad code, not adjusting for ECN brokers. pre-Build 500)
EA builder makes bad code, not checking return codes. -
EATree uses objects on chart to save values — not persistent storage (files or GV+Flush.) No recovery (crash/power failure.)
-
FX EA Builder makes bad code, not checking return codes.
FX EA Builder makes bad code, loosing open tickets on terminal restart. No recovery (crash/power failure.)
FX EA Builder makes bad code, not adjusting stops for the spread.
FX EA Builder makes bad code, using OrdersTotal directly. -
FOREXEADVISOR STRATEGY BUILDER makes bad code, non-updateing global variables.
FOREXEADVISOR STRATEGY BUILDER makes bad code, compilation errors.
FOREXEADVISOR STRATEGY BUILDER makes bad code, not checking return codes.
Learn to code it, or pay someone (Freelance) someone to code it.
Hiring to write script - General - MQL5 programming forum #1 (2019) -
-
bool SelectLastHistoryTrade()
-
Do not assume history has only closed orders.
OrderType() == 6, 7 in the history pool? - MQL4 programming forum (2017) -
Do not assume history is ordered by date, it's not.
Could EA Really Live By Order_History Alone? (ubzen) - MQL4 programming forum (2012)
Taking the last profit and storing it in a variable | MQL4 - MQL4 programming forum #3 (2020.06.08) -
Total Profit is OrderProfit() + OrderSwap() + OrderCommission(). Some brokers don't use the Commission/Swap fields. Instead, they add balance entries. (Maybe related to Government required accounting/tax laws.)
"balance" orders in account history - Day Trading Techniques - MQL4 programming forum (2017)Broker History FXCM Commission - <TICKET>
Rollover - <TICKET>>R/O - 1,000 EUR/USD @0.52 #<ticket> N/A OANDA Balance update
Financing (Swap: One entry for all open orders.)
-
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use