My attempt to create a .bar file

Posted By: Pork

My attempt to create a .bar file - 01/03/14 14:10

Hello all,
after Dusktrader's excellent trading script, I wa eager to create some other strategy's. Come to find out, I don't have access to the history that I need from my trading account with Finfx. I don't have a fxcm account so I went to histdata and downloaded a sample of their data.
the data is formatted as follows:
Row Fields:
DateTime Stamp,Bid Quote,Ask Quote,Volume

DateTime Stamp Format:
YYYYMMDD HHMMSSNNN

Legend:
YYYY – Year
MM – Month (01 to 12)
DD – Day of the Month
HH – Hour of the day (in 24h format)
MM – Minute
SS – Second

I've attached my script which doesn't seem to be able to move the open,close,high and low to the TICK structure and doesn't seem to create the .bar file. It also aborts after the third time thru.
I'm out of ideas. Would appreciate any help any one can bring.
Thanks
P

//convert History downloaded from www.histdata.com
//download each year, change in excel to use a comma delimited file, if not already
//sorted so the latest entry in first as required by zorro.
//This script will read the file defined in the script, convert the records to Zorro's
//format and then write them to a binary file name export.bar to be used by Zorro.
//youo can then rename the file to the Zorro .bar format.
//the format of the histdata.com file is DateTime,Open,High,Low,Close,Volume
//the format for zorron is the tick stru included in include\trading.h
//including OLE Date.counting days since midnight 30 December 1899
//typedef struct TICK{ float fOpen, fClose; float fHigh, fLow; DATE time; // time of the tick in UTC time, OLE date/time format} TICK;
//
//the timezone for the histdata.com files is EST without daylight savings time
//so the conversion must take that into account
#include <default.c>
//#include <litec.h>
#include <stdio.h>
#include <trading.h>

TICK mytick;
int count=0;

typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;

API(SystemTimeToVariantTime,oleaut32)
int _stdcall SystemTimeToVariantTime(SYSTEMTIME* lpSystemTime, double* pvtime);

DATE ConvertTime(int Year,int Month,int Day,int Hour,int Minute)
{
SYSTEMTIME Time;
memset(&Time,0,sizeof(SYSTEMTIME));
Time.wYear = Year;
Time.wMonth = Month;
Time.wDay = Day;
Time.wHour = Hour;
Time.wMinute = Minute;
DATE vTime;
SystemTimeToVariantTime(&Time,&vTime);
return vTime;
}

function convertdata(string csv)
{
string nextline = strstr(csv,"\n");//this is the file without the first line
string separator = ",";

int Year,Month,Day,Hour,Minute;
int mysec;
//use the csv string to seperate the date time
//format of datetime is "YYYYMMDD HHMMSS" SS is always zero and is not used
sscanf(strtok(csv,separator),"%4i%2i%2i %2i%2i%2i",&Year,&Month,&Day,&Hour,&Minute,&mysec);
mytick.time = ConvertTime(Year,Month,Day,Hour,Minute);

//separate the other vars last column is vol it is always 0 and is ignored
sscanf(strtok(0,separator),"%f",&mytick.fOpen);
sscanf(strtok(0,separator),"%f",&mytick.fHigh);
sscanf(strtok(0,separator),"%f",&mytick.fLow);
sscanf(strtok(0,separator),"%f",&mytick.fClose);
printf("\n %f %f %f %f %f",mytick.time,mytick.fOpen,mytick.fHigh,mytick.fLow,mytick.fClose);

return nextline;
}

function main()
{
string Name = "History\\AUDCAD_M1_2012.csv"; // name of the CSV file containing M1 data
if(!file_date(Name)){
quit("File not found!");
}
//open and create export.bar
FILE* pfile;
pfile=fopen("export.bar","w+b");
if(pfile==NULL){
quit("\n unable to open bar file");
}

printf("\n%s found export file opened",Name);
string mycontent = file_content(Name);
printf("\n firstline %s",mycontent);
while(mycontent) {
mycontent=convertdata(mycontent);
printf("\n nextline %s", mycontent);
fwrite(&mytick,sizeof(mytick),sizeof(mytick),pfile);
if(ferror(pfile)){
printf("\nfile write error");
}
x++;
}//endwhile
printf("\n before close file");
fclose(pfile);
}
Posted By: dusktrader

Re: My attempt to create a .bar file - 01/03/14 17:28

Rather than go through all that, it would be easier to just open an FXCM demo account and download the history that way. Have you tried this yet? FXCM has several pairs and using the Download.c script it's pretty easy to get the ones you want.
Posted By: POGLife

Re: My attempt to create a .bar file - 01/03/14 22:20

