Typical mistakes and how to deal with them when dealing with the trading environment - page 2

 

fxsaber:

The function that indicates the need for a wrap is marked in red. Its problem is described here. Some may recall that this is an ancient problem of position reopening, which in ancient times was solved by Sleep, waiting for the position to open after OrderSend. But in fact, this problem has nothing to do with OrderSend. You must be able to correctly read the trading environment.

The right one is a simple example.

The order list, like the list of positions, is not updated instantly. I think we can't do without Sleep-crutch.

Probably more correct is OnTradeTransaction

 
Aleksey Lebedev:

The list of orders, like the list of positions, is not updated instantly. imho, we can't do without Sleep-crutch.

Probably, it would be better to use OnTradeTransaction.

If there is a problem waiting for environment update, how can Sleep help? It will either help or not.

So, the approach should be from the other side: after sending an order to open a position or set a pending order, we should wait for the result and not send any more orders to open or set. Then we need a flag that we ourselves manage instead of trusting to Sleep that only gives delay of program execution but does not check the result of a trade request sent by the program itself that must know what to do after that - to set a flag and work according to the logic of results waiting. After waiting for the result, the flag is removed.

 
Artyom Trishkin:

Question: What will happen if after sending a trade order until the next tick the market order is not placed by the server?

It will be exactly the same as on MT4 - if there is nothing, it will not be counted.


There can be several reasons for such a trade order

  1. Third-party OrderSend or OrderSendAsync - not from the program in which we read the trade environment. It may even be not from the terminal in which the program is running. In this case, nothing can be done. Everything is the same as in MT4 in such situations.
  2. OrderSend or OrderSendAsync - are started from the program in which the trade environment is read. In the case of OrderSend, everything is clear, as OrderSend will finish its execution with a clear result. In case of OrderSendAsync we can do two things - pass data to next events according to the first paradigm, or do OrdersAsyncWait() (I don't have the code), as it is done in a regular asynchronous data transfer simulation in MT4 (multiple threads implementation).
I should probably say a few words about OrderSendAsync in MT4. At any stage of program execution it is possible to see how busy a corresponding trade thread is and what exactly it is doing. In this sense, custom asynchrony in MT4 gives us much more possibilities than the MT5 one. But in MT4 it is implemented by running "clients" on each chart, i.e. expensive. In MT5 it is possible to write the same functionality and even without a lot of charts - running the script on an OBJ_CHART object, but there will still be a slight delay. I.e. OrderSendAsyncCustom will be slightly slower than OrderSendAsync, but it will still be much faster than OrderSend + all advantages of custom implementation.
 
Aleksey Lebedev:

The list of orders, like the list of positions, is not updated instantly. imho, we can't do without Sleep-crutch.

Probably, it would be more correct to use OnTradeTransaction

MqlTradeTransaction may be needed only when choosing the appropriate paradigm when working with OrderSendAsync. In other cases, OnTradeTransaction == OnTrade in sense and plays no more role than OnTick or OnTimer.


Forum on trading, automated trading systems and strategy testing

Typical mistakes and how to fix them when working with a trading environment

fxsaber, 2018.02.19 22:36

There are two paradigms of working with the trading environment, writing EAs.

  1. Event inputs (OnTick, OnTimer, etc.) depend on each other. There is information that MUST have between events (not for speed, like cache, but for usability). For example, we need to save OrderSendAsync result and use it in OnTradeTransaction. Caches are NOT mandatory information and are used only for speeding up. That's why we don't consider them right away.
  2. Event inputs (OnTick, OnTimer, etc.) are NOT dependent on each other. Each input is from scratch. Roughly like a Script that you run yourself on each event.

Highlighted denotes that the same trade code is run in each On-function. The corresponding non-trading code completes everything else.

 
fxsaber:

It will be exactly the same as on MT4 - if there is nothing, it will not be counted.

That is - on the next tick the program sends a new request for opening. As a result, we have the same problem - multiple openings.

The Expert Advisor should have the following logic:

  1. We get a signal to open a position or set a pending order
  2. Check the number of orders/positions, if there is no signal to open a new position - exit (to point 1).
  3. Check the server response waiting flag:
    1. Flag is up - exit (to step 1)
    2. Flag omitted - continue
  4. The flag is omitted - send a trade order (the number of attempts is limited) and check the return code
    1. The order has been executed - set the wait flag
    2. Order failed - call call trade order correction function and go to point 4
  5. Wait flag is raised - check change of trade environment
    1. Trade Environment has not changed - exit (to step 1).
    2. Environment has changed - a pending order is placed or a position is opened - remove the wait flag and exit (to step 1).
 
Artyom Trishkin:

That is, on the next tick, the software sends a new opening request. As a result, we have the same problem - multiple openings.

It would be good to read the entire post.

The EA should have the following logic:

  1. We have received a signal to open a position or set a pending order
  2. Check the number of orders/positions, if there is no signal to open a new position - exit (to point 1).
  3. Check the server response waiting flag:
    1. Flag is up - exit (to step 1)
    2. Flag omitted - continue
  4. The flag is omitted - send a trade order (the number of attempts is limited) and check the return code
    1. The order has been executed - set the wait flag
    2. Order not executed - call function correct trade order and go to point 4
  5. Wait flag is raised - check change of trade environment
    1. Trade Environment has not changed - exit (to step 1).
    2. Environment has changed - a pending order is placed or a position is opened - remove the wait flag and exit (to step 1).

The wait flag is only available for the second case and OrderSendAsync. For OrderSend, the wait flag is not needed at all. OrderSendAsync without waiting flag is OrdersAsyncWait().

You can check any theory in practice.

Guided by practical results.
 
fxsaber:

It is a good idea to read the post in full.

The wait flag is only possible for the second case and OrderSendAsync. For OrderSend the wait flag is not needed at all. OrderSendAsync without waiting flag is OrdersAsyncWait().

Any theory can be tested in practice

I am guided by practical results.

Well, I wrote for asynchronous mode. With synchronous you don't need to wait - the result is already there in the query response.

 
Artyom Trishkin:

Well I wrote for asynchronous mode.

A detailed answer was given from the beginning.

 
fxsaber:

An extended answer was given from the beginning.

I must have read it badly :)

Didn't see any steps in it to get around the multiple discovery error. Only general "paradigms" ;)

That is why I have outlined the approximate logic, which is redundant - the flag is checked in a function (wrapper) that opens positions / sets pending orders. Or maybe in the signal tracking function as well.

You have to think about the best way.

 
Artyom Trishkin:

the flag is checked in the function (wrapper) of opening positions/placement of pending orders. Or maybe in the signal tracking function as well.

I much prefer the solution via OrdersAsyncWait(), when the exit from On-function is always done without hanging state. Then the next reading of the trading environment with a clean slate is as relevant as possible.

Using OrderSendAsync should always be appropriate. The only situation where it can happen is sending several (> 1) trade orders, independent of each other, on the same signal. Therefore, the OrderSendAsync thing never makes sense in all other cases.


SZZY There is a separate topic where OrderSendAsync is very relevant - multi-advisors: several independent TS in one Expert Advisor. The OrderSend is rarely suitable there and even OrderAsyncWait( const string Symb) is not good since no Sleep is allowed in principle.

Reason: