Topic: Averaging improved modification

My modified version of the EA manages to open additional lots without closing the old position (this is when we want to just add to the position).  However, FST reports that we are still "Long 1 lot" (as the add quantity is 1 lot) no matter how many lots we have open in reality as separate positions. I am not sure if this is by design as FST refers to the last opened lot, or there is a change required in my code.

Re: Averaging improved modification

Nick, please attach your work to the forum.

I'll show you how to make it reporting all lots.

We have to set an virtual position and to report it to FST. FST receives information from both functions:

void GetPing(string symbol)
int SendTick(string symbol)

If there is one position only, these functions have to report it. In case of adding - a virtual posAvrg has to be reported.

This is pseudo code (not tested):

// posAvrg - a virtual position.
// It represents the avreged opened positions
int    posAvrgTicket     = 0;
int    posAvrgType       = -1;// -1 Square, 0 Long, 1 Short
double posAvrgLots       = 0;
double posAvrgOpenPrice  = 0;
double posAvrgStopLoss   = 0;
double posAvrgTakeProfit = 0;
double posAvrgProfit     = 0;
string posAvrgComment    = "Averaged position";

///
/// Sets the posAvrg.
/// Returns 0 or -1 in case of on error.
int SetPosAvrg(string symbol)
{
    int iPositions = 0; // The number of positions for this symbol.
    
    for (int pos = 0; pos < OrdersTotal(); pos++)
    {
        if (!OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))
        {
            Print("Error in OrderSelect: ", GetErrorDescription(GetLastError()));
            Comment("Cannot check current position!");
            return (-1);
        }
        
        if (OrderSymbol() != symbol)
            continue;
        
        if (OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLLIMIT || OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP)
        {   // Forex Strategy Trader doesn't like pending orders.
            string message = "A pending order was found! Forex Strategy Trader cannot control pending orders!";
            Comment(message);
            Print(message);
            return (-1);
        }
        
        if (iPositions == 0)
        {
            posAvrgType       = OrderType();
            posAvrgLots       = OrderLots();
            posAvrgOpenPrice  = OrderOpenPrice();
            posAvrgStopLoss   = OrderStopLoss();
            posAvrgTakeProfit = OrderTakeProfit();
        }
        
        if (iPositions > 0)
        {
            if (posAvrgType != OrderType())
            {   // There is another position in different direction.
                message = "There are more than one open positions! Forex Strategy Trader cannot control more than one position at the same time!";
                Comment(message);
                Print(message);
                return (-1);
            }
            
            if (posAvrgStopLoss != OrderStopLoss() || posAvrgTakeProfit != OrderTakeProfit())
            {   // Wrong SL or TP
                message = "There is open positions with different SL or TP.";
                Comment(message);
                Print(message);
                return (-1);
            }
            
            posAvrgOpenPrice  = (posAvrgLots * posAvrgOpenPrice + OrderLots() * OrderOpenPrice()) / (posAvrgLots + OrderOpenPrice()); // Average price.
            posAvrgLots       = posAvrgLots + OrderLots(); // Sum of the lots.
        }
        
        iPositions++;
    }

    return (0);
}

3 (edited by Nick 2009-11-24 21:23:39)

Re: Averaging improved modification

Hi Miroslav,