Thanks for this. Been really helpful dusktrader. And thanks for asking this Pork.
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/03/14 23:17

Still, this script is quite interesting because Pork did some important homework there, especially with dateformat munging, parsing etc... Previously when I needed to convert date formats, I was too lazy to discover how to do it properly, so I cheated. wink

I will take a peek Pork, and see if the script can be finished. Thanks for your work so far.
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/03/14 23:36

Pork, you're describing their tick data in the beginning of your post, yet it seems that you eventually downloaded their M1 data. I will assume that you wanted to import the latter, that should be much easier to accomplish. But later I will build upon that, to create bar synthesizer, so that we can also import tick data and convert it to M1, and some other interesting formats. At least, that's the idea, currently all those windows calls and data structures look very spooky to me. tongue

Here's what my sample import data looks like:

Code:
20131201 170000;1.358680;1.358740;1.358680;1.358680;0
20131201 170100;1.358700;1.358750;1.358650;1.358650;0
20131201 170200;1.358680;1.358750;1.358640;1.358740;0
20131201 170300;1.358850;1.359180;1.358840;1.359070;0



Downloaded from http://www.histdata.com/download-free-fo.../eurusd/2013/12
Posted By: Pork

Re: My attempt to create a .bar file - 01/04/14 00:14

Thanks Dusk trader, I did not know about the FXCM demos. will give that a try.
@acidburn.. I beleive I loaded the M1 data. Here's a sample:
20120102 020200,1.04143,1.04152,1.04143,1.04152,0
20120102 023700,1.04072,1.04075,1.0395,1.04075,0
20120102 023800,1.0412,1.0412,1.04069,1.04088,0
20120102 023900,1.04085,1.04095,1.04059,1.04095,0
20120102 024000,1.04093,1.04097,1.04073,1.04094,0
20120102 024100,1.04092,1.04103,1.0409,1.041,0
20120102 024200,1.04087,1.04108,1.04087,1.04108,0
20120102 024300,1.04105,1.04108,1.04094,1.04097,0
20120102 024400,1.04098,1.04108,1.04098,1.04102,0

Hopefully you have better luck than I did finding the issue or issues. I've tried a number of things over the last few days without effect. I appreciate your efforts.
P
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/04/14 00:46

Lots of stuff is confusing, yes. Zorro crashes left and right. It crashes so often that I had to move the icon closer, so I can restart it faster. grin

Definitely hard working without the debugger...

The data I downloaded uses ';' as a separator, but otherwise looks the same. A different separator should not be a big issue.
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/04/14 11:13

And here's the first version for the public. It's small, simple, beautiful and it actually works. Unfortunately, it's still not doing what Zorro expects, because bar files are backwards in time. &^%^$$#@#&*!

I'm afraid coding that last requirement to make bar file fully Zorro compliant will make it much uglier, thus I decided to post this intermediate version. I still think that bar files are poorly designed, CPU cycles are cheap, human time is precious.

While I'm adding the final piece of magic, if anybody can quickly explain how to add a new instrument to Zorro would be helpful. Or point to an existing forum post, I'm sure it popped up before and I might have it bookmarked, but I'll never find it in dozens of bookmarks I collected. This will come handy to not overwrite existing history files, but test with new instrument names.

Code:
#include <default.c>
#include <stdio.h>
#include <windows.h>

typedef struct SYSTEMTIME {
	WORD wYear;
	WORD wMonth;
	WORD wDayOfWeek;
	WORD wDay;
	WORD wHour;
	WORD wMinute;
	WORD wSecond;
	WORD wMilliseconds;
} SYSTEMTIME;

int _stdcall SystemTimeToVariantTime(SYSTEMTIME *lpSystemTime, DATE *pvtime);

DATE ConvertTime(int year, int month, int day, int hour, int minute, int second)
{
	SYSTEMTIME Time;
	DATE vTime;

	memset(&Time, 0, sizeof(SYSTEMTIME));
	Time.wYear = year;
	Time.wMonth = month;
	Time.wDay = day;
	Time.wHour = hour;
	Time.wMinute = minute;
	Time.wSecond = second;

	SystemTimeToVariantTime(&Time, &vTime);
	return vTime;
}

