mql4 save object to array then to file - mql4

I have an arrayobject class and I am saving the information when a new record is created or deleted. And then loading the data back when the ea initialises
I an unsure how to create a multi array from the object to save/load file
main.mql4
#include <CTrade.mqh>
CArrayObj* listOfTrades=NULL;
int OnInit()
{
//initialise listOfTrades and load saved data from file
listOfTrades = new CArrayObj;
}
void OnDeinit(const int reason)
{
if(CheckPointer(listOfTrades)==POINTER_DYNAMIC)
delete(listOfTrades);
}
void OnTick(){ checkTPHit(listOfTrades); }
signal.mql4
void Trigger()
{
//Create Order
int newTicket=NewOrder(symbol, order, LotSize, price, takeprofit2, stoploss, comment, 5000);
if(newTicket>0)
{
for(int i=listOfTrades.Total()-1;i>=0;i--){
CTrade *trade=listOfTrades.At(i);
if(!trade.isTicketExist())
{listOfTrades.Delete(i);continue;}
}
listOfTrades.Add(new CTrade(ticket,entry, tp1, tp2, tp3, sl));
listOfTrades.saveToFile;
listOfTrades.printTrades;
}
}
CTrade.mql4
#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>
class CTrade : public CObject
{
private:
string file = "CTrade.csv"
public:
int m_ticketId;
double m_entry, m_tp1, m_tp2, m_tp3, m_sl;
CTrade(const int ticket, entry, tp1, tp2, tp3, sl){
m_ticketId=ticket;
m_oop=entry;
m_tp1=tp1;
m_tp2=tp2;
m_tp3=tp3;
m_sl=sl;
}
bool isTicketExist(){
if(OrderSelect(m_ticketId,SELECT_BY_TICKET))
return(OrderCloseTime()==0);
else return(false);//or GetLastError()!=4108
}
saveToFile (){
//save data to file everytime add/delete, to load when the ea is initilaized again
//create multidimensional array and get its size to save to file from objects
//save to file
int handle=FileOpen(file,FILE_READ|FILE_WRITE|FILE_BIN|FILE_COMMON);
if(handle!=INVALID_HANDLE)
{
//--- write array data to the end of the file
FileSeek(handle,0,SEEK_END);
FileWriteArray(handle,arr,0,arraySize);
//--- close the file
FileClose(handle);
}
else
Print("Failed to open the file, error ",GetLastError());
}
loadData () {
// load data on the ea's initilization
}
printTrades(){
//method to print to terminal while in testing phase
CArrayObj* _listOfTrades
for(int i=_listOfTrades.Total()-1;i>=0;i--)
{
CTrade* trade=_listOfTrades.At(i);
// action with CTrade object
printf(trade.m_ticketId);
}
}
};

