Update:
This is even stranger than I thought. It seems that even looking at the contents of a struct means the file won't write:
struct ShootRecord { bool is_overshoot; double level; };
In OnDeInit I try to write the contents of the first element of an array of ShootRecord (my struct):
void OnDeinit(const int reason) { int h=FileOpen("test.csv",FILE_WRITE|FILE_ANSI|FILE_CSV,","); if(h==INVALID_HANDLE) { Comment("Error opening file"); } ShootRecord shoot = overshoots[0]; double d = shoot.level; string test = DoubleToString(d, 5); Comment("test: " + test); FileWrite(h, test); FileClose(h); }
The variable 'test' appears correctly in the debugger watch list and renders fine as a comment on the screen. However the file is always empty. If I substitute an actual double into the line, rather than accessing the struct, like this:
ShootRecord shoot = overshoots[0]; double d = 0.0258644; //double d = shoot.level;
then the file still fails to write (!!!!), but if I remove the (unnecessary) assignment to the struct:
//ShootRecord shoot = overshoots[0]; double d = 0.0258644; //double d = shoot.level;
then the FileWrite works fine.
This is bizarre. I have spent a day reading forum posts without finding any references to this behaviour. There is no error generated (I have used _LastError), and if you step through in debug, everything looks fine.
So it seems to me that even mentioning a struct is enough to kill the FileWrite. What is going on?
Update:
This is even stranger than I thought. It seems that even looking at the contents of a struct means the file won't write:
In OnDeInit I try to write the contents of the first element of an array of ShootRecord (my struct):
The variable 'test' appears correctly in the debugger watch list and renders fine as a comment on the screen. However the file is always empty. If I substitute an actual double into the line, rather than accessing the struct, like this:
then the file still fails to write (!!!!), but if I remove the (unnecessary) assignment to the struct:
then the FileWrite works fine.
This is bizarre. I have spent a day reading forum posts without finding any references to this behaviour. There is no error generated (I have used _LastError), and if you step through in debug, everything looks fine.
So it seems to me that even mentioning a struct is enough to kill the FileWrite. What is going on?
//+------------------------------------------------------------------+ //| StructArray.mq5 | //| Copyright 2020, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ struct overshootstruct { double c; double d; overshootstruct() { c=d=0.00; } ~overshootstruct() {} }; struct Test { double a; double b; Test() { a=b=0.00; } ~Test() {} }; int OnInit() { overshootstruct overshoot[]; Test test_a[]; for(int i=0;i<10;i++) { ArrayResize(overshoot,i+1); overshoot[i].c = (double)(i+1); overshoot[i].d = (double)(i+2); } ArrayPrint(overshoot); ArrayResize(test_a,2); test_a[0].a = 1.23; test_a[0].b = 2.34; test_a[1].a = 1.23; test_a[1].b = 2.34; overshoot[0].c = test_a[0].a; overshoot[0].d = test_a[0].b; ArrayPrint(overshoot); Print("array struct of test_a size is ",ArraySize(test_a)); Print("array struct of overshoot is ",ArraySize(overshoot)); int h=FileOpen("test.csv",FILE_WRITE|FILE_ANSI|FILE_CSV,","); if(h==INVALID_HANDLE) { Comment("Error opening file"); } int _size = ArraySize(overshoot); PrintFormat("%s file is available for writing","test.csv"); for (int i=0;i<_size;i++) { FileWrite(h, "fubar"); } PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH)); FileClose(h); //--- return(INIT_SUCCEEDED); }
KO 0 23:03:13.721 Tester expert file added: Experts\StructArray.ex5. 16721 bytes loaded IH 0 23:03:13.742 Tester initial deposit 10000000.00 USD, leverage 1:500 IM 0 23:03:13.742 Tester successfully initialized JI 0 23:03:13.742 Network 16 Kb of total initialization data received FP 0 23:03:13.742 Tester Intel Xeon E5-2686 v4 @ 2.30GHz, 8191 MB KE 0 23:03:13.777 Symbols EURUSD: symbol to be synchronized HQ 0 23:03:13.778 Symbols EURUSD: symbol synchronized already, 18 bytes received MP 0 23:03:13.781 History EURUSD: history synchronization started LG 0 23:03:13.786 History EURUSD: load 27 bytes of history data to synchronize in 0:00:00.002 PR 0 23:03:13.786 History EURUSD: history synchronized from 1999.01.04 to 2020.08.21 NE 0 23:03:13.787 Ticks EURUSD: ticks synchronization started RR 0 23:03:13.788 Ticks EURUSD: load 34 bytes of tick data to synchronize in 0:00:00.000 DO 0 23:03:13.788 Ticks EURUSD: history ticks synchronized from 2019.03.29 to 2020.08.21 LH 0 23:03:13.964 History EURUSD,M15: history cache allocated for 40787 bars and contains 40650 bars from 2019.01.02 09:00 to 2020.08.20 23:45 MJ 0 23:03:13.965 History EURUSD,M15: history begins from 2019.01.02 09:00 OE 0 23:03:13.976 Tester EURUSD,M15 (XMGlobal-MT5 2): generating based on real ticks KN 0 23:03:13.976 Tester testing with execution delay 251 milliseconds OI 0 23:03:13.976 Tester EURUSD,M15: testing of Experts\StructArray.ex5 from 2020.08.21 00:00 to 2020.08.23 00:00 started EJ 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [c] [d] CP 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [0] 1.00000 2.00000 FM 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [1] 2.00000 3.00000 IJ 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [2] 3.00000 4.00000 DG 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [3] 4.00000 5.00000 GL 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [4] 5.00000 6.00000 JI 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [5] 6.00000 7.00000 MF 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [6] 7.00000 8.00000 HS 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [7] 8.00000 9.00000 FI 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [8] 9.00000 10.00000 NE 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [9] 10.00000 11.00000 ES 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [c] [d] IO 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [0] 1.23000 2.34000 FD 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [1] 2.00000 3.00000 IQ 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [2] 3.00000 4.00000 DN 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [3] 4.00000 5.00000 GK 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [4] 5.00000 6.00000 JP 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [5] 6.00000 7.00000 MM 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [6] 7.00000 8.00000 HJ 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [7] 8.00000 9.00000 FF 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [8] 9.00000 10.00000 NL 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 [9] 10.00000 11.00000 HE 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 array struct of test_a size is 2 IG 0 23:03:14.015 StructArray (EURUSD,M15) 2020.08.21 00:00:00 array struct of overshoot is 10 RO 0 23:03:14.016 StructArray (EURUSD,M15) 2020.08.21 00:00:00 test.csv file is available for writing NL 0 23:03:14.016 StructArray (EURUSD,M15) 2020.08.21 00:00:00 File path: C:\Users\Administrator\AppData\Roaming\MetaQuotes\Tester\BB16F565FAAA6B23A20C26C49416FF05\Agent-127.0.0.1-3000\Files\
Consult this (mql5 code add property strict if you use it in mql4)
struct shoots { bool set; double value; datetime time; shoots(void){set=false;value=0;time=0;} }; shoots ShootsArray[]; int OnInit() { //--- //fill up with random data ArrayResize(ShootsArray,20,0); //fill half for(int rd=0;rd<10;rd++) { //irrelevant stuff to your issue just getting data ,ignore from here ... ResetLastError(); int error_sum=0; double h=iHigh(_Symbol,_Period,rd+1); error_sum+=GetLastError(); datetime t=iTime(_Symbol,_Period,rd+1); error_sum+=GetLastError(); if(error_sum==0) { //...until here //fill your struct array ShootsArray[rd].set=true;//has data ShootsArray[rd].value=h;//high ShootsArray[rd].time=t;//time } } //fill up with random data ends here //save int method=1; //method 1 Human Readable Format : [i dont know if the ea can load it,havent tested/needed it] if(method==1) { int fop=FileOpen("test_struct_array.csv",FILE_WRITE|FILE_ANSI|FILE_CSV,","); if(fop==INVALID_HANDLE){Alert("Cant create file");ExpertRemove();} if(fop!=INVALID_HANDLE) { //header FileWrite(fop,"Set","Time","Value"); for(int x=0;x<ArraySize(ShootsArray);x++) { FileWrite(fop,ShootsArray[x].set,ShootsArray[x].time,ShootsArray[x].value); } FileClose(fop); } } //method 1 Human Readable Format ends here //method 2 ,save load capacity if(method==2) { int fop=FileOpen("test_struct_array.extention",FILE_WRITE|FILE_BIN); if(fop==INVALID_HANDLE){Alert("Cant create file");ExpertRemove();} if(fop!=INVALID_HANDLE) { FileWriteArray(fop,ShootsArray,0,ArraySize(ShootsArray)); FileClose(fop); } } //method 2 ,save load capacity ends here //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- ArrayFree(ShootsArray); }
Thank you kind stranger.
The main issue was that when I didn't use the struct, the file was correctly written to the Terminal Files folder (presumably as well as the Tester/Files folder), so I was expecting to look in there each time.
When I DID use the struct, the file was only written to the Tester folder. I don't know why. However your tracing lines of code really helped me isolate what was happening.
I also don't yet understand the last properties (methods?) of the structs you used (probably because I am coming from C# not Cpp), but I am going to look them up now to see whether they also make a difference or are not required.
Much appreciated.
Thank you kind stranger.
The main issue was that when I didn't use the struct, the file was correctly written to the Terminal Files folder (presumably as well as the Tester/Files folder), so I was expecting to look in there each time.
When I DID use the struct, the file was only written to the Tester folder. I don't know why. However your tracing lines of code really helped me isolate what was happening.
I also don't yet understand the last properties (methods?) of the structs you used (probably because I am coming from C# not Cpp), but I am going to look them up now to see whether they also make a difference or are not required.
Much appreciated.
You are welcome , the method int is just for testing ,its not required .
Just out of curiosity, do you really indent your code like this or is your translator modifying your indentations?
ehehe ,yeah ,its a silly leftover from coding with notepad .

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Why does this not work? overshoots is an array of struct...
but this does.
Using the debugger I can see that _size gets correctly set as the size of the array called overshoots. So it is an integer and is equal to 12.
More struct weirdness below...