Database to remember trades?

 

I have an EA that closes off half the lot of a trade once a target profit is reached.

I would like the EA to remember which order it has already closed so it doesn't close it again.

I think the only way I can do this is to save the data in a database (ticket number) and have it check the table first.

Is this true? Variables can only be kept for 4 weeks and every time I close MT4, it will forget the variables.


Does it work with PostGresSql?


...or perhaps save the ticket to a text file?

 

SM

You have OrderHistory to look at?

Also you could write results to a text file at OrderClose time, so that the info is not volatile?

FWIW

-BB-

 
BarrowBoy:

SM

You have OrderHistory to look at?

Also you could write results to a text file at OrderClose time, so that the info is not volatile?

FWIW

-BB-

Processing a text file is going to be time consuming after a long time with lots of trades whereas a MySQL database could look up the information quickly?

When closing half an order, does it create a new ticket for the order? It is this new ticket that I don't want the EA to change. I don't believe OrderClose returns the new ticket number?

 

SM

> Processing a text file is going to be time consuming after a long time with lots of trades

Depends how much of the file is relevant?

Maybe it could be trimmed once a day?

In any case, indexing on the relevant columns would be needed to speed up any database search

SQL Server has been hooked up to MT already, see 'Integrating MetaTrader 4 Client Terminal with MS SQL Server'

The Express edition of SQL Server is free, see http://www.microsoft.com/express/sql/download/

For ticket hints see 'Retrieve new ticket number after partial close ?'

Good Luck

-BB-

 
SanMiguel:

Processing a text file is going to be time consuming after a long time with lots of trades whereas a MySQL database could look up the information quickly?

Largely just agreeing with what BarrowBoy has said, plus a slightly different perspective...


If you're forever going to be appending to the text file, and effectively replicating MetaTrader's own trade history, then by far the fastest option is simply to use MetaTrader's trade history.


If you're just storing "state" (e.g. continually overwriting a file rather than appending) then sensible use of a text file is going to be significantly faster than any proper database which implements ACID, a security infrastructure etc, particularly because there's something of a speed penalty in calling DLLs from MQL.


 
SanMiguel wrote >>

Processing a text file is going to be time consuming after a long time with lots of trades whereas a MySQL database could look up the information quickly?

When closing half an order, does it create a new ticket for the order? It is this new ticket that I don't want the EA to change. I don't believe OrderClose returns the new ticket number?

NO, it does not.

The EA must traverse Trade Pool list for the order created with the remaining volume.

How?

this is where the Magic# enters.

---1. the original order MUST have unique Magic# (IF you may have more than one order open at any one time EACH Magic# MUST be UNIQUE)

Why? it is the only clue you have to ident the order (see 2. below)

---2.

A. OrderOpen(....,totalVolume,...,MAGIC.123,...) returns value: ticket.X

B. OrderClose(ticket.X,...,partialVolume,...) returns TRUE if does the close.

C. A new order will be opened with the remainingVolume (totalVolume minus partialVolume) AND... the ONLY information it will carry over from the partClosed order "ticket.X" is the Magic# "MAGIC.123" (NOTE:comment field is NOT seen in new order...)

D. YOU must manually search Trade Pool for an order with "MAGIC.123".

E. When you find it, the OrderTicket() of that OrderSelect(..)'d Trade Pool entry will be the newly created remainingVolume order...

.

BUT... guess what, as in all things client/server based, it is very possible that should either the server have nervous breakdown or your line goes down or whatever, that the Client Terminal will not have any record of this newly created remainingVolume order...

.

That is when a totally robust EA will/must enter a retry/sleep loop - polling Client Terminal via doing D. above. Eventually, either you find the order with MAGIC.123 because the Client Terminal has begun to talk to the server and refresh it's data structures OR a sensible time has expired + the line is up etc, BUT no order found.

.

Errors which give you a clue as to comms status: ERR_NO_CONNECTION, ERR_TRADE_TIMEOUT

below is what can happen...

.

/*Timeout for the trade has been reached.
Before retry (at least, in 1-minute time), it is necessary to make sure
that trading operation has not really succeeded (a new position has not
been opened, or the existing order has not been modified or deleted,
or the existing position has not been closed)
Ref: MQL4 Reference - Trading functions - Execution errors*/
/*
https://www.mql5.com/en/forum/45597
Slawa 16.05.06 10:49

It is easy.

Each trade operation
(send market or pending order, modify market or pending order, close market order, delete pending order)
passes 3 stages:
1. request to server
2. processing by server
3. answer from server

Client must wait for answer from server. Server answers OK or some error code.
But in the case of broken connection or network problems client can wait infinitely.

Network subsystem of the client terminal generates timeout error after few minutes to avoid endless waiting.

We do not know exactly on which stage (1 or 3) network problems appeared.
Therefore after timeout error you need to check whether your request processed by the server or not
*/

 
fbj wrote >>

