Orders Counter class

rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

I have taken the COrdersCounter class and added a bunch of functionality that some might find useful. The original was published here: https://www.mql5.com/en/code/11786

Using the class to handle open orders and order history takes away much of the Empty4 complexity and I think makes for much more readable code. You can do things like this:

Code: Select all

      
      // do this once in the OnTick() loop
     
      // initialize class for open orders
      COrdersCounter ord(MagicNumber, Symbol(), MODE_TRADES);
      ord.refreshData();
      // initialize class for history
      COrdersCounter his(MagicNumber, Symbol(), MODE_HISTORY);
      his.refreshData();


      if(Signal_Buy) {
          if(ord.getOrdersCount(OP_BUY)<1 && his.OrderClosedDuringBar(PERIOD_H4)==0) {
                ......... open an order if no open orders and no order closed during last H4 bar
          }
      }

      if(his.OrderTPDuringBar(PERIOD_H4)) {
                ......... we hit TP!!!
      }

      if(his.OrderSLDuringBar(PERIOD_H4)) {
                ......... we hit SL!!! Sad.
      }

      if(his.getLastOrderStatus()==STATUS_CLOSED) {
                ......... the order was closed either manually or by an EA but not due to SL or TP
      }
The advantage of using a class like this is that it can be extended very easily without breaking existing code. All the required variables are kept track of internally.

I have attached a simple script as a sample that can be dropped on a chart to demonstrate some of the functions.
You do not have the required permissions to view the files attached to this post.
Last edited by rocketman99 on Mon Apr 13, 2015 10:11 pm, edited 1 time in total.
rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

Constructor:

COrdersCounter(int magic, string symbol, int counter_mode = MODE_TRADES)
  • Parameters:

    magic - integer value of Magic Number for for the filtering of the orders. When magic = 0 is not used.
    symbol - symbol of the instrument. When symbol = "" is not used. This parameter can be any number of symbols to work with baskets - eg. "EURUSD USDJPY"
    counter_mode - the pool of the orders (either closed, either opened orders). Allows 2 values: MODE_TRADES (by default) - opened orders, MODE_HISTORY - closed orders.
Methods:

void refreshData(void)
  • The method renews data for orders and history pools and must be called before any of the get methods are used.
Working with order and history pools:

int getOrdersCount(int type)
  • The method returns orders count of defined type. Parameters:
    type - type of the orders. Allowed values:
    OP_BUY - market buy orders,
    OP_SELL - market sell orders,
    OP_SELLLIMIT - sell limit orders,
    OP_BUYLIMIT - buy limit orders,
    OP_SELLSTOP - sell stops orders,
    OP_BUYSTOP - buy stop orders.
    When type = -1, the method will return total count of all orders.
int getLastOrder()
  • Returns ticket number of last closed/opened order from the retrieved list.
int getFirstOrder()
  • Returns ticket number of first closed/opened order from the retrieved list.
Status of orders and history:

int getOrderStatus(int ticket)
  • Return status of a ticket. Return codes are as follows:
    STATUS_OPEN
    STATUS_CLOSED
    STATUS_CLOSED_SL
    STATUS_CLOSED_TP
    STATUS_PENDING
int getFirstOrderStatus()
  • Returns first orders status
int getLastOrderStatus()
  • Returns last orders status
int OrderTPDuringBar(int period=PERIOD_CURRENT)
  • Did order hit TP during a period? Default period is current chart period. If you change the chart period with an active EA you could experience unexpected results so it's better to specify a period to check.
    Return codes are:
    0 - did not hit TP
    1 - did hit TP
    -1 - you are trying to use this function on open orders
int OrderSLDuringBar(int period=PERIOD_CURRENT)
  • Did order hit SL during a period?
int OrderClosedDuringBar(int period=PERIOD_CURRENT)
  • Did order close for any reason during a period?
The money and risk aspects of orders and history:

ProfitData getTotalProfit()
  • Returns an instance of the struct ProfitData, containing total profit/loss of the retrieved list.

    The struct ProfitData contains fields:

    double currency - profit/loss in currency
    double points - profit/loss in points
double getTotalProfit().currency
  • Returns total profit in currency
double getTotalProfit().points
  • Returns total profit in points
double getMarketVolume()
  • Returns the total volume of the market trades of the retrieved list.
double getTotalVolume()
  • Returns the total volume for all orders of of the retrieved list.
Other stuff and helpers:

void setMagicNumber(int magic)
  • Sets Magic Number value. Parameters: magic - new value for Magic Number.
