Knowing the profit of the last closed position

 

With two trials to get the profit of the last closed position (Hedging account), I am not arriving anywhere.

The first trial is personal, and it goes like this:

//+------------------------------------------------------------------+
//| Ask: MQL4 emulation                                              |
//+------------------------------------------------------------------+
double Ask(string aPair)                                      //[MQL5]
{
MqlTick last_tick;
SymbolInfoTick(aPair,last_tick);
double ask=last_tick.ask;
return ask;
} //--- *

//+------------------------------------------------------------------+
//| CheckProfit: Checks If Last Postion Was Profitable               |
//| I am in HEDGING account.                                         |
//+------------------------------------------------------------------+
bool CheckProfit_MethodA()
{
//-- first open a position, for the exercice:
Trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.01,Ask(_Symbol),0,0);
//-- Immediately get the ticket number:
ulong lastTicket = Trade.RequestPosition();
Print("the last ticket was: " + IntegerToString(lastTicket));
//-- sleep some time
Sleep(4000);
//-- then close this position, to provide some data for coming code:
Trade.PositionClose(_Symbol,3);
//-- Now get the outcome of that position (loss off course):
//--- select history for access
HistorySelect(TimeCurrent()-24*60*60,TimeCurrent());//since yesterday
double lastProfit = HistoryDealGetDouble(lastTicket,DEAL_PROFIT);
Print("and its profit was: " + DoubleToString(lastProfit));
if (lastProfit>0) return true;
return false;
}

I am not even receiving a proper ticket:

The second trial was given in MQL5 forum, and while I get all the profits, how can I be sure that the orders of the loop correspond to the order of opening positions?


void ScanClosedTrades() // Courtesy Diane Minshew
{
HistorySelect(0,TimeCurrent());
ulong  ticket = 0;
double profit;
uint   dealsTotal=HistoryDealsTotal(); 
 //--- Loop for tracking wins losses and lot sizes for trading
for (uint i=0; i < dealsTotal; i++)
{
 if((ticket=HistoryDealGetTicket(i))>0)
 {
  profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
 }
if (profit < 0)
{
 Print("Profit: %f",profit);//profit);
}
}
}

It gives something like this:


Any help?

 

Save/Update that double each time a position closes :

double LAST_TRADE_PROFIT=0;     // global variable

void OnTrade()
{
        static int previous_open_positions = 0;
        int current_open_positions = PositionsTotal();
        if(current_open_positions < previous_open_positions)    // a position just got closed.
        {
                previous_open_positions = current_open_positions;
                HistorySelect(TimeCurrent()-300, TimeCurrent()) // 5 minutes ago up to now :)
                int All_Deals = HistoryDealsTotal();
                if(All_Deals < 1) Print("Some nasty shit error has occurred :s");
                ulong temp_Ticket = HistoryDealGetTicket(All_Deals-1); // last deal (should be an DEAL_ENTRY_OUT type)
                // here check some validity factors of the position-closing deal (symbol, position ID, even MagicNumber if you care...)
                LAST_TRADE_PROFIT = HistoryDealGetDouble(temp_Ticket , DEAL_PROFIT);
        }
        else if(current_open_positions > previous_open_positions) previous_open_positions = current_open_positions; // a position just got opened.
}


if you want to get that LAST_TRADE_PROFIT variable refreshed anywhere outside OnTrade() and OnTradeTransaction() events, you need to load more history, and search through deals differently.

 
OrderCloseTime Expert Advisor MQL5
OrderCloseTime Expert Advisor MQL5
  • 2018.07.03
  • www.mql5.com
Hi, Im looking for a way to retrieve the last closed order/deal/position close time, possibly in datetime...
 

