该文件似乎也包含“交易总和”字段。我稍微改进了我之前的程序:
/* version 1.2 - generates a CSV file on the desktop for another application to create a reverse engineered hcc file */
/* version 1.1 - includes header format and detects the number of data rows */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#pragma pack(1)
union header {
struct {
char magic[2]; // 0x81 0x00
char label[64];
char something[18];
int nrows;
} data;
char rawbytes[189];
};
struct record {
int separator;
int time;
double open, high, low, close;
char additional[10]
};
void printint(char *buf, FILE *fpcsv,int size);
void dumpat(FILE *fp,FILE *fpcsv, int start);
int main(int argc, char **argv) {
FILE *fp,*fpcsv;
union header header;
if ((fpcsv=fopen("C:\\Users\\Hello\\Desktop\\2015.csv", "w"))==NULL) {
perror("C:\\Users\\Hello\\Desktop\\2015.csv"); return 1;
}
if ((fp=fopen("C:\\Users\\Hello\\Desktop\\2015.hcc", "rb"))==NULL) {
perror("C:\\Users\\Hello\\Desktop\\2015.hcc"); return 1;
}
fseek(fp, 0x3be5-sizeof(header), 0);
while (fread(&header, sizeof header, 1, fp)!=0) {
if ((header.data.magic[0]&0xff)!=0x81
|| header.data.magic[1]!=0x00) {
fprintf(stderr, "Bad header magic number at %08lx\n",
ftell(fp)-sizeof(header));
exit(1);
}
fprintf(fpcsv,"Expect %d rows\n", header.data.nrows);
dumpat(fp,fpcsv, header.data.nrows);
// dumpat(fp, 0x3be5);
// dumpat(fp, 0xde1a);
// dumpat(fp, 0x1e169);
// dumpat(fp, 0x2e4a5);
// dumpat(fp, 0x3bd7e);
// dumpat(fp, 0x55c07);
}
fclose(fp);
fclose(fpcsv);
}
void dumpat(FILE *fp,FILE *fpcsv, int nrows) {
struct record data;
int i, extra1, extra2, extra3, pos;
time_t time;
struct tm *tm;
char timebuf[80];
for (i=0; i<nrows; i++) {
if (fread(&data, sizeof(int), 1, fp)==0)
break;
if ((data.separator & 0x00088884) != 0x00088884) {
fprintf(stdout, "bad separator %08x at %lx\n",
data.separator, ftell(fp));
break;
}
extra1=data.separator>>28;
extra2=((data.separator>>24)&0x0f);
extra3=((data.separator>>20)&0x0f);
fread(&data.time, 4 + 8 + 8 + 8 + 8 + extra3 + extra2 + extra1
, 1, fp);
time=data.time;
tm=gmtime(&time);
strftime(timebuf, sizeof timebuf, "%Y-%m-%d %H:%M:%S", tm);
fprintf(fpcsv,"%s,%lf,%lf,%lf,%lf,", timebuf, data.open,
data.high, data.low, data.close);
pos=0;
printint(data.additional+pos,fpcsv, extra3); pos+=extra3;
fprintf(fpcsv,",");
printint(data.additional+pos,fpcsv, extra2); pos+=extra2;
fprintf(fpcsv,",");
printint(data.additional+pos,fpcsv, extra1); pos+=extra1;
fprintf(fpcsv,"\n");
}
}
void printint(char *buf,FILE *fpcsv, int size) {
int val=0, scale=1;
while (size--) {
val+=(*buf++&0xff)*scale;
scale<<=8;
}
fprintf(fpcsv,"%5d", val);
}
结果开始于:
2015-01-02 10:00:00 1.205450 1.205450 1.205140 1.205160 31 9 22000000
2015-01-02 10:01:00 1.205160 1.205210 1.205030 1.205030 31 6 35000000
2015-01-02 10:02:00 1.205030 1.205030 1.204680 1.204730 51 9 54500000
2015-01-02 10:03:00 1.204730 1.204750 1.203460 1.203850 81 18 65700000
2015-01-02 10:04:00 1.203790 1.204210 1.203750 1.204210 79 9 85100000
2015-01-02 10:05:00 1.204200 1.204210 1.204090 1.204170 41 10 38300000
2015-01-02 10:06:00 1.204170 1.204570 1.204150 1.204150 52 13 46600000
2015-01-02 10:07:00 1.204150 1.204460 1.204150 1.204380 44 8 53900000
2015-01-02 10:08:00 1.204380 1.204380 1.203800 1.203800 52 9 70400000
2015-01-02 10:09:00 1.203820 1.204010 1.203600 1.203900 72 9 76100000
标题(包含EUR USD)似乎具有相同的大小,并且数据的开头似乎每次都在 D 之后 176 个字节,但我还不确定在哪里/如何找到它们中的第一个,以及在哪里存储到下一个标题的数据行数,所以我还不能摆脱那些幻数(数据开始的字节位置)。