void setSymbol(string symbol)
  • Sets Symbol value. Parameters: symbol - new symbol value of currency. This parameter can be any number of symbols to work with baskets - eg. "EURUSD USDJPY"
void setMode(int mode)
  • Set pool. Parameters: mode - the pool type: MODE_TRADES - opened orders, MODE_HISTORY - closed orders.
int getMagicNumber()
  • Returns value of magic (Magic Number) for the filtering of the orders.
string getSymbol()
  • Returns value of symbol.
int getMode()
  • Return type of current pool for orders filtering: MODE_TRADES - opened orders, MODE_HISTORY - closed orders.
Last edited by rocketman99 on Tue Apr 14, 2015 8:34 am, edited 4 times in total.
User avatar
renexxxx
Trader
Posts: 860
Joined: Sat Dec 31, 2011 3:48 am

Orders Counter class

Post by renexxxx »

I applaud this work! :clap: :clap: :clap:

We should all be using OO concepts for our EAs and indicators -- in order to be able to re-use code and write more readable code. In fact, we should strive to create a class library that should form the basis of any new project. Unfortunately, there is so much existing legacy code around, that I foresee that the resistance to such a direction will be high.
rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

renexxxx » Sun Apr 12, 2015 7:07 am wrote:I applaud this work! :clap: :clap: :clap:

We should all be using OO concepts for our EAs and indicators -- in order to be able to re-use code and write more readable code. In fact, we should strive to create a class library that should form the basis of any new project. Unfortunately, there is so much existing legacy code around, that I foresee that the resistance to such a direction will be high.
Thanks for the encouragement. Yes, I agree. I was starting to run into difficulty with maintaining my own shell code that I decided to just sit down and hack it apart and to use OO concepts. Well it turned out to be a breeze really and my code is VASTLY more readable.

Some things that I am working on:

Work with baskets - actually quite simple to implement and due to OO will not break existing code
Filter on time so that you can query:
orders over last period (for example last H4 or D1)
length orders have been hanging around (in seconds and minutes)

I also know that many people hate CamelCase as its wordy, but I find it makes reading logic so much simpler.
User avatar
renexxxx
Trader
Posts: 860
Joined: Sat Dec 31, 2011 3:48 am

Orders Counter class

Post by renexxxx »

rocketman99 » Sun Apr 12, 2015 4:42 pm wrote: I also know that many people hate CamelCase as its wordy, but I find it makes reading logic so much simpler.
For what it is worth, I am a big fan of CamelCase, having programmed in Java for the last 20 years or so.
dietcoke
Trader
Posts: 162
Joined: Tue Nov 15, 2011 9:59 pm

Orders Counter class

Post by dietcoke »

Thanks for posting this Rocketman. I shall study this and see how I can use this.

As a non-programming "amateur".
I learned mql4 by modifying existing code.
Even now, much of what I write is based on something that has been previously published.
OO code is great for this type of extending work but there is a dearth of published code around which uses the new features which is making it difficult for people like me to follow the same path now.

OOP in mql4 can't take off until more good people like yourself are prepared to share their classes and resulting indicators and ea's

Personally, I also find OO code a bit wierd looking and can't quite get my head around it. The program structure is different. For me, it's like learing a 3rd language from a textbook written in my 2nd language
I'm sure I'm not alone in that.
Image
rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

dietcoke » Sun Apr 12, 2015 9:37 am wrote:Thanks for posting this Rocketman. I shall study this and see how I can use this.

As a non-programming "amateur".
I learned mql4 by modifying existing code.
Even now, much of what I write is based on something that has been previously published.
OO code is great for this type of extending work but there is a dearth of published code around which uses the new features which is making it difficult for people like me to follow the same path now.

OOP in mql4 can't take off until more good people like yourself are prepared to share their classes and resulting indicators and ea's

Personally, I also find OO code a bit wierd looking and can't quite get my head around it. The program structure is different. For me, it's like learing a 3rd language from a textbook written in my 2nd language
I'm sure I'm not alone in that.
I feel for you as a self taught coder (although with many many years of experience) OO also boggled my mind when I initially dabled in it. But I can say it makes coding really easy and is worth it in the long run.

When I have some time I will put together some example EA's. Also feel free to ask questions regarding OO coding. Note I am no expert.
rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

I added the ability to work with baskets. This required modifying two lines of code. Where you specify the Symbol you can now specify a string of symbols - eg: "EURUSD USDJPY AUDUSD" using any delimeter.

The update can be found in post 1.

Code: Select all

      // initialize class for open orders
      COrdersCounter ord(MagicNumber, "EURUSD USDJPY AUDUSD", MODE_TRADES);
      ord.refreshData();