I use JAson.mqh lib for saving data to json - it is simpler. I use json.mqh (prev. messages on SOF if needed, or download from http://lordy.co.nf) for deserialization because the first lib has a bug when parsing arrays (or maybe fixed already, dont know).
If you need a deserialization example, please ask for link in comment
#include <JAson.mqh> //https://www.mql5.com/en/code/13663
class CTrade : public CObject{
//...
public:
static void jsonList(CArrayObj* list, CJAVal &js)
{
for(int i=0;i<list.Total();i++)
{
CTrade *trade=list.At(i);
js["array"].Add(trade.json());
}
}
CJAVal json()const
{
CJAVal result;
result["ticketId"]=(string)m_ticketId;
result["entry"]=DoubleToString(m_entry,_Digits);
result["tp1"]=DoubleToString(m_tp1,_Digits);
result["tp2"]=DoubleToString(m_tp2,_Digits);
result["tp3"]=DoubleToString(m_tp3,_Digits);
result["sl"]=DoubleToString(m_sl,_Digits);
return result;
}
};
void save(CArrayObj* list)
{
int handle=FileOpen(generateFileName(InpMagicNumber,_Symbol),FILE_WRITE);
if(handle==INVALID_HANDLE){Print(__LINE__,__FILE__," error# ",_LastError);return;}
FileWriteString(handle,CTrade::jsonList(list).Serialize());
FileClose(handle);
}

Related

proper video streaming with rxjava

To handle a video stream from a webcam (delivered by opencv) i am considering to use RxJava.
I am hoping to achieve the following:
being able to control the frames per second to be delivered
to be able to handle different inputs - e.g. a life webcam, a video or even a still picture
being able to switch to a picture-by-picture handling under the control of a gui
I have been experimenting a bit with RxJava but i am confused about the debounce, throttleFirst and async operators
Examples like https://stackoverflow.com/a/48723331/1497139 show some code but I am missing more detailed explanation.
Where could I find a decent example for video processing or something similar along the needs mentioned above?
The code below does some non async logic at this time - please let me know if i could build on it:
ImageFetcher
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
/**
* fetcher for Images
*
*/
public class ImageFetcher {
// OpenCV video capture
private VideoCapture capture = new VideoCapture();
private String source;
protected int frameIndex;
public int getFrameIndex() {
return frameIndex;
}
/**
* fetch from the given source
*
* #param source
* - the source to fetch from
*/
public ImageFetcher(String source) {
this.source = source;
}
/**
* try opening my source
*
* #return true if successful
*/
public boolean open() {
boolean ret = this.capture.open(source);
frameIndex=0;
return ret;
}
/**
* fetch an image Matrix
*
* #return - the image fetched
*/
public Mat fetch() {
if (!this.capture.isOpened()) {
boolean ret = this.open();
if (!ret) {
String msg = String.format(
"Trying to fetch image from unopened VideoCapture and open %s failed",
source);
throw new IllegalStateException(msg);
}
}
final Mat frame = new Mat();
this.capture.read(frame);
frameIndex++;
return !frame.empty() ? frame : null;
}
#Override
protected void finalize() throws Throwable {
super.finalize();
}
/**
* convert me to an observable
* #return a Mat emitting Observable
*/
public Observable<Mat> toObservable() {
// Resource creation.
Func0<VideoCapture> resourceFactory = () -> {
VideoCapture capture = new VideoCapture();
capture.open(source);
return capture;
};
// Convert to observable.
Func1<VideoCapture, Observable<Mat>> observableFactory = capture -> Observable
.<Mat> create(subscriber -> {
boolean hasNext = true;
while (hasNext) {
final Mat frame = this.fetch();
hasNext = frame!=null && frame.rows()>0 && frame.cols()>0;
if (hasNext) {
String msg = String.format("->%6d:%4dx%d", frameIndex, frame.cols(), frame.rows());
System.out.println(msg);
subscriber.onNext(frame);
}
}
subscriber.onCompleted();
});
// Disposal function.
Action1<VideoCapture> dispose = VideoCapture::release;
return Observable.using(resourceFactory, observableFactory, dispose);
}
}
ImageSubscriber
import org.opencv.core.Mat;
import rx.Subscriber;
public class ImageSubscriber extends Subscriber<Mat> {
public Throwable error;
public int cols = 0;
public int rows=0;
public int frameIndex=0;
public boolean completed = false;
public boolean debug = false;
#Override
public void onCompleted() {
completed = true;
}
#Override
public void onError(Throwable e) {
error = e;
}
#Override
public void onNext(Mat mat) {
cols = mat.cols();
rows = mat.rows();
frameIndex++;
if (cols==0 || rows==0)
System.err.println("invalid frame "+frameIndex);
if (debug) {
String msg = String.format("%6d:%4dx%d", frameIndex, cols, rows);
System.out.println(msg);
}
}
};

MQL4 Send objects array as function parameter

I had the function as a class member with an array of my custom object as a parameter:
class Stochastic { ... some class which sent into initializeStochastics method as param };
class StochasticInitializer {
public:
Properties *properties[8];
public:
StochasticInitializer(void) {
this.properties = ...
}
public:
void initializeStochastics(Stochastic& *stochastics[]) { // This param is my problem
for (int i = 0 ;i < ArraySize(properties); i++) {
if (properties[i].enabled) {
stochastics[i] = new Stochastic(properties[i]);
}
}
}
};
My errors:
'&' - comma expected
']' - declaration without type
']' - comma expected
'initializeStochastics' - wrong parameters count
'stochastics' - undeclared identifier
I take syntax from here, but perhaps it solution for MQL5.
Can I send an array of class instances as a method parameter in MQL4? If "yes" - how, if no - it answers too.
Everything works (almost works) just decide whether you are going to create an global array or with pointer access (need to delete it after you finish). Here is example of pointers. Also, please provide MCVE next time, because someone needs to write all that useless stuff like properties&stoch classes to make it testable.
class Properties
{
public:
bool enabled;
int periodK;
Properties(bool _enabled,int k):enabled(_enabled),periodK(k){}
~Properties(){}
};
class Stochastic
{
public:
int periodK;
Stochastic(){}
~Stochastic(){}
Stochastic(Properties *prop):periodK(prop.periodK){}
double get(const int shift,const int buffer=0)const{return iStochastic(_Symbol,0,periodK,3,3,MODE_SMA,STO_LOWHIGH,buffer,shift);}
};
class StochasticInitializer
{
public:
Properties *properties[8];
StochasticInitializer()
{
Deinit();
properties[0]=new Properties(true,5);
properties[1]=new Properties(true,13);
properties[2]=new Properties(true,14);
properties[3]=new Properties(true,15);
properties[4]=new Properties(true,16);
properties[5]=new Properties(true,17);
properties[6]=new Properties(true,18);
properties[7]=new Properties(false,19);
}
~StochasticInitializer(){Deinit();}
void Deinit(const int reason=0){ for(int i=0;i<ArraySize(properties);i++)delete(properties[i]); }
void initializeStochastics(Stochastic *&stochastics[])// THIS IS WHAT YOU NEED IN CASE OF POINTERS
{
for(int i=0;i<ArraySize(properties);i++)
{
if(properties[i].enabled)
{
stochastics[i]=new Stochastic(properties[i]);
}
}
}
};
StochasticInitializer initializer;
void OnTick()
{
Stochastic *array[8]; //THIS IS ARRAY OF POINTERS
initializer.initializeStochastics(array);
for(int i=0;i<ArraySize(array);i++)
{
printf("%i %s: %d %s",__LINE__,__FILE__,i,CheckPointer(array[i])==POINTER_INVALID ? "null" : (string)array[i].periodK);
}
for(int i=ArraySize(array)-1;i>=0;i--)delete(array[i]);//DELETING POINTERS
ExpertRemove();
}

How to implement the Delphi protected member access trick in C++ builder?

I need access to TControlItem.InternalSetLocation which is protected. I Delphi you would do
type
THackControlItem = class(TControlItem);
How do you do this in C++ Builder?
As in Delphi, you need to inherit the class but also override and make public the protected function. However, I wouldn't recommend to use it in production code.
class THackControlItem : public TControlItem
{
public:
void __fastcall InternalSetLocation(int AColumn, int ARow, bool APushed, bool MoveExisting)
{
TControlItem::InternalSetLocation(AColumn, ARow, APushed, MoveExisting);
}
};
In the program
TControlItem* ci = ...;
static_cast<THackControlItem*>(ci)->InternalSetLocation(...);
This is a nice trick I think Remy Lebeau showed me but can not find the QA anymore...
//---------------------------------------------------------------------------
#ifndef _TDirectMemoryStream
#define _TDirectMemoryStream
class TDirectMemoryStream:TMemoryStream // just for accessing protected SetPointer
{
public:
void SetMemory(BYTE *ptr,DWORD siz) { SetPointer(ptr,siz); Position=0; };
};
#endif
//---------------------------------------------------------------------------
You simply create new class that is descendant of the class you want to access. Now just add get/set functions for the protected members ...
Now usage:
TMemoryStream *mem=new TMemoryStream(); // original class instance you want to access
// overtype to our new class and access/use you get/set ...
((TDirectMemoryStream*)(mem))->SetMemory(hdr->lpData,hdr->dwBytesUsed);
delete mem; // release if not needed anymore
I am using it btw to feed a memory stream with custom memory data hdr coming from vfw camera so I can properly decode it using TJPEGImage class instead of writing the data into file and loading it back each frame ...
Here another example:
class A
{
protected:
int x;
public:
int getx(){ return x; }
};
class hack_A:A
{
public:
void setx(int _x){ x=_x; }
};
void test()
{
A a;
hack_A *ha=(hack_A*)&a;
ha->setx(10);
a.getx(); // print the x somwhere
}
However this will not work for private members ... In such case its doable too but requires access to A source code:
class A
{
protected:
int x;
private:
int y;
public:
int getx(){ return x; }
int gety(){ return y; }
friend class hack_A; // but this one requires access to A soourcecode
};
class hack_A:A
{
public:
void setx(int _x){ x=_x; }
void sety(int _y){ y=_y; }
};
void test()
{
A a;
hack_A *ha=(hack_A*)&a;
ha->setx(10);
ha->sety(20);
a.getx(); // print the x somwhere
a.gety(); // print the x somwhere
}

dependency injection in Arduino

I've started working with Arduino and I want to do a time share system so I do not use the delay command.
I have a problem when I try to register objects that inherit from another.
Here I have a test code that should show in the terminal: "Wow wow Miuau miuau ..."
I have doubts when I try to create an Interface and how do I declare the register () function so that Cat and Dog objects can be entered in the Animal type Array.
The following code is only to show the problem:
class Animal {
public:
void message() {
}
};
class Dog : public Animal {
public:
void message() {
Serial.println("Guau guau");
}
};
class Cat : public Animal {
public:
void message() {
Serial.println("Miau miau ");
}
};
class Multiplex {
private:
int index = 0;
Animal objects[5];
public:
void register(Animal object) {
objects[index] = object;
index++;
}
void go() {
for(int i = 0;i<index;i++) {
objects[i].message();
}
}
};
Dog dog;
Cat cat;
Multiplex multiplex;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
multiplex.register(dog);
multiplex.register(cat);
}
void loop() {
// put your main code here, to run repeatedly:
multiplex.go();
delay(1000);
}
Any help is welcome ...
Thanks and sorry for my english.
In this case you have to use polymorphism (virtual methods). But it still won't work with so many copies of "registered" object into the Animal base class (it shows nothing because Animal::message() is called). You have to use pointers (or references - but it's not so easy in this case)
class Animal { // pure virtual class (abstract class)
public:
virtual void message() = 0; // The '= 0;' makes whole class "pure virtual"
};
class Dog : public Animal {
public:
virtual void message() {
Serial.println("Guau guau");
}
};
class Cat : public Animal {
public:
virtual void message() {
Serial.println("Miau miau ");
}
};
class Multiplex {
private:
int index = 0;
Animal * objects[5];
public:
void reg(Animal * object) { // pass pointer to the object
objects[index] = object; // object must be valid for whole time
index++;
}
void go() {
for(int i = 0;i<index;i++) {
objects[i]->message();
}
}
};
Dog dog;
Cat cat;
Multiplex multiplex;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
multiplex.reg(&dog);
multiplex.reg(&cat);
}
void loop() {
// put your main code here, to run repeatedly:
multiplex.go();
delay(1000);
}
If you don't like dynamic polymorphism, you have to use something like object type, switch and typecasting to its correct type.