thanks for the reply and for the information on virtual position reporting. I will try to implement your suggestion for virtual position reporting. For now, I am attaching the current file that seems to work. These are the modifications (I tried to keep them tidy, but they are not as good looking as your code smile - please note, I have global variable for tickets which I know it's bad practice but I am not too familiar with array handling in MT4, in particular how to pass back an array from a function call):

1. Added function MagicFromSymbol() to auto calculate a magic number depending on the current symbol. I wanted to include this in order send, but then I realised that FST sends an argument with magic number information, so for the moment my MagicNumber is not being used. I would like to know your opinion about this. The idea was to include checking based on magic on each order before modify or close, to make sure it belongs to the EA (in case we are also trading other EA or manually on the same account and symbol).

2. Added array int tickets[] to hold all the tickets of the EA.

3. Added string orderComment to allow me to visually know which trades belong to this EA on the positions log in MT4.

4. In GetPositionTicket(string symbol) removed the check for positionTicket != 0 so that we can have more than 1 position without reporting error. The same in OpenNewPosition () function.

5. Modified  CloseCurrentPosition() to close all positions on this symbol (hopefully later can include check against magic too as I mentioned in (1)).

6. In ClosePosition() I added color of arrow to visually show in MT4 where the position was closed.

7. In AddToCurrentPosition() removed the call to close position function.

8. In ReduceCurrentPosition() I removed call to open new position, and modified the number of lots for the close position function (I haven't tested this).

9. In ModifyPosition() for Stop Loss and Take Profit, cycling through all orders to modify them (haven't tested this).

10. In AdjustTrailingStop() same as (9) above.

11. Added function GetPositionTickets(string symbol) to populate the array of tickets (I should have modified this to return void really...)

12. In OpenNewPosition() I changed the OrderSend to send 0 TP SL and modify them with OrderModify, because my broker requires this. I added 10 retries to open order with Sleep(500), error checking for Context Busy. Also I wanted to add some code to check for invalid stop loss/TP, because it can happen sometimes (especially with the confusion between 4 and 5 digits brokers or in case there are incorrect settings for the instrument in FST), but this code is commented out for now cause I haven't had the chance to check it.

13. Added function CountOpenOrders()

I am sure my code can be improved and things can be done better, maybe some more error checking, but I hope it helps a bit.

Thanks

4 (edited by Nick 2009-11-25 00:11:15)

Re: Averaging improved modification

I have added virtual order reporting (used weighting according to lots relative to total lot size). I checked with some print statements that the position type is reported correctly and  that the rest positions are averaged correctly (I have already some sell trades open and the EA identifies them as virtual type 1)

I hope this helps.

PS: the forum time is off by 1 hour (shows 1 hour more than it should be).

Edit: hopefully fixed the single order error

Re: Averaging improved modification

First thank you for the detailed change log.

I downloaded successfully your expert and I'm going to test it.

Re: Averaging improved modification

I didn't check your code thoroughly yet but it looks promising at first glance.

Some issues:
- when you attach expert on a chart with one open position the expert doesn't reports properly to FST (the "start execution" button changes to grey). The same is when you open your very first trade on FSB.

- When adds to a position(s) the expert must change the SL and TP of all the previous opened positions. All positions must be with equal SL and TP and that has to be reported to FST.

- When you reduce a position the expert closes all opened positions instead only one with the same lots. If there is no position with the same lots, the expert must close some other and to open a new with lots = oldLots - reducingLots.


Edit:

Check all the operations with different lots, SL and TP manually. If they work manually, the will work automatically also. The only problem I see is the necessary time for managing multiple orders.

PS

It's nice you have added some error checks and a cycle for order execution.

7 (edited by Nick 2009-11-25 00:12:10)

Re: Averaging improved modification

thanks Miroslav,

nice observations. I will look into these issues and let you know.

Edit: I updated the file in the post above with what I think fixes the single order error. Can't test it right now, but will test later and will try to implement the other suggestions.

Thanks

Re: Averaging improved modification

1. Added function MagicFromSymbol() to auto calculate a magic number depending on the current symbol. I wanted to include this in order send, but then I realised that FST sends an argument with magic number information, so for the moment my MagicNumber is not being used. I would like to know your opinion about this. The idea was to include checking based on magic on each order before modify or close, to make sure it belongs to the EA (in case we are also trading other EA or manually on the same account and symbol).

FST doesn't use the magic number. It only copies and resends it. My idea was one to be able to trade manually together with FST. Manual and automated trade at the same as a collaboration. FST is stateless and adopts the trading according to the current environment. It loads account, market and positions info at every tick/ping. So a trader can execute an entry manually (from FST or from MT) and FST to close it according to the strategy. Or  a trader can close the automatically opened position without problems.  Thinking in that direction FST should know about all the opened positions for the symbol. But if you want you can make exceptions (special magics) that makes a position(s) invisible for the program.

Re: Averaging improved modification

sounds good. I think we can add an option to the EA, if user wants the EA to specify magic then it will handle it's own trades, otherwise it will be like now, all trades on the symbol.

Thanks!

10 (edited by Nick 2009-11-25 03:24:13)

Re: Averaging improved modification

Popov wrote:

- When adds to a position(s) the expert must change the SL and TP of all the previous opened positions. All positions must be with equal SL and TP and that has to be reported to FST.

So for example, if we buy 1 lot at 1.5100 with SL 10 pips lets say SL will be 1.5090 (lets ignore spread for now).

Then if the price goes to 1.5200 and we want to add 1 more lot, the 2nd position SL (for 10 pips SL) will be 1.5190.

At this moment, the EA will report back 1 virtual position of price the average of the 2 entries = 1.5150, and virtual SL the average of the 2 SL = 1.5140. So the FST sees 1 virtual order.

So what is the problem with this? because I can't understand why we need to change the previous order SL smile

Or maybe it's wrong to report back the average of the 2 as entry price, and we should report the first order entry only as order entry price, just with increased lot size = the total lot size? How is this best to match the engine of FSB? (I mean to make the real execution as close to the backtest as possible). I dont know how FSB handles an order when we have added to it. Which is the combined order open price and SL/TP?

Thanks

Re: Averaging improved modification

Mod 4.

I made modifications to fix the problem with the partial orders close in position reduction mode, fix the problem of single order management, and allow the user to limit the EA to its own orders only (with extern parameter).

I think the position reverse needs looking into as well, not sure it will work as it is.

This is an untested version.

Re: Averaging improved modification

One simple thought. If you change the EA to act differently than it acts currently meaning - each position is open by closing the previous one with its own SL and TP then the FSB should be changed accordingly. Else you will end up with a strategy tested in a way by the FSB and traded differently by the FST. It is a recipe for disaster. I am using FST in live and works ok. My main issue is the imposibillity to trade multiple pairs. I am trading two pairs now and I am using two computers for it. That is why I salute your magic number initiative. But how can I run on the same PC two instances of the FST? I thik Mr. Popov will be the only one to help with this.

Anyhow , great work so far!

Re: Averaging improved modification

Yes you are right, the SL handling is not quite there yet in my mod, and it is a problem if the strategy uses them. For now I just design my strategies without SL and TP, I never liked them anyway. At some point I hope to look into more detail about how the backtester treats the combined SL/TP and modify the mod accordingly, unless someone else does it before me smile

Mr Popov is already looking into multiple pairs, I believe will be possible soon. There is another topic for that smile

Re: Averaging improved modification

Years ago when I've started FSB development I was in front of the dilemma how to treat SL and TP.
Finally I decided that the SL and TP have to be readjusted at every adding or reducing. My logic was:

The strategy must be objective and to analyze the market at the exact moment of entry. That decision includes the entry direction, the entry price (or time), trading size, SL and TP. The strategy should look at the market only when rises a signal. But several situations are possible depending on what our position was just before the signal.

Let say we have a buy signal and the present position was:

- Square: We open new long position;
- Long: We add to the current position;
- Short: (Depending on the lots) - Reducing, Closing or Reversing.

The user can decide how the strategy to react on these situations by changing the same/ opposite signal options but the important is that the logic behind these signals is the same. So the SL and TP have to be readjusted at every execution. That's why I requested the SL and TP to be changed for the previously opened positions in the Nick's code. SL and TP have to be equal for all positions and have to be readjusted after adding, reducing, trailing stop move or manual SL/TP modification from FST.

Please note that FST doesn't modify SL / TP during automatic trade. SL/TP are set at entry only. An exception is Trailing Stop but it's code is in the expert.

Actually FSB deals with SL/TP in different way. It sends OCO stop and limit pending orders to every open position and OCO stop and limit IF orders to the pending orders. (You can see these orders in the FSB's journal). On the other hand FST uses SL/TP features of MetaTrader. The end result is the same. The only problem is the unavailability of MT to add to a position.

FSB averages the price of a position after adding and sets new SL and TP. The current Nick's code leaves the SL/TP of the previously opened position unchanged. That may result in closing of these positions at their SL / TP which will be a reduction of the virtual averaged position. That reduction will not be because of an opposite  entry signal like in FSB.

I'm not sure how MT will deal with multiple OrderModify() and OrderClose() in case of 10-20 positions. Probably it will be OK. We'll see it soon.

Re: Averaging improved modification

Let me show you in a live account how the orders are taken. I am usin a fixed 100 pips stop and a fixed 176 TP. I am usind add as the Same direction signal. As I was saying the FST is setting these TP and PL at each order independently. It does not keep the TP and SL set by the fisrt order. I truly hope that FSB is acting in the same way. Else I will have to rethink the strategy. Thank you.
http://s3.postimage.org/1qAdiA.jpg

Re: Averaging improved modification

Probably we can workaround SL/TP modifications. It's possible SL / TP to be saved in the  global posAvrgStopLoss and posAvrgTakeProfit at every signal from FST. At the same time to send  OrderSend without SL and TP. After that a function CheckSLandTP(symbol) to be called at every tick.

prototype:

int CheckStopLossAndTakeProfit(symbol)
{
   if (posAvrgType == Long)
   {
      if(posAvrgStopLoss  > 0)
         if(MarketInfo(symbol, MODE_BID) < posAvrgStopLoss + Point / 2)
            CloseAll();
      if(posAvrgTakeProfit > 0)
         if(MarketInfo(symbol, MODE_BID) > posAvrgTakeProfit - Point / 2)
            CloseAll();
   }
   
   if (posAvrgType == Short)
   {
      if(posAvrgStopLoss  > 0)
         if(MarketInfo(symbol, MODE_ASK) > posAvrgStopLoss - Point / 2)
            CloseAll();
      if(posAvrgTakeProfit > 0)
         if(MarketInfo(symbol, MODE_ASK) <  posAvrgTakeProfit + Point / 2)
            CloseAll();
   }
}

Pros:
  - it is not necessary to modify SL and TP at every adding or reducing

Cons:
  - The orders haven't got SL and TP. That is dangerous because of possible failure of the net connection or software.

Re: Averaging improved modification

Hi Miroslav,

thanks a lot for your explanation, it really helps a lot. I will go through everything in detail and try to come up with an implementation on what you suggested.

For me, the possibility of having the EA close and reopen the trades is not an option as the spread cost is way too much for my taste, so for sure it has to be a solution based on the virtual position and partial close/open of orders.

One thing I observed on my currrent mod 4 is as you said, the time it takes to handle 20 orders is quite a lot, and some of them close several minutes appart for some reason. So some work needs to be done in that front too, I checked my code and I believe there is some redundant code that might be causing the extra delay. I will post here any progress I make.

Thanks.

Re: Averaging improved modification

I'm closing this thread since a proper averaging is included in the distributed expert.