// Id: // More information about this indicator can be found at: // http://fxcodebase.com/code/viewtopic.php?f=38&t=67186 //+------------------------------------------------------------------+ //| Copyright � 2018, Gehtsoft USA LLC | //| http://fxcodebase.com | //+------------------------------------------------------------------+ //| Developed by : Mario Jemic | //| mario.jemic@gmail.com | //+------------------------------------------------------------------+ //| Support our efforts by donating | //| Paypal : https://goo.gl/9Rj74e | //+------------------------------------------------------------------+ //| Patreon : https://goo.gl/GdXWeN | //| BitCoin : 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF | //| BitCoin Cash : 1BEtS465S3Su438Kc58h2sqvVvHK9Mijtg | //| Ethereum : 0x8C110cD61538fb6d7A2B47858F0c0AaBd663068D | //| LiteCoin : LLU8PSY2vsq7B9kRELLZQcKf5nJQrdeqwD | //+------------------------------------------------------------------+ #property copyright "Copyright � 2018, Gehtsoft USA LLC" #property link "http://fxcodebase.com" #property strict extern string _symbol = "GBPNZD"; // Symbol to open extern double _lots = 100; // Lots extern double _stop = 0; // Stop extern double _limit = 0; // Limit extern int _slippagePoints = 3; // Slippage, points extern int _magicNumber = 1234; // Magic number enum OrderSide { BuySide, SellSide }; int OnInit() { return INIT_SUCCEEDED; } void OnDeinit(const int reason) { } // Market order builder v 1.2 class MarketOrderBuilder { OrderSide _orderSide; string _instrument; double _amount; double _rate; int _slippage; double _stop; double _limit; int _magicNumber; string _comment; public: MarketOrderBuilder *SetSide(const OrderSide orderSide) { _orderSide = orderSide; return &this; } MarketOrderBuilder *SetInstrument(const string instrument) { _instrument = instrument; return &this; } MarketOrderBuilder *SetAmount(const double amount) { _amount = amount; return &this; } MarketOrderBuilder *SetSlippage(const int slippage) { _slippage = slippage; return &this; } MarketOrderBuilder *SetStop(const double stop) { _stop = NormalizeDouble(stop, Digits); return &this; } MarketOrderBuilder *SetLimit(const double limit) { _limit = NormalizeDouble(limit, Digits); return &this; } MarketOrderBuilder *SetMagicNumber(const int magicNumber) { _magicNumber = magicNumber; return &this; } MarketOrderBuilder *SetComment(const string comment) { _comment = comment; return &this; } int Execute(string &errorMessage) { int orderType = _orderSide == BuySide ? OP_BUY : OP_SELL; double minstoplevel = MarketInfo(_instrument, MODE_STOPLEVEL); double rate = _orderSide == BuySide ? MarketInfo(_instrument, MODE_ASK) : MarketInfo(_instrument, MODE_BID); int order = OrderSend(_instrument, orderType, _amount, rate, _slippage, _stop, _limit, _comment, _magicNumber); if (order == -1) { int error = GetLastError(); switch (error) { case ERR_NOT_ENOUGH_MONEY: errorMessage = "Not enought money"; return -1; case ERR_INVALID_TRADE_VOLUME: { double minVolume = SymbolInfoDouble(_instrument, SYMBOL_VOLUME_MIN); if (_amount < minVolume) { errorMessage = "Volume of the lot is too low: " + DoubleToStr(_amount) + " Min lot is: " + DoubleToStr(minVolume); return -1; } double maxVolume = SymbolInfoDouble(_instrument, SYMBOL_VOLUME_MAX); if (_amount > maxVolume) { errorMessage = "Volume of the lot is too high: " + DoubleToStr(_amount) + " Max lot is: " + DoubleToStr(maxVolume); return -1; } errorMessage = "Invalid volume: " + DoubleToStr(_amount); } return -1; case ERR_TRADE_NOT_ALLOWED: errorMessage = "Trading is not allowed"; return -1; case ERR_INVALID_STOPS: { double point = SymbolInfoDouble(_instrument, SYMBOL_POINT); int minStopDistancePoints = (int)SymbolInfoInteger(_instrument, SYMBOL_TRADE_STOPS_LEVEL); if (_stop != 0.0) { if (MathRound(MathAbs(rate - _stop) / point) < minStopDistancePoints) errorMessage = "Your stop loss level is too close. The minimal distance allowed is " + IntegerToString(minStopDistancePoints) + " points"; else errorMessage = "Invalid stop loss in the request"; } else if (_limit != 0.0) { if (MathRound(MathAbs(rate - _limit) / point) < minStopDistancePoints) errorMessage = "Your take profit level is too close. The minimal distance allowed is " + IntegerToString(minStopDistancePoints) + " points"; else errorMessage = "Invalid take profit in the request"; } else errorMessage = "Invalid take profit in the request"; } return -1; default: errorMessage = "Failed to create order: " + IntegerToString(error); return -1; } } return order; } }; bool executed = false; void OnTick() { if (executed) return; string error; MarketOrderBuilder *orderBuilder = new MarketOrderBuilder(); int order = orderBuilder .SetSide(BuySide) .SetInstrument(_symbol) .SetAmount(_lots) .SetSlippage(_slippagePoints) .SetMagicNumber(_magicNumber) .SetStop(_stop) .SetLimit(_limit) .Execute(error); delete orderBuilder; executed = true; if (order == -1) { Print("Failed to open position: " + error); } }