function main()
{
	char line[64];
	int year, month, day, hour, minute, second, bars = 0, errors = 0;
	float open, high, low, close;
	FILE *in, *out;
	TICK tick;

	if (!(out = fopen("export.bar", "wb"))) {
		printf("\ncan't open output file");
		return;
	}

	if (!(in = fopen("EURUSD_M1_201312.csv", "r"))) {
		printf("\ncan't open input file");
		fclose(out);
		return;
	}

	while (fgets(line, 64, in)) {
		bars++;
		if (sscanf(line, "%4d%2d%2d %2d%2d%2d;%f;%f;%f;%f;",
			&year, &month, &day, &hour, &minute, &second,
			&tick.fOpen, &tick.fHigh, &tick.fLow, &tick.fClose) == 10) {
			tick.time = ConvertTime(year, month, day, hour, minute, second);
			if (!fwrite(&tick, sizeof(tick), 1, out)) {
				printf("\nwrite error");
				fclose(in);
				fclose(out);
				return;
			}
		} else {
			errors++;
		}
	}

	fclose(in);
	fclose(out);
	printf("\nConverted: %d bars, %d errors", bars, errors);
}

Posted By: Pork

Re: My attempt to create a .bar file - 01/04/14 13:41

WOW! Truly amazing!
My idea for the zorro requirement of reverse order was to sort the csv file in excel before running the script. Otherwise a bubble sort should work. tho not very effecient.
as far as the bar file goes I was just going to rename.
Thanks acidburn.
Adding a new instrument is explained on the data import page. There is also a slightly confusing sript to create the needed entries.
P
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/04/14 13:56

Done! The generated export.bar file now has bars in reverse order, as required by Zorro. Instead of slowly parsing csv backwards, or stuffing all bars in the memory to write them out in reverse at the very end, I decided to go with a temporary file. It should be the most efficient approach of the three (having in mind that Zorro is an ancient 32bit architecture). Will pay off later when I choke Zorro with gigabytes of tick data. grin

The script has not been tested, I leave that to you. If you find any bugs, do report!

Code:
#include <default.c>
#include <stdio.h>
#include <windows.h>

typedef struct SYSTEMTIME {
	WORD wYear;
	WORD wMonth;
	WORD wDayOfWeek;
	WORD wDay;
	WORD wHour;
	WORD wMinute;
	WORD wSecond;
	WORD wMilliseconds;
} SYSTEMTIME;

int _stdcall SystemTimeToVariantTime(SYSTEMTIME *lpSystemTime, DATE *pvtime);

DATE ConvertTime(int year, int month, int day, int hour, int minute, int second)
{
	SYSTEMTIME Time;
	DATE vTime;

	memset(&Time, 0, sizeof(SYSTEMTIME));
	Time.wYear = year;
	Time.wMonth = month;
	Time.wDay = day;
	Time.wHour = hour;
	Time.wMinute = minute;
	Time.wSecond = second;

	SystemTimeToVariantTime(&Time, &vTime);
	return vTime;
}

function main()
{
	FILE *in, *tmp, *out;

	if (!(in = fopen("EURUSD_M1_201312.csv", "r"))) {
		printf("\ncan't open input file");
		return;
	}

	if (!(tmp = tmpfile())) {
		printf("\ncan't open temporary file");
		return;
	}

	if (!(out = fopen("export.bar", "wb"))) {
		printf("\ncan't open output file");
		return;
	}

	char line[64];
	TICK tick;

	int lines = 0, errors = 0;
	while (fgets(line, 64, in)) {
		int year, month, day, hour, minute, second;
		if (sscanf(line, "%4d%2d%2d %2d%2d%2d;%f;%f;%f;%f;",
			&year, &month, &day, &hour, &minute, &second,
			&tick.fOpen, &tick.fHigh, &tick.fLow, &tick.fClose) == 10) {
			tick.time = ConvertTime(year, month, day, hour, minute, second);
			if (!fwrite(&tick, sizeof(TICK), 1, tmp)) {
				printf("\nwrite error");
				return;
			}
		} else {
			errors++;
		}
		lines++;
	}

	printf("\nStep 1/2: %d lines parsed (%d errors)", lines, errors);	

	int offset, bars = 0;
	for (offset = ftell(tmp) - sizeof(TICK); offset >= 0; offset -= sizeof(TICK)) {
		fseek(tmp, offset, SEEK_SET);
		if (fread(&tick, sizeof(TICK), 1, tmp)) {
			if (!fwrite(&tick, sizeof(TICK), 1, out)) {
				printf("\nwrite error");
				return;
			}
			bars++;
		}			
	}

	fclose(out);
	printf("\nStep 2/2: %d bars saved", bars);	
}

Posted By: Pork

Re: My attempt to create a .bar file - 01/06/14 15:53

This is great acidburn!
Got it working with minor changes for filenames and formatting.
I added a printf to try and confirm the writing, but it isn't working out like I expected. Here's the .csv line:
20120102 024400,1.04098,1.04108,1.04098,1.04102,0
here's the printf statement:
printf("\n %f %f %f %f %f",tick.time,tick.fOpen,tick.fHigh,tick.fLow,tick.fClose);
here's the results:
40910.113889 0.010380 0.010376 0.000000 0.000000
The time appears to be OK. the values, not so much.
Is there a better way to confirm the writing?
Thanks,
P
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/06/14 16:06

