Metastock data format

/* The orignal 255 record format */

typedef	unsigned char	u_char;
typedef	unsigned short	u_short;

/*
 * MASTER file description
 *  floats are in Microsoft Basic format
 *  strings are padded with spaces, not null terminated
 */
struct rec_1 {
    u_short num_files;	    /* number of files master contains */
    u_short file_num;	    /* next file number to use (highest F# used) */
    char zeroes[49];
};
struct rec_2to255 {	    /* description of data files */
    u_char file_num;	    /* file #, i.e., F# */
    char file_type[2];	    /* CT file type = 0'e' (5 or 7 flds) */
    u_char rec_len;	    /* record length in bytes (4 x num_fields)
*/
    u_char num_fields;	    /* number of 4-byte fields in each record
*/
    char reserved1[2];	    /*  in the data file */
    char issue_name[16];    /* stock name */
    char reserved2;
    char CT_v2_8_flag;	    /* if CT ver. 2.8, 'Y'; o.w., anything else */
    float first_date;	    /* yymmdd */
    float last_date;
    char time_frame;	    /* data format: 'I'(IDA)/'W'/'Q'/'D'/'M'/'Y' */
    u_short ida_time;	    /* <b>intraday</b> (IDA) time base */
    char symbol[14];	    /* stock symbol */
    char reserved3;	    /* <b>MetaStock</b> reserved2: must be a space */
    char flag;		    /* ' ' or '*' for autorun */
    char reserved4;
};

/*
 * EMASTER data structure
 *  floats are in IEEE format
 *  strings are padded with nulls
 */
struct emashdr {
    u_short num_files;	    /* number of files in emaster */
    u_short file_num;	    /* last (highest) file number */
    char stuff[188];
};
struct emasdat {
    char asc30[2];	    /* &quot;30&quot; */
    u_char file_num;	    /* file number F# */
    char fill1[3];
    u_char num_fields;	    /* number of 4-byte data fields */
    char fill2[2];
    char flag;		    /* ' ' or '*' for autorun */
    char fill3;
    char symbol[14];	    /* stock symbol */
    char fill4[7];
    char issue_name[16];    /* stock name */
    char fill5[12];
    char time_frame;	    /* data format: 'D'/'W'/'M'/ etc. */
    char fill6[3];
    float first_date;	    /* yymmdd */
    char fill7[4];
    float last_date;
    char fill8[116];
};

/* seven-field data file description */
struct dathdr7 {
    u_short max_recs;	    /* 0 ==&gt; unlimited size */
    u_short last_rec;	    /* dathdr7 = 1; ctdata7 starts with 2 */
    char zeroes[24];
};
struct ctdata7 {
    float date;
    float open;
    float high;
    float low;
    float close;
    float volume;
    float op_int;
};

/* five-field data file description */
struct dathdr5 {
    u_short max_recs;
    u_short last_rec;
    char zeroes[16];
};
struct ctdata5 {
    float date;
    float high;
    float low;
    float close;
    float volume;
};

/* IEEE floating point format to Microsoft Basic floating point format */
int fieee2msbin(float *src, float *dst) {
    union {
	float a;
	u_long b;
    } c;
    u_short man;
    u_short exp;

    c.a = *src;
    if (c.b) {		/* not zero */
	man = c.b &gt;&gt; 16;
	exp = ((man &lt;&lt; 1) &amp; 0xff00) + 0x0200;
	if (exp &amp; 0x8000 != (man &lt;&lt; 1) &amp; 0x8000)
	    return 1;	/* exponent overflow */
	man = man &amp; 0x7f | (man &gt;&gt; 8) &amp; 0x80;	/* move sign */
	man |= exp;
	c.b = c.b &amp; 0xffff | (long)man &lt;&lt; 16;
    }
    *dst = c.a;
    return 0;
}

/* Microsoft Basic floating point format to IEEE floating point format */
int fmsbin2ieee(float *src, float *dst) {
    union {
	float a;
	u_long b;
    } c;
    u_short man;
    u_short exp;

    c.a = *src;
    if (c.b) {		/* not zero */
	man = c.b &gt;&gt; 16;
	exp = (man &amp; 0xff00) - 0x0200;
	if (exp &amp; 0x8000 != man &amp; 0x8000)
	    return 1;	/* exponent overflow */
	man = man &amp; 0x7f | (man &lt;&lt; 8) &amp; 0x8000;	/* move sign */
	man |= exp &gt;&gt; 1;
	c.b = c.b &amp; 0xffff | (long)man &lt;&lt; 16;
    }
    *dst = c.a;
    return 0;
}
