How to check if last three orders were in loss? - page 3

Alain Verleyen
41528
Alain Verleyen  
nicholishen:

So you're going to completely rewrite multi-layer nesting blocks any time you need to work with sorted history? Have fun with that. ... let's see you analyse the last 10 orders......

Let's see when someone will use your code and it will take 20 hours to backtest instead of 1 hour.

The example I provided could be generalized, using OOP for example, or not, to produce efficient code working with any X last orders. A good exercise for you

Why is it so hard for you to admit you could have been wrong ?

nicholish en
2750
nicholish en  
Alain Verleyen:

Let's see when someone will use your code and it will take 20 hours to backtest instead of 1 hour.

The example I provided could be generalized, using OOP for example, or not, to produce efficient code working with any X last orders. A good exercise for you

Why is it so hard for you to admit you could have been wrong ?


Meh, I use MT5 for that... 20 hr backtest is 5 minutes in the cloud.


As far as live goes, that's why you separate account maintenance from your hot-path. Hot path says do I meet the price requirements set for me on the last tick? If no then do slow stuff for next tick.

JC
1674
JC  
Alain Verleyen:

Let's see when someone will use your code and it will take 20 hours to backtest instead of 1 hour.

I wouldn't suggest using something like the following for general purposes, because the speed gain is too trivial compared to the ugliness of the code, but...

Anything which uses built-in MQL functions is likely to outperform anything written in MQL itself. If all you want is a complete list of tickets sorted by time, then something old-school like the following is going to be hard to beat on speed:

   int ct = OrdersHistoryTotal();
   long arr[][2];
   ArrayResize(arr, ct);
   
   for (int i = 0; i < ct; i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
         arr[i][0] = OrderOpenTime();
         arr[i][1] = OrderTicket();
      }
   }

   ArraySort(arr);
   
   // Array is now sorted by time. Each ticket is in arr[x][1]

For a list of 1000 historic trades, a very rough-and-ready benchmark says:

  • Approx 200 microseconds for the above code
  • Approx 500 microseconds for something using an array of objects and a generic quicksort algorithm
  • About 10,000 microseconds for CList and CList.sort()
Alain Verleyen
41528
Alain Verleyen  
JC:

I wouldn't suggest using something like the following for general purposes, because the speed gain is too trivial compared to the ugliness of the code, but...

Anything which uses built-in MQL functions is likely to outperform anything written in MQL itself. If all you want is a complete list of tickets sorted by time, then something old-school like the following is going to be hard to beat on speed:

For a list of 1000 historic trades, a very rough-and-ready benchmark says:

  • Approx 200 microseconds for the above code
  • Approx 500 microseconds for something using an array and a generic quicksort alogrithm
  • About 10,000 microseconds for CList and CList.sort()

Of course.

Taking your numbers, supposing they are exact as I didn't check, my point is to say that 50 times slower using CList is completely unacceptable. For me it's clearly bad OOP usage. If anyone is happy with it, fine.

And just to be complete, the code I posted is just to be compared to nicholishen OOP implementation, I will not use such code on each tick as there is no point to read all history on each tick.

JC
1674
JC  
Alain Verleyen:

my point is to say that 50 times slower using CList is completely unacceptable.

I'm not familiar with CList. I may be doing something wrong with it (though I have only copied and pasted nicholishen's code). But the performance of its Sort() seems to be very poor compared to the other alternatives because of the overheads of a linked-list rather than an array.
JC
1674
JC  
JC:
But the performance of its Sort() seems to be very poor compared to the other alternatives because of the overheads of a linked-list rather than an array.

... So, if you are not maintaining a permanent list of orders, it seems preferable to use an array rather than anything else. If you are maintaining a list of orders across ticks, and occasionally want to sort the list, then it seems far more efficient to use something like ydrol's excellent hashtable where you can quickly get the contents out into an array (e.g. using my templated additions) and then sort them there, rather than doing the sort within the list. (And, for persisting use, it's generally going to be far more useful and efficient to have a hashtable, indexed by order ticket, than an unindexed CList.)

nicholish en
2750
nicholish en  