Originally Posted By: Pork
This is great acidburn!
Got it working with minor changes for filenames and formatting.
I added a printf to try and confirm the writing, but it isn't working out like I expected. Here's the .csv line:
20120102 024400,1.04098,1.04108,1.04098,1.04102,0
here's the printf statement:
printf("\n %f %f %f %f %f",tick.time,tick.fOpen,tick.fHigh,tick.fLow,tick.fClose);
here's the results:
40910.113889 0.010380 0.010376 0.000000 0.000000
The time appears to be OK. the values, not so much.
Is there a better way to confirm the writing?
Thanks,
P


Ah, that is strange, yes. Lost half an hour myself, trying to debug that weird issue. Printf format %f expects double, not float! I believe standard C would promote floats to doubles behind your back, but Lite-C doesn't. So you can get the correct output by manually casting all the floats on the right. Like this:

Code:
printf("\n %f %f %f %f %f", (double) tick.time, (double) tick.fOpen...



At least that's how I workaround the same issue.
Posted By: Pork

Re: My attempt to create a .bar file - 01/06/14 16:13

YEP! That did it. Now they match. WOOOHHOOO!
I had read about manual casting and floats and doubles, but had not found an example and couldn't tell when to do it.
Tell the boss I said it was ok to take an extra 20 out of the petty cash laugh
P
Posted By: Jeff_Raven

Re: My attempt to create a .bar file - 01/06/14 16:50

Originally Posted By: acidburn

While I'm adding the final piece of magic, if anybody can quickly explain how to add a new instrument to Zorro would be helpful.


1. Open Download.c in Zorro Editor

2. Uncomment the line
#define ADD_ASSET "Copper"

and add your new asset name inside the quotes. For example to add the Eur/Nzd pair, the line is:
#define ADD_ASSET "EUR/NZD"

The format of the asset (currency pair) should include the "/" even though the broker name may be just eurnzd (as it is with FXCM).

3. Make sure the line
#define PRICE_HISTORY

is uncommented.

4. Change the line
StartDate = 2013;

to whatever you want for your start date.

5. Save.

6. In Zorro, Make sure you have a valid User and password filled in, and the account is selected for Demo or Real of that user.

7. Click Test. Zorro should log in and begin a download (not swift), and will beep between years.

8. Close Zorro

9. In any text editor, open the Assets.dta and AssetsFix.dta files. The Assets.dta file will now have a new line in it (in alpha order) for your new asset. Copy that line and paste it into the AssetsFix.dta file in the same relative line location. Save and Close both files.

10. Open Zorro, and the new asset should appear in the list.
Posted By: Jeff_Raven

Re: My attempt to create a .bar file - 01/06/14 16:53

Thank you for this work, Pork and acidBurn. I was putting off writing this until I got more comfortable with Lite-C. Now, with a bit of fiddling with the sprintf format, I'll have what I need to migrate some of my MT4 history files into Zorro.
Posted By: Anonymous

Re: My attempt to create a .bar file - 01/06/14 16:59

Thank you Jeff_Raven!

Although I decided to let others test the script. But I will need this soon, too.
Posted By: Pork

Re: My attempt to create a .bar file - 01/06/14 17:50

I'm glad I could be help to someone. blush There are still many times that I feel totally inadequate with Zorro.
For those keeping scorecards at home, I've attached my convert file for you.
P


Description: historyconvert.zip
Attached File
historyconvert.zip  (22 downloads)
Posted By: firesell

Re: My attempt to create a .bar file - 01/09/14 23:11

is there anyway to split a csv file per years ? before importing
Posted By: Pork

Re: My attempt to create a .bar file - 01/10/14 11:50

Hi firesell,
My choice would be decidedly low tech. Open the file in Excel, sort by the date and then copy the years to a separate spreadsheet. I would think I could do this faster than I could create and test a script to write the records to separate csv files. Although I could see how the historyconvert script could be modified to help.
Hope this helps
P
Posted By: dusktrader

Re: My attempt to create a .bar file - 01/10/14 13:26

I was going to suggest a manual way first, but it could quickly get old. If you have to do it more than a handful of times, then it would make sense to automate. In the case of manual, I would choose notepad++ over a spreadsheet program though.
Posted By: easyX

Re: My attempt to create a .bar file - 12/18/17 16:44

Is this still working? Try to get it working but no success so far.
© 2024 lite-C Forums