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.
How can I close/cancel one immediately when the other is opened?
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);
}
What Is Time In Force? Time in force is a special instruction used when placing a trade to indicate how long an order will remain active before it is executed or expires. These options are especially important for active traders and allow them to be more specific about the time parameters.
Time In Force is the amount of time spent during the execution of an order before it expires.
Orders may remain open because certain conditions such as limit price have not yet been met. Market orders, on the other hand, do not have such restrictions and are typically filled fairly instantaneously. Open orders may be cancelled before they are filled in whole or in part.
The six types of time in force orders include: Day Order (DAY) Good 'Til Canceled (GTC) Immediate or Cancel (IOC) Fill or Kill (FOK)
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):
Visual: To show that it executes in time (this is Asian time, so liquidity is low, so +- a few seconds before price ticks).
Closing: It closes automatically based on the settings.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With