An object oriented language for Empty4

Post Reply
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

Instance methods: This is the third and final type of method to be created in oq. You would declare it as follows:

Code: Select all

class TimeRange
{
    bool IsActive();
    {
        if( Time:Current() >= @From && Time:Current() < @To )
            return(true);
        return(false);
    }
}
Note that you do include a return type, but that you do not use the word 'static'. This will let oq know that it is an instance method, which means you have access to all of the instance properties. In our example, you can easily create multiple instance of a TimeRange. So whenever TimeRange:IsActive is called, the method knows to use the correct From/To values for the particular object or instance.

But speaking of calling TimeRange:IsActive, you would need to pass the object ID as the first parameter if calling from outside of the class. To make this clearer, if I'm coding ouside the TimeRange class and want to make use of this class, it would look like this:

Code: Select all

    int trng = TimeRange:New(from, to);

    <...somewhere else...>

    if( TimeRange:IsActive(trng) )
        <do something>;
So from the outside looking in, you have to be object ID aware. But inside the object, you can refer to the properties and make method calls without need to refer to the ID's. For example:

Code: Select all

class TimeRange
{
    void AnotherMethod()
    {
        if( @IsActive() )
            <do something>;
    }
}
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

For brevity sake, please note that I'm not filling out the whole class every time in the examples. But just to be clear, there is only one 'class TimeRange' definition, for example, and all defines, properties and methods go inside the "{}". Coders who already know OO would assume this, but I thought I better clarify it.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

If you're not familiar with OO programming and stumbled upon this thread, and patiently read through my ramblings, you may be saying to yourself, "okay....". While classifying code is certainly important to keep things organized, it's by no means a revolution, right?

Well, now that there is a basic framework in place for defining classes, we can start having some real fun. To launch us into the power of OO programming I'll discuss inheritance. Like the way we inherit certain traits from our parents, whether good or bad, and the way they did from their parents, classes can inherit all the stuff mentioned above (defines, properties and methods) from another class.

Let's say someone creates a class called Trend, which has methods to do things like tell whether the trend is up, down, or indifferent. Or maybe it has a method to return the strength of the trend, for example. Now, let's say the author posts it here on the forum for folks to drop into their projects and use. You really like the Trend class and find it performs pretty well. But if only you could tweak it just a bit and add RSI to it as well, for example. With the current paradigm, you would grab the code, hack it up to make it work the way you want. Great! But what you've just done is bastardize the original. As easy and fun as this is, you could never get away it in a commercial development environment. So you make a copy and hack it up, maybe several times. Now suppose you realize there is something you need to change in the original algorithm. Guess what? You now have to make the same change in all the places you copied the original to. Now multiply this by a thousand times for complex projects and you have programmer's purgatory.