Code2219 or probably 2319 Thanks but it is now working. I made an EA based on your code:


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{ 
for(int i=0; i<5; i++)
{
//-- first open a position, for the exercice:
Trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,0.01,Ask(_Symbol),0,0);
Sleep(4000);
Trade.PositionClose(_Symbol,3);
Sleep(4000);
OnTrade();  // I had to put this here, otherwise no output
}
Sleep(12000);
ExpertRemove();
}
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
{
static int previous_open_positions = 0;
int current_open_positions = PositionsTotal();
 // a position just got closed:
if(current_open_positions < previous_open_positions)   
{
 previous_open_positions = current_open_positions;
 HistorySelect(TimeCurrent()-300, TimeCurrent()); // 5 minutes ago
 int All_Deals = HistoryDealsTotal();
 if(All_Deals < 1) Print("Some nasty shit error has occurred :s");
 // last deal (should be an DEAL_ENTRY_OUT type):
 ulong temp_Ticket = HistoryDealGetTicket(All_Deals-1); 
 // here check some validity factors of the position-closing deal 
 // (symbol, position ID, even MagicNumber if you care...)
 LAST_TRADE_PROFIT = HistoryDealGetDouble(temp_Ticket , DEAL_PROFIT);
}
// a position just got opened:
else if(current_open_positions > previous_open_positions) 
 previous_open_positions = current_open_positions; 
Print ("Last Trade Profit " + DoubleToString(LAST_TRADE_PROFIT));
}



 

you don't need to call OnTrade() from OnTick() !!!

OnTick()
{
    // open/close your positions here as usual
    // OnTrade() will be called automatically with each trade-related operation
}

void OnTrade()
{
        static int previous_open_positions = 0;
        int current_open_positions = PositionsTotal();
        if(current_open_positions < previous_open_positions)             // a position just got closed:
        {
                previous_open_positions = current_open_positions;
                HistorySelect(TimeCurrent()-300, TimeCurrent()); // 5 minutes ago
                int All_Deals = HistoryDealsTotal();
                if(All_Deals < 1) Print("Some nasty shit error has occurred :s");
                // last deal (should be an DEAL_ENTRY_OUT type):
                ulong temp_Ticket = HistoryDealGetTicket(All_Deals-1); 
                // here check some validity factors of the position-closing deal 
                // (symbol, position ID, even MagicNumber if you care...)
                LAST_TRADE_PROFIT = HistoryDealGetDouble(temp_Ticket , DEAL_PROFIT);
                Print("Last Trade Profit : ", DoubleToString(LAST_TRADE_PROFIT));
        }
        else if(current_open_positions > previous_open_positions)       // a position just got opened:
                previous_open_positions = current_open_positions; 
}

Also those Sleeps aren't needed

 

Code2219 or probably 2319

It works. Thank you very much.

 

Hi 

 Allthough its an old thread ,  I'm struggling with this code..

        static int previous_open_positions = 0;
        int current_open_positions = PositionsTotal();
        if(current_open_positions < previous_open_positions)         

Since your set  previous_open_positions  to 0, this "if" is only true when     PositionsTotal() is negative !?!

Can that be possible?

 
grobbrecht:

Hi 

 Allthough its an old thread ,  I'm struggling with this code..

Since your set  previous_open_positions  to 0, this "if" is only true when     PositionsTotal() is negative !?!

Can that be possible?

It is a static variable
https://www.mql5.com/en/docs/basis/variables/static
So it will keep last assigned value. It has, however, a few flaws. First there is no symbol check. But mainly, if the EA is reinitialized with an active trade, it might miss a trade closure.
 

Thanks for the info!

Didnt notice the "static" keyword, nor did I knew of if.

Whats the difference with using a global variable? Don't see any to be honest.


Thanks

 
As a general rule of thumb, the fewer global variables the better. No chances that a change inside of a function affects other functions or naming overlaps.
 

This wont work on a live account!

You have no chance when you do not deal with delayed, async processing. The only chance to get the results is to use OnTradeTransaction(), cause you will face the challenge, that from time to time you wont receive the valid/final results when your EA doesn´t wait for the postponed transaction results. Like that it may work in 80-90% of the cases, maybe less, maybe more, but surely not in all cases!

See: https://www.mql5.com/en/forum/357245

OnTrade/OnTradeTransaction - Are deal results always async?
OnTrade/OnTradeTransaction - Are deal results always async?
  • 2020.12.05
  • www.mql5.com
Hi, since some time I am facing the issue, that after a position was closed/partially closed the deal database does not provide valid results - and...