Search code examples
mql4metatrader4

How can I cancel a trade when another is open and keep the open trade for a given duration?


I have written the code below that opens a buy and sell trade (a certain number of pips above and below the ask and bid price) at a specific time.

  1. How can I close/cancel one immediately when the other is opened?

  2. How can I close the opened trade if it's say X pips in profit or after a minute (depending on which condition is reached first)?

I'm a not too sure I've done the right thing in the code below and would really appreciate some help.

double spread = Ask-Bid;
extern datetime time;
extern int pipGap = 7;
extern int lotSize = 0.01;
extern int closeTimeInSeconds = 60;


int start() {
  if (TimeCurrent() >= StrToTime(time)){

    OrderSend(Symbol(),OP_BUYSTOP,lotSize, Ask + Point*pipGap, 0,0,0);
    OrderSend(Symbol(),OP_SELLSTOP,lotSize, Bid - Point*pipGap, 0,0,0);


    }


for(int pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
    OrderSelect(pos, SELECT_BY_POS)           
){              
    int duration = TimeCurrent() - OrderOpenTime();
    if (duration >= closeTimeInSeconds)
         OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),
                     3*Point);
}

   return(0);
}

Solution

  • AUTOMATED NEWS TRADING What you (@iGetIt ) are looking for is a rudimentary News Trading bot. Here's a diluted implementation for it.

    In the more advanced stages, you will need to automatically download news and auto-trade base on the affected pairs, track volatility (to avoid swings), sync your PC time (Windows date/time is NOT accurate and news trading need to be synced to the millisecond level). Track your broker server response time, implement Trailing-StopLoss (for improved profit), implement slide-in-orders (multiple stop orders to catch huge spikes), calculate order-set profitability (to know when to close all the orders when price retrace), etc etc.

    Anyway, here's a basic version that you can play with (based on the Bounty requirements):

    1. Opens buy + sell stop-orders at specific time.
    2. Configurable number of pips AWAY from current ask/bid.
    3. Implements OCO (One Cancels the Other).
    4. Closes executed trades with x-pip profit (aka TP level).
    5. Closes executed or outstanding stop-orders after x-seconds.

    Visual: To show that it executes in time (this is Asian time, so liquidity is low, so +- a few seconds before price ticks). enter image description here


    Closing: It closes automatically based on the settings. enter image description here

    SOURCE CODE: And this is the complete MQL4 source-code for it.

    (UPDATED 15May19 1045 GMT+8) to fix bug as reported in the closing of executed orders after TTL.

    //+------------------------------------------------------------------+
    //|                                                                 SO55930471.mq4 |
    //|                   Copyright 2019, Joseph Lee, [email protected] |
    //|                                                       TELEGRAM @JosephLee74 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2019, Joseph Lee, TELEGRAM @JosephLee74"
    #property link      "http://www.fs.com.my"
    #property version   "1.00"
    #property strict
    
    
    //-------------------------------------------------------------------
    // APPLICABLE PARAMETERS
    //-------------------------------------------------------------------
    //-------------------------------------------------------------------
    // NEWS IMPACT SELECTION
    //===================================================================
    extern string       vsEAComment                         = "Telegram @JosephLee74";      //Ego trip
    extern datetime vdTradeStartInGMT                   = D'2019.5.14 06:00';           //When to trade (GMT)
    extern int          viStopOrderLevelInPip           = 5;                    // StopOrder distance from ask/bid (pips)
    extern double       viFixLots                           = 0.01;             // Lot size
    extern int          viStopLossInPip                 = 20;                   // StopLoss (pips)
    extern int          viTargetProfitInPip             = 100;              // TargetProfit (pips)
    extern int          viDeleteStopOrderAfterInSec = 30;                   // StopOrder TTL (sec)
    extern int          viDeleteOpenOrderAfterInSec = 300;              // Executed Order TTL (sec)
    extern int          viMaxSlippageInPip              = 2;                    // Max Slippage (pip)
    
    
    //-------------------------------------------------------------------
    // System Variables
    //-------------------------------------------------------------------
    int     viMagicId                   = 0;
    double  viPipsToPrice               = 0.0001;
    double  viPipsToPoint               = 1;
    int     viBuyStopTicket         = -1;
    int     viSellStopTicket            = -1;
    int     viBuyOrderTicket            = -1;
    int     viSellOrderTicket           = -1;
    string  vsDisplay                   = "EVENT-TRADER v1.01 - ";
    
    //-------------------------------------------------------------------
    
    
    
    //+------------------------------------------------------------------+
    //| EA Initialization function
    //+------------------------------------------------------------------+
    int init() {
        ObjectsDeleteAll(); Comment("");
        // Caclulate PipsToPrice & PipsToPoints (old sytle, but works)
        if((Digits == 2) || (Digits == 3)) {viPipsToPrice=0.01;}
        if((Digits == 3) || (Digits == 5)) {viPipsToPoint=10;}
        viMagicId = vdTradeStartInGMT;
        start();
        return(0);
    }
    //+------------------------------------------------------------------+
    //| EA Stand-Down function
    //+------------------------------------------------------------------+
    int deinit() {
        ObjectsDeleteAll();
        return(0);
    }
    
    
    //============================================================
    // MAIN EA ROUTINE
    //============================================================
    int start() {
    
        //==========================================
        //MANAGE ROBOT EXPIRY
        //==========================================
        if( TimeCurrent() > D'2020.1.1' ) {
            Comment(vsDisplay + "EXPIRED. Please contact josephfhlee74 at gmail dot com"); // Who am I kidding?
            return(0);
        }
    
    
        ResetLastError();
        // Exit the routine if it is not time to trade yet.
        if(TimeGMT() < vdTradeStartInGMT) {
            // Show a count-down timer to the trading time.
            Comment(vsDisplay +
                "[" + TimeToStr(TimeGMT()) + " GMT] " + 
                IntegerToString(int(vdTradeStartInGMT - TimeGMT())) + " sec to [" + 
                TimeToStr(vdTradeStartInGMT) + " GMT]"
            );
            return(0);
        }
    
    
        viBuyStopTicket     = -1;
        viSellStopTicket        = -1;
        viBuyOrderTicket        = -1;
        viSellOrderTicket       = -1;
        //=========================================================
        //FIND *OPENED* BUY/SELL PENDING ORDERS
        //---------------------------------------------------------
        for( int i=OrdersTotal()-1; i>=0; i-- ) {
            if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES ))
                if( OrderSymbol() == Symbol() )
                    if( OrderMagicNumber() == viMagicId) {
                        if( OrderType() == OP_BUYSTOP )
                            viBuyStopTicket  = OrderTicket();
                        if( OrderType() == OP_SELLSTOP )
                            viSellStopTicket  = OrderTicket();
                        if( OrderType() == OP_BUY )
                            viBuyOrderTicket  = OrderTicket();
                        if( OrderType() == OP_SELL )
                            viSellOrderTicket  = OrderTicket();
                    }
        }
        //=========================================================
        //FIND *CLOSED* BUY/SELL ORDERS FOR THIS EVENT
        //---------------------------------------------------------
        for(int i=OrdersHistoryTotal()-1; i>=0; i--) {
            if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
                if(OrderSymbol() == Symbol())
                    if(OrderMagicNumber() == viMagicId) {
                        if( OrderType() == OP_BUYSTOP )
                            viBuyStopTicket  = OrderTicket();
                        if( OrderType() == OP_SELLSTOP )
                            viSellStopTicket  = OrderTicket();
                        if( OrderType() == OP_BUY )
                            viBuyOrderTicket  = OrderTicket();
                        if( OrderType() == OP_SELL )
                            viSellOrderTicket  = OrderTicket();
                    }
        }
        // The above 2 sections will ensure that each event will only be executed once.
        // If orders are cancelled or closed for whatever reason, they will never be open again.
    
        string vsVerbose     =  vsDisplay + "[GMT " + TimeToStr(TimeGMT()) + "] Executing ..."
                                        "\nActive BUYSTOP: " + viBuyStopTicket +
                                        "  |  Active SELLSTOP: " + viSellStopTicket +
                                        "" +
                                        "\nActive BUY: " + viBuyOrderTicket +
                                        "  |  Active SELL: " + viSellOrderTicket;
        Comment(vsVerbose);
    
    
        //=========================================================
        // HANDLES OCO (One-Cancels-the-Other)
        //---------------------------------------------------------
        // BUY Order EXISTS, cancels all SellStops
        if( viBuyOrderTicket != -1 ) {
            for( int i=OrdersTotal()-1; i>=0; i-- ) {
                if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES ))
                    if( OrderSymbol() == Symbol() )
                        if( OrderMagicNumber() == viMagicId)
                            if( OrderType() == OP_SELLSTOP )
                                OrderDelete(OrderTicket());
            }
        }
        // SELL Order EXISTS, cancels all BuyStops
        if( viSellOrderTicket != -1 ) {
            for( int i=OrdersTotal()-1; i>=0; i-- ) {
                if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES ))
                    if( OrderSymbol() == Symbol() )
                        if( OrderMagicNumber() == viMagicId)
                            if( OrderType() == OP_BUYSTOP )
                                OrderDelete(OrderTicket());
            }
        }
    
        //=========================================================
        //CLOSE EXPIRED STOP/EXECUTED ORDERS
        //---------------------------------------------------------
        for( int i=OrdersTotal()-1; i>=0; i-- ) {
            if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES ))
                if( OrderSymbol() == Symbol() )
                    if( OrderMagicNumber() == viMagicId) {
                        if( (OrderType() == OP_BUYSTOP) || (OrderType() == OP_SELLSTOP) )
                            if((TimeCurrent()-OrderOpenTime()) >= viDeleteStopOrderAfterInSec)
                                OrderDelete(OrderTicket());
    
                        if( (OrderType() == OP_BUY) || (OrderType() == OP_SELL) )
                            if((TimeCurrent()-OrderOpenTime()) >= viDeleteOpenOrderAfterInSec) {
                                // For executed orders, need to close them
                                double closePrice = 0;
                                RefreshRates();
                                if(OrderType() == OP_BUY)
                                    closePrice  = Bid;
                                if(OrderType() == OP_SELL)
                                    closePrice  = Ask;
                                OrderClose(OrderTicket(), OrderLots(), closePrice, int(viMaxSlippageInPip*viPipsToPoint), clrWhite);
                            }
                    }
        }
    
    
    
        //===================================================================
        //OPEN STOP ORDERS IF NO EXISTING nor CLOSED NO BUY/SELL STOP/ORDERS
        //-------------------------------------------------------------------
        // Do NOT execute (place new orders) if it is past the trading window.
        if(TimeGMT() >= (vdTradeStartInGMT+viDeleteStopOrderAfterInSec))
        {
            Comment(vsDisplay + "[" + TimeToStr(TimeGMT()) + " GMT] " + "Already passed execution time.");
            return(0);
        }
        // Place BuyStop if not exists; and no executed-Buy order
        if( (viBuyStopTicket == -1) && (viBuyOrderTicket == -1)) {
            RefreshRates();
            viFixLots       = NormalizeDouble(viFixLots, 2);
            double viPrice = NormalizeDouble(Ask + (viStopOrderLevelInPip*viPipsToPrice), Digits);
            double viSL  = viPrice - (viStopLossInPip*viPipsToPrice);
            double viTP  = viPrice + (viTargetProfitInPip*viPipsToPrice);
            viBuyStopTicket   = OrderSend(Symbol(), OP_BUYSTOP, viFixLots
                                            , viPrice
                                            , int(viMaxSlippageInPip*viPipsToPoint)
                                            , viSL, viTP
                                            , vsEAComment, viMagicId, 0, Blue);
            if(viBuyStopTicket == -1)
                Print("Error executing BuyStop [" + IntegerToString(GetLastError()) + "]." );
        }
        // Place SellStop if not exists; and no executed-Sell order
        if( (viSellStopTicket == -1) && (viSellOrderTicket == -1) ) {
            RefreshRates();
            viFixLots       = NormalizeDouble(viFixLots, 2);
            double viPrice  = NormalizeDouble(Bid - (viStopOrderLevelInPip*viPipsToPrice), Digits);
            double viSL     = viPrice + (viStopLossInPip*viPipsToPrice);
            double viTP     = viPrice - (viTargetProfitInPip*viPipsToPrice);
            viSellStopTicket      = OrderSend(Symbol(), OP_SELLSTOP, viFixLots
                                            , viPrice
                                            , int(viMaxSlippageInPip*viPipsToPoint)
                                            , viSL, viTP
                                            , vsEAComment, viMagicId, 0, Red);
            if(viSellStopTicket == -1)
                Print("Error executing SellStop [" + IntegerToString(GetLastError()) + "]." );
        }
        return(0);
    }