Alain, you are forever trying to instigate a dick measuring contest with me by comparing my over-simplied, un-optimized, and non-production examples to more complex production-code. I didn't want to overwhelm OP by uploading my production library, but rather post a simple example for OP to start with. Since we have relegated to measuring dicks, how about you benchmark my actual production code? 

#property strict
#include <MQL4OrderPool.mqh>
#define MAGIC 0
void OnStart()
{
   MQL4OrderPool pool;
   pool.Init(_Symbol,MAGIC,MODE_HISTORY,ORDERS_FILLED,SORT_CLOSE_TIME_DESCENDING);
   
   ulong smsc = GetMicrosecondCount();
   for(int cnt = 0;cnt<1000;cnt++)
   {
      int losses=0;
      pool.Refresh();
      for(int i=0;i<pool.Total();i++)
         if(pool[i].OrderProfit() < 0.0)
            losses++;
         else break;
   }
   ulong emsc = GetMicrosecondCount();
   Print("Bench nisholishen (production example): ",emsc-smsc," µs 1000 iterations.");
}
//+------------------------------------------------------------------+
nicholish en
2750
nicholish en  
JC:

... So, if you are not maintaining a permanent list of orders, it seems preferable to use an array rather than anything else. If you are maintaining a list of orders across ticks, and occasionally want to sort the list, then it seems far more efficient to use something like ydrol's excellent hashtable where you can quickly get the contents out into an array (e.g. using my templated additions) and then sort them there, rather than doing the sort within the list. (And, for persisting use, it's generally going to be far more useful and efficient to have a hashtable, indexed by order ticket, than an unindexed CList.)


That's exactly what I do in my production lib... I don't use a hash table because I don't want static keys and only one way to sort the pool for each initialization... Have a look at my mqh above, and I would appreciate any constructive feedback. 

Anwar Ben
62
Anwar Ben  

Ill have to disagree with you there.

As someone who knows a few languages but is currently learning MQL5 and all of its quirks. eg Why the hell did they not just build the solution to correct win loss history into their std lib?

I have to say this there is no point debating any of this between yourselves without providing easy to understand code which can be implemented easily by an OP who obviously needs some guidance.

The amount of time I have spent on here sorting through dross to try and find a simple solution to a simple question which has been asked by many before me is ludicrous.

Over-Simplified, Un-Optimised, Non-Production examples are all well and good if the reader knows how to fill in the blanks. But if they did chances are they wouldn't be asking.

I DO NOT expect other busy coders to do my work for me by providing snippets I can then Frankenstein into an EA. It would be awesome to have more //COMMENTS & DESCRIPTIONS// to aid the learning process.

Often the answer has been provided by three of four people in different ways depending on their preferred formatting and scripting preferences. ALONG with solutions which can "should" be able to be pulled direct from the reference material.

Of all so far @JC hit it on the head as far as ease of comprehension goes. The reason for that was BECAUSE it was OVER_SIMPLIFIED, ELEGANT and not at all hard to add functionality to or add it to an existing program. 

Alain was right to query your code as were you of his tower of babylon-esque nested indents. However I still found his to be more logical.

And after all is said and done if I can Frankenstein your examples and fix them into something USABLE I'll take the ten minutes to add some //COMMENTED SECTIONS// Explaining it and dump the code on this site so the next person to AltaVista Search Function that s**t can focus on implementing their strategy instead of having to sort through pages of unspecific and hazy examples.

They do have a service where I can sell code right? I reckon I'd pay a fiver for it. Why oh why is there not already a link on this post to such a wise tome of knowledge.

Thanks for trying to help though. I'm probably just to easily frustrated.

I do have some thoughts on how to solve this but I shall refrain until I have the solution I am happy with then I leave it here to be peer-reviewed.





nicholish en:

Alain, you are forever trying to instigate a dick measuring contest with me by comparing my over-simplied, un-optimized, and non-production examples to more complex production-code. I didn't want to overwhelm OP by uploading my production library, but rather post a simple example for OP to start with. Since we have relegated to measuring dicks, how about you benchmark my actual production code?