MQL4 Function pointer / function callback solution - algorithmic-trading

As far as i have seen function pointers do not exist in MQL4.
As a workaround i use:
// included for both caller as callee side
class Callback{
public: virtual void callback(){ return; }
}
Then in the source where a callback is passed from:
class mycb : Callback{
public: virtual void callback(){
// call to whatever function needs to be called back in this source
}mcbi;
now mcbi can be passed as follows:
afunction(){
fie_to_receive_callback((Callback *)mycbi);
}
and the receiver can callback as:
fie_to_receive_callback(mycb *mcbi){
mcbi.callback(); // call the callback function
}
is there a simpler way to pass a function callback in mql4 ?

Actually there is a way, using function pointers in MQL4.
Here is an example:
typedef int(*MyFuncType)(int,int);
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, MyFuncType myfunc)
{
int g;
g = myfunc(x,y);
return (g);
}
int OnInit()
{
int m,n;
m = operation (7, 5, addition);
n = operation (20, m, subtraction);
Print(n);
return(INIT_FAILED); //just to close the expert
}

No. Fortunately there is not. ( . . . . . . . however MQL4 language syntax creeps * )
MQL4 Runtime Execution Engine ( MT4 ) has rather fragile process/thread handling and adding more ( and smarter ) constructs ( beyond rudimentary { OnTimer() | OnTick() | OnCalculate() } event-bound callbacks ) constitutes rather a threat to the already unguaranteed RealTime Execution of the main MT4-duties. While "New"-MQL4.56789 may provide hacks into doing so, there might be safer rather an off-loading strategy to go distributed and let MT4-legacy handlers receive "pre-baked" results from external processing Cluster, rather than trying to hang more and more and more flittering gadgets on a-years-old-poor-Xmas-tree.
To realise how brute this danger-avoidance is, just notice that original OnTimer() used 1 second resolution ( yes 1.000.000.000 ns steps in the world, where stream-providers label events in nano-seconds ... )
* ): Yes, since "new"-MQL4 introduction, there were many stealth-mode changes in the original MQL4-language. After each update it is more than recommendable to review "new"-Help file, as there might be both new options & nasty surprises. Maintaining an MQL4 Code-Base with more than a few hundreds man*years, this is indeed a very devastating experience.

Related

Send an struct array across a FREERTOS queue