NO, it does not.

The EA must traverse Trade Pool list for the order created with the remaining volume.

How?

this is where the Magic# enters.

---1. the original order MUST have unique Magic# (IF you may have more than one order open at any one time EACH Magic# MUST be UNIQUE)

Why? it is the only clue you have to ident the order (see 2. below)

To create a unique magic order number, don't you have to use a database? How do we know the magic order number hasn't already been used?

We need to keep state somehow?

 

Have you started reading the docs yet???
Not attempting to be cute here, but this is very basic programming concept and seriously advise consider reading book or something about programming.
maybe even: https://book.mql4.com/variables/types

Hint: Your 'database' can be EA globally scoped declarations...
Therefore, EACH new order has the next order# eg, 1,2,3,4,...

Then just tack onto the EA id

long as EA id is UNIQUE then each order will also have UNIQUE magic#

 
fbj wrote >>

Have you started reading the docs yet???
Not attempting to be cute here, but this is very basic programming concept and seriously advise consider reading book or something about programming.
maybe even: https://book.mql4.com/variables/types

Hint: Your 'database' can be EA globally scoped declarations...
Therefore, EACH new order has the next order# eg, 1,2,3,4,...

Then just tack onto the EA id

long as EA id is UNIQUE then each order will also have UNIQUE magic#

Variables are only stored temporarily and even global variables lose their value after 4 weeks!

With a database, this is easy, but some advised not to use a db above.

How do we generate a unique magic order number each time without using a database?

1. So I create an order through a script assigning a magic number, which also takes the ticket number, e.g 0.2 lots ticket number 123456, magicnumber 1.

2. Half the trade is closed at a certain point.

3. A new ticket number is created with half the lot, but the same magic number by the broker, eg 0.1 lots ticket number 123457, magicn umber 1.

4. I can now search the history for the magic number 1, find the lot size of 0.2 and leave any new orders with magic number 1 and lot size 0.1 alone - the script will now ignore them.

5. I create another new order for 0.2 lots ticket number 654321, magicnumber - how do I get the magicnumber here? Do I have to scroll through all the history and find the highest magic number and add 1 - time consuming. Wouldn't a database with a unique ID create this much more quickly and efficiently for me? It can also store the ticket numbers.

 

SanMiguel, MT4 keeps the value of the global variable at the client terminal for 4 weeks since the last access.

Code to generate a sequence number which i store in OrderComment() leaving OrderMagicNumber to uniquely identify all orders of a particular EA.


double SeqNum() {
  double dSeqNum=1;
  string sName=StringConcatenate(AccountServer(),"_SequenceNumber");
  
  if(GlobalVariableCheck(sName)) {
    dSeqNum=GlobalVariableGet(sName)+1;
    if(dSeqNum==1) dSeqNum=-1;
  }
  if((dSeqNum>0) && (GlobalVariableSet(sName,dSeqNum) == 0)) dSeqNum=-1;
  if(dSeqNum==-1) Print(sName," error ",GetLastError());
  return(dSeqNum);
}
 

SanMiguel. You need to listen to the good advice from BarrowBoy and fbj.


Remember that MQL4 is a programming FRAMEWORK not just a programming language.


Good programmers attempt first to reuse rather than reinvent. Sorry for sounding patronizing here.


You will find yourself in a world of pain which is all your own making if you continue what I think you are doing which is to attempt to reinvent the wheel without first taking the time to appraise yourself a) that the wheel exists b) how it behaves and c) how to use it.


Use the inbuilt order history to access persistent order data without the overhead of having to manage it.


Use your own flat files when you need to persist state information which is specific to your own EA - eg. to provide unattended recovery from sudden outage of your PC.


Have a look at some of the code snippets on this forum to learn how to leverage magic numbers. Only use magic numbers if necessary to identify orders. Do not add the management overhead in the situation, for example, where an EA only ever 'owns' one open order.


Make your code modular and make those modules reusable.


Keep an open mind. There are folks on here who know a great deal about MQL4 and program design.

Reason: