Search code examples
mql4

Store values in struct


I am trying to save OrderProfit, HighestProfit, LowestProfit of my orders in a struct

I define it like this, as a global variable

struct OrderStats {
  string ThisOrderTicket;
  double CurrentProfit;
  double HighestProfit;
  double LowestProfit; 
};

Within my method, I instantiate my struct like this

// insert order stats into struct
string OrderTicketStatsName = StringConcatenate("OrderTicketStats-", OrderTicket());
string OrderTicketStats = OrderTicketStatsName;

OrderStats OrderTicketStats={};
OrderTicketStats.ThisOrderTicket = OrderTicketStatsName

I then check my previously saved data with

// current profit
if(DEBUG) {
    Print("CheckForClose ",OrderTicket(), ":", OrderTypeByName, " : Struct Name is: ", OrderTicketStats.ThisOrderTicket);
    Print("CheckForClose ",OrderTicket(), ":", OrderTypeByName, " : Previous OrderProfit is: ", OrderTicketStats.CurrentProfit);
    Print("CheckForClose ",OrderTicket(), ":", OrderTypeByName, " : Previous OrderProfit is: ", OrderTicketStats.HighestProfit);
    Print("CheckForClose ",OrderTicket(), ":", OrderTypeByName, " : Previous OrderProfit is: ", OrderTicketStats.LowestProfit);
    Print("===================================================");
}

And finally, I set my data like this

if(OrderTicketStats.ThisOrderTicket == OrderTicket()) {
    OrderTicketStats.CurrentProfit=OrderProfit();

    // highest profit
    if(OrderProfit() > OrderTicketStats.HighestProfit) {
        OrderTicketStats.HighestProfit = OrderProfit();
    }

    // lowest profit
    if(OrderProfit() < OrderTicketStats.LowestProfit) {
       OrderTicketStats.LowestProfit = OrderProfit();
    }
}

This always produces,

CheckForClose 2:SELL : Struct Name is: OrderTicketStats-2
CheckForClose 2:SELL : Previous CurrentProfit is: 0
CheckForClose 2:SELL : Previous HighestProfit is: 0
CheckForClose 2:SELL : Previous LowestProfit is: 0
===================================================
CheckForClose 2:SELL : CurrentProfit is: -0.24
CheckForClose 2:SELL : HighestProfit is: 0
CheckForClose 2:SELL : LowestProfit is: -0.24
===================================================

See how it resets the Previous values? How can I get my previous data to stick?

UPDATE

I have edited my code, and now have this:

OrderTicketStats = OrderTicket();
OrderStats OrderTicketStats;

if(OrderProfit() > OrderTicketStats.HighestProfit) {
                    OrderTicketStats.HighestProfit = OrderProfit();
                }
if(OrderProfit() < OrderTicketStats.LowestProfit) {
                    OrderTicketStats.LowestProfit = OrderProfit();
                }

The problem I have is this: I want to save a trades LowProfit, HighProfit to understand the profit extremes and order goes through. I open multiple orders at the same time, and I then go over my log to see the influence of that.

Currently, I see this:

EURUSD,M15: ===================================================
EURUSD,M15: CheckForClose 1:BUY : OrderTicketStats for: 1
EURUSD,M15: CheckForClose 1:BUY : OrderProfit is: -5.54
EURUSD,M15: CheckForClose 1:BUY : OrderProfit High is: 0
EURUSD,M15: CheckForClose 1:BUY : OrderProfit Low is: -5.54
EURUSD,M15: ===================================================
EURUSD,M15: CheckForClose 3:SELL : OrderTicketStats for: 3
EURUSD,M15: CheckForClose 3:SELL : OrderProfit is: 1.3
EURUSD,M15: CheckForClose 3:SELL : OrderProfit High is: 1.3
EURUSD,M15: CheckForClose 3:SELL : OrderProfit Low is: -5.54

Notice how OrderProfit Low for trade 3 is the same as trade 1. That's my issue


Solution

  • First of all, please keep in mind that structures can keep float(double), long(int,short), enum and other struct of the same kind. If you have string as a field of your struct, you cannot pass it by reference, you cannot copy it, and you can also expect to have unexpected problems with it. It may fail to compile, it may compile but not work, it may work but incorrectly. If it is not too late, change struct to class and you have no limitations with it (an instance may be of POINTER_INVALID or NULL, of course, so knowledge of classes is needed). Moreover, you do not need to develop arrays to store some number of instances, CArrayObj is already there. Also, you can create a new instance by passing required parameters.

    Second point is about the logic. Could you please explain how do you expect this line to work
    if(OrderTicketStats.ThisOrderTicket == OrderTicket()) {
    In my view, ThisOrderTicket is a string that has some chars before ticketId, OrderTicket() is an integer ticketId. So the condition you wrote is never true. I would suggest to declare int orderTicket within the struct, remove the string field as useless, and initialize by
    structInstance.orderTicket=OrderTicket() etc.