I am starting with ESP32 and FREERTOS, and I am having problems sending an Struct array across a queue. I have already sent another kind of variables but never an array of Structs and I am getting an exception.
The sender and the receiver are in different source files and I am starting to thing that maybe is the problem (or at least part of the problem).
My simplified code looks like this:
common.h
struct dailyWeather {
// Day of the week starting in Monday (1)
int dayOfWeek;
// Min and Max daily temperature
float minTemperature;
float maxTemperature;
int weather;
};
file1.h
#pragma once
#ifndef _FILE1_
#define _FILE1_
// Queue
extern QueueHandle_t weatherQueue;
#endif
file1.cpp
#include "common.h"
#include "file1.h"
// Queue
QueueHandle_t weatherQueue = xQueueCreate( 2, sizeof(dailyWeather *) ); // also tried "dailyWeather" without pointer and "Struct dailyWeather"
void task1(void *pvParameters) {
for (;;) {
dailyWeather weatherDATA[8] = {};
// Code to fill the array of structs with data
if (xQueueSend( weatherQueue, &weatherDATA, ( TickType_t ) 0 ) == pdTRUE) {
// The message was sent sucessfully
}
}
}
file2.cpp
#include "common.h"
#include "file1.h"
void task2(void *pvParameters) {
for (;;) {
dailyWeather *weatherDATA_P; // Also tried without pointer and as an array of Structs
if( xQueueReceive(weatherQueue, &( weatherDATA_P ), ( TickType_t ) 0 ) ) {
Serial.println("Received");
dailyWeather weatherDATA = *weatherDATA_P;
Serial.println(weatherDATA.dayOfWeek);
}
}
}
When I run this code on my ESP32 it works until I try to print the data with Serial.println. The "Received" message is printed, but it crash in the next Serial.println with this error.
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
I am locked with this problem and I am not able to find a way to fix it, so any help will be very apreciated.
EDIT:
I am thinking that maybe a solution will be just to add an order item to the struct, make the queue bigger (in number) and send all the Structs separately to the queue. Then use that order in reader to order it again.
Anyway, will be nice to learn what I am doing wrong with the above code.
freeRTOS queues operate by using the buffer and data size you specify during initialization, when you call xQueueCreate(), to make copies of the data you want to send-receive.
When you call xQueueSend(), which is equivalent to xQueueSendToBack(), it makes a copy into that buffer.
If another task is awaiting for the queue in a call to xQueueReceive(), at the moment it becomes ready to run, xQueueReceive() will make a copy of the item in front of the queue's buffer into the destination buffer you specify in your call to xQueueReceive().
If the data you want to send is of pointer/array type, dailyWeather * in your case, then you need to make sure the memory pointed to by the pointer does not get out of scope before being read by the task that receives the pointer by calling xQueueReceive(). Local variables are created in the calling task's stack and will certainly get out of scope, and very likely overwritten, after the function returns.
IMO, best solution if you really need to pass pointers is to allocate the structures array in the function that generates the data and deallocate it in the task that consumes the data.
For many scenarios it is highly desirable not to abuse of dynamic memory handling, so in several communications stacks you will find the use of buffer pools, which at the end are also queues that are initialized during application startup. Operation is approximately as follows:
Initialization:
Initialize the buffer pool queues (simple queues of pointers).
Fill the buffer pools with dynamically allocated buffers of appropriated sizes.
Initialize the queues for inter- task communications.
Task that provides the data:
Get (Receive) a buffer pointer from one buffer pool.
Fill the buffer with data.
Send the buffer pointer to the communications queue.
Task that receives the data:
Get (Receive) the data buffer pointer from the communications queue.
Use the data.
Return (Send) the buffer pointer to the buffer pool.
In case your structures are small, so you have a more or less constrained copy-then-copy overhead, it makes more sense to create the queue so you work directly with structure instances and structure copies instead of structure buffer pointers.
Firstly it's not a good idea to create the queue in the global scope like you do. A global queue handle is OK. But run xQueueCreate() in the same function that creates task1 and task2 (queue must be created before the tasks), something like this:
QueueHandle_t weatherQueue = NULL;
void main() {
weatherQueue = xQueueCreate(32, sizeof(struct dailyWeather));
if (!weatherQueue) {
// Handle error
}
if (xTaskCreate(task1, ...) != pdPASS) {
// Handle error
}
if (xTaskCreate(task2, ...) != pdPASS) {
// Handle error
}
}
Secondly, the code in task1() does the following in a loop:
Create a new array of 8 dailyWeather structs in stack (in the scope of a single loop iteration)
Copy a pointer to first item in weatherDATA[] to the queue (task2 will receive it a bit later, when it's time to switch tasks)
Release the array of 8 dailyWeather (because we're exiting loop scope)
A bit later task2() executes and tries to read the pointer to first item in weatherDATA[]. However this memory has probably been released already. You can't dereference it.
So you're passing pointers to invalid memory over the queue.
It's much, much easier to work with a queue if you just pass the data you want to send instead of a pointer. Your structure is small and consists of elementary data types, so it's a good idea to pass it over the queue in its entirety, one at a time (you can pass an entire array if you want, but this way is simpler).
Something like this:
void task1(void *pvParameters) {
for (;;) {
dailyWeather weatherDATA[8] = {};
// Code to fill the array of structs with data
for (int i = 0; i < 8; i++) {
// Copy the structs to queue, one at a time
if (xQueueSend( weatherQueue, &(weatherDATA[i]), ( TickType_t ) 0 ) == pdTRUE) {
// The message was sent successfully
}
}
}
}
On the receiver side:
void task2(void *pvParameters) {
for (;;) {
dailyWeather weatherDATA;
if( xQueueReceive(weatherQueue, &( weatherDATA ), ( TickType_t ) 0 ) ) {
Serial.println("Received");
Serial.println(weatherDATA.dayOfWeek);
}
}
}
I cannot recommend the official FreeRTOS book enough, it's a great resource for beginners.
Thanks for all for the answers.
Finally I have added a variable to track the item position and I have passed all the data through the queue to the destination task. Then I put all those structs back into another array.
common.h
#include <stdint.h>
struct dailyWeather {
// Day of the week starting in Monday (1)
uint8_t dayOfWeek;
// Min and Max daily temperature
float minTemperature;
float maxTemperature;
uint8_t weather;
uint8_t itemOrder;
};
file1.h
// Queue
extern QueueHandle_t weatherQueue;
file1.cpp
#include "common.h"
#include "file1.h"
// Queue
QueueHandle_t weatherQueue = xQueueCreate( 2 * 8, sizeof(struct dailyWeather) );
void task1(void *pvParameters) {
for (;;) {
dailyWeather weatherDATA[8];
// Code to fill the array of structs with data
for (uint8_t i = 0; i < 8; i++) {
weatherDATA[i].itemOrder = i;
if (xQueueSend( weatherQueue, &weatherDATA[i], ( TickType_t ) 0 ) == pdTRUE) {
// The message was sent sucessfully
}
}
}
}
file2.cpp
#include "common.h"
#include "file1.h"
void task2(void *pvParameters) {
dailyWeather weatherDATA_D[8];
for (;;) {
dailyWeather weatherDATA;
if( xQueueReceive(weatherQueue, &( weatherDATA ), ( TickType_t ) 0 ) ) {
Serial.println("Received");
weatherDATA_D[weatherDATA.itemOrder] = weatherDATA;
}
}
}
Best regards.

'Open' - undeclared identifier

Does somebody know why this code inside a .mqh file throws the error 'Open' - undeclared identifier?
It seems like Open, Close, High, Low functions aren´t "detected" in my library. ( Other system functions like Print() are properly loaded ).
bool isBlueCandle( int candle ) export {
return Open[candle] < Close[candle];
}
Not exactly, neither 1:1 copy, nor any MODs, return any error:
//+------------------------------------------------------------------+
//| isBlueCandle TESTs MetaLang.exe: Build 1154 |
//+------------------------------------------------------------------+
bool isBlueCANDLE_TEST( int candle ) export
{
return Open[candle] < Close[candle];
}
bool isBlueCANDLE_TEST2( int candle ) export {
return Open[candle] < Close[candle];
}
bool isBlueCANDLE_TEST3( const int candle ) export {
return Open[candle] < Close[candle];
}
bool isBlueCANDLE_TEST4( const int candle ) export {
return( Open[candle] < Close[candle] );
}
As posted in the comment above, the missing context would help trace the root-cause for your stated issue.
Post a complete copy of the MetaLang.exe Error-description.
Use mouse-right-click + copy ( in MetaLang.exe-Toolbox window on [Error]-page + paste that complete description on StackOverflow )
As an example:
return value of 'OrderModify' should be checked
FOREX_SimpleSAR_EA_msMOD_0.00.mq4 227 19
Just for a clarity sake:
MQL4 recognises both functions ( Print() ) and other objects ( Open ) with specific access-protocol to work with them. In case of functions, one passes "arguments" compatible with the function´s expectations.
Open, High, Volume et al, are not functions, but Arrays, the more, these arrays are special and carefully constructed in the internal MT4-engine, so as to provide a very fast & very efficient manipulation.
MetaQuotes call this a TimeSeries-object, a reversed-stepping-index into
( otherwise normal ) array.
So, your function isBlueCandle() is indeed a function, however, internally it does not call a function, but it compares a cell-values of Open ( the [anIntIndexAsPtrIntoTimeSeriesOrderedARRAY]-*referenced cell )
against a value of Close ( namely the [anIntIndexAsPtrIntoTimeSeriesOrderedARRAY]-*referenced cell ) to construct a bool which the isBlueCandle() function is about to return.

Swift Dictionary slow even with optimizations: doing uncessary retain/release?

The following code, which maps simple value holders to booleans, runs over 20x faster in Java than Swift 2 - XCode 7 beta3, "Fastest, Aggressive Optimizations [-Ofast]", and "Fast, Whole Module Optimizations" turned on. I can get over 280M lookups/sec in Java but only about 10M in Swift.
When I look at it in Instruments I see that most of the time is going into a pair of retain/release calls associated with the map lookup. Any suggestions on why this is happening or a workaround would be appreciated.
The structure of the code is a simplified version of my real code, which has a more complex key class and also stores other types (though Boolean is an actual case for me). Also, note that I am using a single mutable key instance for the retrieval to avoid allocating objects inside the loop and according to my tests this is faster in Swift than an immutable key.
EDIT: I have also tried switching to NSMutableDictionary but when used with Swift objects as keys it seems to be terribly slow.
EDIT2: I have tried implementing the test in objc (which wouldn't have the Optional unwrapping overhead) and it is faster but still over an order of magnitude slower than Java... I'm going to pose that example as another question to see if anyone has ideas.
EDIT3 - Answer. I have posted my conclusions and my workaround in an answer below.
public final class MyKey : Hashable {
var xi : Int = 0
init( _ xi : Int ) { set( xi ) }
final func set( xi : Int) { self.xi = xi }
public final var hashValue: Int { return xi }
}
public func == (lhs: MyKey, rhs: MyKey) -> Bool {
if ( lhs === rhs ) { return true }
return lhs.xi==rhs.xi
}
...
var map = Dictionary<MyKey,Bool>()
let range = 2500
for x in 0...range { map[ MyKey(x) ] = true }
let runs = 10
for _ in 0...runs
{
let time = Time()
let reps = 10000
let key = MyKey(0)
for _ in 0...reps {
for x in 0...range {
key.set(x)
if ( map[ key ] == nil ) { XCTAssertTrue(false) }
}
}
print("rate=\(time.rate( reps*range )) lookups/s")
}
and here is the corresponding Java code:
public class MyKey {
public int xi;
public MyKey( int xi ) { set( xi ); }
public void set( int xi) { this.xi = xi; }
#Override public int hashCode() { return xi; }
#Override
public boolean equals( Object o ) {
if ( o == this ) { return true; }
MyKey mk = (MyKey)o;
return mk.xi == this.xi;
}
}
...
Map<MyKey,Boolean> map = new HashMap<>();
int range = 2500;
for(int x=0; x<range; x++) { map.put( new MyKey(x), true ); }
int runs = 10;
for(int run=0; run<runs; run++)
{
Time time = new Time();
int reps = 10000;
MyKey buffer = new MyKey( 0 );
for (int it = 0; it < reps; it++) {
for (int x = 0; x < range; x++) {
buffer.set( x );
if ( map.get( buffer ) == null ) { Assert.assertTrue( false ); }
}
}
float rate = reps*range/time.s();
System.out.println( "rate = " + rate );
}
After much experimentation I have come to some conclusions and found a workaround (albeit somewhat extreme).
First let me say that I recognize that this kind of very fine grained data structure access within a tight loop is not representative of general performance, but it does affect my application and I'm imagining others like games and heavily numeric applications. Also let me say that I know that Swift is a moving target and I'm sure it will improve - perhaps my workaround (hacks) below will not be necessary by the time you read this. But if you are trying to do something like this today and you are looking at Instruments and seeing the majority of your application time spent in retain/release and you don't want to rewrite your entire app in objc please read on.
What I have found is that almost anything that one does in Swift that touches an object reference incurs an ARC retain/release penalty. Additionally Optional values - even optional primitives - also incur this cost. This pretty much rules out using Dictionary or NSDictionary.
Here are some things that are fast that you can include in a workaround:
a) Arrays of primitive types.
b) Arrays of final objects as long as long as the array is on the stack and not on the heap. e.g. Declare an array within the method body (but outside of your loop of course) and iteratively copy the values to it. Do not Array(array) copy it.
Putting this together you can construct a data structure based on arrays that stores e.g. Ints and then store array indexes to your objects in that data structure. Within your loop you can look up the objects by their index in the fast local array. Before you ask "couldn't the data structure store the array for me" - no, because that would incur two of the penalties I mentioned above :(
All things considered this workaround is not too bad - If you can enumerate the entities that you want to store in the Dictionary / data structure you should be able to host them in an array as described. Using the technique above I was able to exceed the Java performance by a factor of 2x in Swift in my case.
If anyone is still reading and interested at this point I will consider updating my example code and posting.
EDIT: I'd add an option: c) It is also possible to use UnsafeMutablePointer<> or Unmanaged<> in Swift to create a reference that will not be retained when passed around. I was not aware of this when I started and I would hesitate to recommend it in general because it's a hack, but I've used it in a few cases to wrap a heavily used array that was incurring a retain/release every time it was referenced.

atomics/mutex hybrid counter

I know that using atomics is dangerous (I watched Herb Sutter's 3hr lecture a few days ago), but the following use case seems reasonable to me, in terms of being simple and well contained.
Questions: (a) Is there something wrong with this? (Surely, there must be.) (b) Is there a name for this kind of hybrid atomic/mutex based approach? (c) Is there a simpler way of achieving the same thing?
The goal is to have a thread-safe counter class which we can call attempt_invalidation() on, knowing that it will only set its invalid flag to true if the count is at zero. There will be no other public methods on the class, but we will have a friend class specially designed to do RAII incrementing/decrementing of the counter.
class hybrid_counter{
friend class hybrid_counter_user;
bool invalidated = false;
int counter_a = 0;
std::atomic_int counter_b;
std::mutex mu;
bool increment_safely(){
std::lock_guard<std::mutex> gaurd(mu);
if ( !invalidated )
counter_a++;
return invalidated;
};
void increment_dangerously(){
counter_b++;
};
void decrement(){
counter_b--;
};
public:
bool attempt_invalidation(){
if(counter_a + counter_b == 0){
std::lock_guard<std::mutex> gaurd(mu);
if(counter_a + counter_b == 0)
invalidated = true;
}
return invalidated;
};
};
This is the friend class that knows how to use the counter correctly:
class hybrid_counter_user{
public:
hybrid_counter_user(hybrid_counter& hc){
if(hc.increment_safely() == false) // is not yet invalidated
c = &hc;
else
c = nullptr;
};
~hybrid_counter_user(){
if(c)
c->decrement();
};
hybrid_counter_user(hybrid_counter_user&& old){
c = old.c;
old.c = nullptr;
}
hybrid_counter_user(hybrid_counter_user& other){
c = other.c;
if(c)
c->increment_dangerously();
}
private:
hybrid_counter* c;
};
Note that the copy constructor uses the fact that hybrid_counter remains valid while other is in scope and other's destructor cannot be reordered with increment_dangerously because both involve the same atomic var.
The move constructor is simply transferring responsibility for decrementing.

Trying to use lambda functions as predicate for condition_variable wait method

I am trying to make the producer-consumer method using c++11 concurrency. The wait method for the condition_variable class has a predicate as second argument, so I thought of using a lambda function:
struct LimitedBuffer {
int* buffer, size, front, back, count;
std::mutex lock;
std::condition_variable not_full;
std::condition_variable not_empty;
LimitedBuffer(int size) : size(size), front(0), back(0), count(0) {
buffer = new int[size];
}
~LimitedBuffer() {
delete[] buffer;
}
void add(int data) {
std::unique_lock<std::mutex> l(lock);
not_full.wait(l, [&count, &size]() {
return count != size;
});
buffer[back] = data;
back = (back+1)%size;
++count;
not_empty.notify_one();
}
int extract() {
std::unique_lock<std::mutex> l(lock);
not_empty.wait(l, [&count]() {
return count != 0;
});
int result = buffer[front];
front = (front+1)%size;
--count;
not_full.notify_one();
return result;
}
};
But I am getting this error:
[Error] capture of non-variable 'LimitedBuffer::count'
I don't really know much about c++11 and lambda functions so I found out that class members can't be captured by value. By value though, I am capturing them by reference, but it seems like it's the same thing.
In a display of brilliance I stored the struct members values in local variables and used them in the lambda function, and it worked! ... or not:
int ct = count, sz = size;
not_full.wait(l, [&ct, &sz]() {
return ct != sz;
});
Obviously I was destroying the whole point of the wait function by using local variables since the value is assigned once and the fun part is checking the member variables which may, should and will change. Silly me.
So, what are my choices? Is there any way I can make the wait method do what it has to do, using the member variables? Or I am forced to not use lambda functions so I'd have to declare auxiliary functions to do the work?
I don't really get why I can't use members variables in lambda functions, but since the masters of the universe dessigned lamba functions for c++11 this way, there must be some good reason.
count is a member variable. Member variables can not be captured directly. Instead, you can capture this to achieve the same effect:
not_full.wait(l, [this] { return count != size; });

Resources