How to combine traditional and Future-based API in one interface in Dart?

I would like to parse binary file (from some old game) as on desktop as in browser.
So, I should use abstract class, which can read binary data from array of bytes:
abstract class BinData {
int readByte();
String readNullString(){
var buffer = new StringBuffer();
int char;
do {
char = readByte();
if (char == 0){
break;
}
buffer.writeCharCode(char);
} while(true);
return buffer.toString();
}
}
Now I can implement my parser. For example:
class Parser {
BinData _data;
void load(BinData data){
...
}
}
For desktop console application I use dart:io RandomAccessFile:
class FileBinData extends BinData {
RandomAccessFile _file;
FileBinData.from(RandomAccessFile file){
this._file = file;
}
int readByte(){
return this._file.readByteSync();
}
}
For web application I have to use dart:html FileReader. However, this class has only Future-based API, which isn't compatible with my interface:
class WebFileBinData extends BinData {
File _file;
int _position = 0;
WebFileBinData.from(File file){
this._file = file;
}
int readByte(){
Blob blob = _file.slice(_position, _position + 1);
FileReader reader = new FileReader();
var future = reader.onLoad.map((e)=>reader.result).first
.then((e) { ... });
reader.readAsArrayBuffer(blob);
...
}
}
How can I solve it?
Your readByte() should return Future<int> instead of int. You can return a Future from a function/method even when it doesn't do any async operation (return new Future.value(5);) but you can not return int (or any non-Future value) from a function which executes async operations, at least not when the value should be returned as result of the async operation.
You also need to ensure to connect all async calls.
Future<int> readByte(){
return reader.onLoad.map((e)=>reader.result).first
.then((e) {
...
return reader.readAsArrayBuffer(blob);
});
** readNullString
Future<String> readNullString() {
var buffer = new StringBuffer();
int char;
return Future.doWhile(() {
return readByte().then((char) {
if (char == 0) {
return false; // end doWhile
}
buffer.writeCharCode(char);
return true; // continue doWhile
});
}).then((_) => buffer.toString()); // return function result
}

Resources