User avatar
RedLineFred
Trader
Posts: 52
Joined: Wed May 01, 2013 6:15 am
Location: Brisbane, Australia

Orders Counter class

Post by RedLineFred »

Great work here, but as others have already stated, I too am more than a little confused by OO programming and concepts.
Any pointers to where one can get educated on OO - web site, pdf or book?
rocketman99
Trader
Posts: 91
Joined: Wed Dec 19, 2012 1:19 am

Orders Counter class

Post by rocketman99 »

RedLineFred » Tue Apr 14, 2015 3:45 am wrote:Great work here, but as others have already stated, I too am more than a little confused by OO programming and concepts.
Any pointers to where one can get educated on OO - web site, pdf or book?
I just did a quick google and understand your frustration - any explanation of OO, even so called basic ones quickly delve into things like inheretance and other bizarre OO concepts that you do not need to know about to get started.

So let me try and explain. Think of a class as a template or blueprint (for example a house blueprint will have options or variables for number of floors, number of rooms etc). Once you define the object based on the class (build the actual house or construct it in OO terms) you use the blueprint (predefined class) and populate the internal class variables (template) to make it a unique house. These variables stick to this object and are unique to the object - each new house object automatically keeps track of its own details. This is where the beuty of OO comes in - you can have many house objects using the same class as the template. So when using the COrdersClass I can keep track of individual currencies without having to resort to arrays and other means. For example:

Code: Select all

# track 3x currencies open orders
COrdersCounter eurusd(MagicNumber, "EURUSD", MODE_TRADES); eurusd.refreshData();
COrdersCounter usdjpy(MagicNumber, "USDJPY", MODE_TRADES); usdjpy.refreshData();
COrdersCounter audusd(MagicNumber, "AUDUSD", MODE_TRADES); audusd.refreshData();
Just running the above will keep track of all the following details inside each class automatically:

Code: Select all

   int orders_magic;                   // Magic Number for the filtering orders. If 0, then doesn't filter.
   string orders_symbol;               // Currency symbol for the filtering orders. If "", then doesn't filter.
   int orders_mode;                    // Type of the pool: MODE_TRADES(default) - trading, MODE_HISTORY - history pool
   int buys;                           // Count of the buy positions
   int sells;                          // Count of the sell poistions
   int buy_limits;                     // Count of the buy limit orders
   int sell_limits;                    // Count of the sell limit orders
   int buy_stops;                      // Count of the buy stop orders
   int sell_stops;                     // Count of the sell stop orders
   datetime last_time;                 // Time of last pool ticket
   datetime first_time;                // Time of first pool ticket
   int last_ticket;                    // Last ticket number
   int first_ticket;                   // first ticket number
   bool pool_scanned;                  // Does the order pool need scanning to update cache
   ProfitData total_profit;            // Profit of the counted orders
   double total_volume;                // Total volume - number of lots for all counted orders
   double market_volume;               // Total volume - number of lots for counted market positions
Now I can use all 3 currencies at the same time with minimal fuss:

Code: Select all

if(eurusd.OrderSLDuringBar(PERIOD_H4)) {
                ......... EURUSD hit SL!!! Sad.
}
if(usdjpy.OrderSLDuringBar(PERIOD_H4)) {
                ......... USDJPY hit SL!!! Sad.
}
if(audusd.OrderSLDuringBar(PERIOD_H4)) {
                ......... AUDUSD hit SL!!! Sad.
}
The power of OO comes in when I want to add another variable or function to the class - I just add it plus some methods (functions) to work with the new variables knowing that no other code will break. The original intended purpose of the class (to build a house) does not change. I mearly added a new option to have central heating, but I do not need to use the option.

For me the absolute minimum you need to understand to make OO worthwhile is:
  • How to define a class and add variables to it
    What is a private declaration
    What is public declaration
    What is a method and how to use them
Ignore all the rest about OO.

Looking at the COrdersCounter class code, start with

COrdersCounter::COrdersCounter(int magic, string symbol, int counter_mode = MODE_TRADES)

This creates the object and populates the internal variables (this. syntax).

void COrdersCounter::refreshData(void)

This scans the order pools and works out all the other variables. All the remaining methods (functions) just pull variables out, or do further computations on the variables already updated by refreshData(). You now want to do some new wizbang thing with all those internal variables - well just add a new method.

I hope this explanation helps just a little. As mentioned, try understanding just the four OO concepts above and ignore all the rest OO has to offer.
Post Reply

Return to “Coders Hangout”