What if you could create your own class, called, say, RSITrend, and have it inherit everything good from Trend, but you add just the bits you need for the tweak? Now, the creator of Trend can make any needed changes in just the one place, reposts his class, you grab the update and voila, the world is right as rain (assuming, that is, the method signatures didn't change).

If you begin to see how OO works, how it allows for easier code management, how it forces you to classify and carefully structure lasting modules, it will eventually start to click that this is the best way to write software, if for nothing more than the ability to easily share stuff with other people on the forum.

So how do you inherit from another class? I'm glad you asked:
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

Original Trend class definition:

Code: Select all

class Trend
{
    #define Up  1
    #define Down -1
    #define Neutral 0

    int TimeFrame;

    New(int timeframe)
    {
        int ID = @new();
        @TimeFrame = timeframe;
        return(ID);
    }

    void Delete()
    {
        // <any of your own cleanup>
        @del();
    }

    int Direction()
    {
        int dir;
        if( <some code> ) dir = @Up; else
        if( <some code> ) dir = @Down;
        else dir = @Neutral;
        return(dir);
    }

    double Strength()
    {
        double strength = <some code>;
        return(strength);
    }
}
Your own RSITrend that inherits from Trend:

Code: Select all

class RSITrend : Trend
{
    New(int timeframe)
    {
        int ID = @new();
        @TimeFrame = timeframe;
        return(ID);
    }

    int Direction()
    {
        //  Inherit the original behavior

        int dir = Trend:Direction$();

        //  Now add my own spin on it using RSI, or whatnot

        if( dir==@Up && <some code> ) dir = @Neutral; else
        if( dir==@Down && <some code> ) dir = @Neutral;
        return(dir);
    }
}
In the RSITrend class definition above, Strength will continue to behave exactly as it did before, but Direction will inherit the original behavior and allow you to make your own modifications to the outcome. At some point here I'll discuss syntax like why '@' and colon, and now the '$' is used to call Trend:Direction$(). Suffice it to say for the moment that whenever you want to call your parent class to inherit the method behavior, you use the '$' sign. Otherwise if you were to call it without, it would again atempt to call the method you're in, filling up the call stack and aborting the program.

You will notice that in the class definition for RSITrend there is a colon followed by the class you wish to inherit from. For experienced OO programmers, oq will not support multiple inheritance (or inheriting from more than one class at a time). But class A can inherit from class B, and class C can inherit from class A, etc. Genrally speaking a class can either be a root class with no inheritance, or it can inherit from one other class.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

I posted an update to the oq builder with a few improvements:

- static method inheritance (I'll have to discuss this later)
- on target output, separated the mq4 files into mqh/mq4 and all mqh files get placed at the beginning so no referenced globals (at least from a class) will turn up missing
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

I've updated the ObjectQuotes builder again to v0.94 in the first post. This has a few bug fixes and minor improvements.

The biggest fix was a problem introduced in v0.92 with static method inheritance. It stomped on some binding methods (new and size), and the del binding method was causing things to hang. Fixed now.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

Referencing Names

Finally I get around to the topic of how you reference names within a class, whether defines, properties or methods. But before I get started, I have a confession to make. ObjectQuotes could have been better. And perhaps if there is enough interest in the future it will get there with a second iteration. The difference is, I had personal motivation for developing oq rather quickly because for me, this is not an end in itself, but a tool to creating the kind of trading framework I've always dreamed of. So instead of spending 6 months full time creating a full language interpreter, which would have been required to do this in the best possible way, I took a shortcut.

What does this have to do with name referencing? It means there are some butt-ugly syntactical hooks if you will, that allow me to very easily scan old style mql code without having to fully interpret things like expressions and so forth. If you can stand these hooks, oq works very well, and I'm already well underway with my own trading framework.

There are two characters you need to be aware of: ':' and '@'

Any time you want to reference any name within a class in a fully qualified way, you would use the class name, followed by a colon, followed by the name, with no spaces. Here are some examples:

Code: Select all

    int dir = Trend:Direction(trendid);
    if( dir==Trend:Up ) <do something>
    SetName(List:Names[listid][idx]);
You would use fully qualified names like this when you are outside of a class but wish to reference a name within the class. In the above, the first line references a method, the second line a define and the third line a property. Note that if the name is an instance or property method, the the object ID must be present. For methods, the object ID must be the first argument in the list (see 'trendid' above). For properties, the object ID must be given in the first array dimension (see 'listid' above). Static methods and properties require no such ID since they won't have one.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

Referencing from ouside a class is always done in the manner listed in the previous post (by outside, I mean not even a parent class, but some external code wanting to utilize the particular class's facilities). When you are coding inside of a class, referring to its own names is a different story. The colon is still valid, but you can drop the class name as follows:

Code: Select all

    double val = :Strength(ID);
This is referring to a method called Strength in the current namespace, which could be the current class, it's parent class, or any of its parents. But if Strength exists in both the current class as well as the parent class, it will use the one in the current class. The name lowest in the class hierarchy is always used.

When using the colon and you are referring an instance method or property, as in the previous post, you have to give the object ID as well.

But do I really have to give the ID every time? I mean shouldn't it know if I'm coding within an instance class? Actually, yes. And here's how.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

Much of the coding you do will be inside methods of a class, so passing the ID around all the time can be a nuisance. Enter the '@' symbol. This symbol is ONLY used when referring to names within the current namespace (current class or any heredity class). And when coding within an instance method and the name happens to be an instance method or property, you can simply drop the need for referencing the ID. So for example:

Code: Select all

    double val = @Strength();
    string s = @List[idx];
So, it follows, that when referring to static methods and properties within the current namespace, using '@' and ':' are identical and interchangeable. I personally prefer always using colon when referring to local static methods and '@' when referring to local static properties, but that's just me. So a quick summary reference:

class:name - outside a class referencing a define
class:name - outside a class referencing a static property
class:name(...) - outside a class referencing a static method
class:name[id] - outside a class referencing an instance property
class:name(id, ...) - outside a class referencing an instance method
:name - inside a class referencing a define
@name - inside a class referencing a define
:name - inside a class referencing a static property
@name - inside a class referencing a static property
:name(...) - inside a class referencing a static method
@name(...) - inside a class referencing a static method
:name[id] - inside a class referencing an instance property
@name - inside a class referencing an instance property
:name(id, ...) - inside a class referencing an instance method
@name(...) - inside a class referencing an instance method

I think that covers it.
roger-write
Trader
Posts: 63
Joined: Sat May 19, 2012 10:34 am

Re: An object oriented language for Empty4

Post by roger-write »

If anyone is interested in this project feel free to make comments, ask questions, or make suggestions.

A reminder as to why something like ObjectQuotes was necessary: it is not about changing mql's basic facilities like trading functions, etc., but more about structuring code better such that it is more maintainable and to provide a better method to build more complex EA's/Indys and make it easier to share pieces of functionality with others. Also, if you've ever salivated over the idea of being able to have callback functions in mql, well, using oq makes the callback concept obsolete as you can pass around object id's and then call methods on those objects. Simply subclass the objects and you have custom behavior as you would with callbacks. As I go, I'll be posting some usefull .oq modules along the way and more examples.

In the meantime, I want to bring up a topic that is a bit sketchy even in the OO programming world. Static method inheritance. Instance inheritance is a given, but static not so much. We could have just ignored this for ObjectQuotes, but there are two really great examples of why you might want to do this. Consider the following:

As part of your trading framework, you have a module that handles errors. For example, lets say you have a class called Error with a static method called Msg, which displays an error message based upon some error code. Now lets say you're writing a custom EA using your framework and you would like to call a DLL with the error so it can pop up in a windows dialogue. You'd like to be ale to override the existing behavior without changing anyplace that calls Error:Msg. So providing a way to override static functions is important. That's one.

The other is for the purpose of extending functionality. Let's say you have a class with a static Init function. But you again are writing a custom EA and would like to add some additional intializations, so it would be useful if you could tack on additional items to initialize without touching the original class's Init function. So being able to extend a static method's functionality could also be extremely useful.

The next time I post ill give some examples to make this clearer. They are some powerful coding concepts to make things easier to maintain.
Post Reply

Return to “Coders Hangout”