[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to read from Metastock file format?



PureBytes Links

Trading Reference Links


Here are some files that describe the formats. 
DOWNLOAD THIS FREE SOFTWARE to read/convert the files and get the formats.

-Corey.

----- Original Message -----
From: "Sherwood Hu" <sherwoodhu@xxxxxxxxx>
To: <metastock@xxxxxxxxxxxxx>
Sent: Wednesday, December 26, 2001 7:25 PM
Subject: how to read from Metastock file format?


> Any information? Thanx.
>


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;
}




Converting between Microsoft Binary and IEEE formats1400 Converting between 
Microsoft Binary and IEEE formats
Last update 06/11/96



  //
  // The following are implementations of Microsoft RTL functions
  // not include in the Borland RTL.
  //
  // Functions:
  //     _fmsbintoieee()
  //     _fieeetomsbin()
  //     _dmsbintoieee()
  //     _dieeetomsbin()
  //
  // These functions convert back and forth from Microsoft Binary
  // Format to IEEE floating point format.
  //
  // As with the Microsoft RTL functions,
  //
  // The argument srcX points to the value to be converted and the
  // result is stored at the location given at destX.
  //
  // These routines do not handle IEE NAN's and infinities.  IEEE
  // denormals are treated as 0's.
  //
  // Return:
  //
  // These functions return 0 if the conversion is successful and 1
  // if the conversion causes an overflow.
  //
  //
  //
  // Examples of the use of these functions can be found on-line as
  // MSBIN.ZIP.
  //
  //--------------------------------------------------------------------

  #include <string.h>        /* for strncpy  */

  int _fmsbintoieee(float *src4, float *dest4)
     {
     unsigned char *msbin = (unsigned char *)src4;
     unsigned char *ieee = (unsigned char *)dest4;
     unsigned char sign = 0x00;
     unsigned char ieee_exp = 0x00;
     int i;

     /* MS Binary Format                         */
     /* byte order =>    m3 | m2 | m1 | exponent */
     /* m1 is most significant byte => sbbb|bbbb */
     /* m3 is the least significant byte         */
     /*      m = mantissa byte                   */
     /*      s = sign bit                        */
     /*      b = bit                             */

     sign = msbin[2] & 0x80;      /* 1000|0000b  */

     /* IEEE Single Precision Float Format       */
     /*    m3        m2        m1     exponent   */
     /* mmmm|mmmm mmmm|mmmm emmm|mmmm seee|eeee  */
     /*          s = sign bit                    */
     /*          e = exponent bit                */
     /*          m = mantissa bit                */

     for (i=0; i<4; i++) ieee[i] = 0;

     /* any msbin w/ exponent of zero = zero */
     if (msbin[3] == 0) return 0;

     ieee[3] |= sign;

     /* MBF is bias 128 and IEEE is bias 127. ALSO, MBF places   */
     /* the decimal point before the assumed bit, while          */
     /* IEEE places the decimal point after the assumed bit.     */

     ieee_exp = msbin[3] - 2;    /* actually, msbin[3]-1-128+127 */

     /* the first 7 bits of the exponent in ieee[3] */
     ieee[3] |= ieee_exp >> 1;

     /* the one remaining bit in first bin of ieee[2] */
     ieee[2] |= ieee_exp << 7;

     /* 0111|1111b : mask out the msbin sign bit */
     ieee[2] |= msbin[2] & 0x7f;

     ieee[1] = msbin[1];
     ieee[0] = msbin[0];

     return 0;
     }


  int _fieeetomsbin(float *src4, float *dest4)
     {
     unsigned char *ieee = (unsigned char *)src4;
     unsigned char *msbin = (unsigned char *)dest4;
     unsigned char sign = 0x00;
     unsigned char msbin_exp = 0x00;
     int i;

     /* See _fmsbintoieee() for details of formats   */
     sign = ieee[3] & 0x80;
     msbin_exp |= ieee[3] << 1;
     msbin_exp |= ieee[2] >> 7;

     /* An ieee exponent of 0xfe overflows in MBF    */
     if (msbin_exp == 0xfe) return 1;

     msbin_exp += 2;     /* actually, -127 + 128 + 1 */

     for (i=0; i<4; i++) msbin[i] = 0;

     msbin[3] = msbin_exp;

     msbin[2] |= sign;
     msbin[2] |= ieee[2] & 0x7f;
     msbin[1] = ieee[1];
     msbin[0] = ieee[0];

     return 0;
     }


  int _dmsbintoieee(double *src8, double *dest8)
     {
     unsigned char msbin[8];
     unsigned char *ieee = (unsigned char *)dest8;
     unsigned char sign = 0x00;
     unsigned int ieee_exp = 0x0000;
     int i;

     /* A manipulatable copy of the msbin number     */
     strncpy((char *)msbin,(char *)src8,8);

   /* MS Binary Format                                           */
   /* byte order =>  m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent */
   /* m1 is most significant byte => smmm|mmmm                   */
   /* m7 is the least significant byte                           */
   /*      m = mantissa byte                                     */
   /*      s = sign bit                                          */
   /*      b = bit                                               */

     sign = msbin[6] & 0x80;      /* 1000|0000b  */


   /* IEEE Single Precision Float Format                         */
   /*  byte 8    byte 7    byte 6    byte 5    byte 4  and so on */
   /* seee|eeee eeee|mmmm mmmm|mmmm mmmm|mmmm mmmm|mmmm ...      */
   /*          s = sign bit                                      */
   /*          e = exponent bit                                  */
   /*          m = mantissa bit                                  */

     for (i=0; i<8; i++) ieee[i] = 0;

     /* any msbin w/ exponent of zero = zero */
     if (msbin[7] == 0) return 0;


     ieee[7] |= sign;

     /* MBF is bias 128 and IEEE is bias 1023. ALSO, MBF places  */
     /* the decimal point before the assumed bit, while          */
     /* IEEE places the decimal point after the assumed bit.     */

     ieee_exp = msbin[7] - 128 - 1 + 1023;

     /* First 4 bits of the msbin exponent   */
     /* go into the last 4 bits of ieee[7]   */
     ieee[7] |= ieee_exp >> 4;

     /* The last 4 bits of msbin exponent    */
     /* go into the first 4 bits of ieee[6]  */
     ieee[6] |= ieee_exp << 4;

     /* The msbin mantissa must be shifted to the right 1 bit.   */
     /* Remember that the msbin number has its bytes reversed.   */
     for (i=6; i>0; i--)
         {
         msbin[i] <<= 1;
         msbin[i] |= msbin[i-1] >> 7;
         }
     msbin[0] <<= 1;

     /* Now the mantissa is put into the ieee array starting in  */
     /* the middle of the second to last byte.                   */

     for (i=6; i>0; i--)
         {
         ieee[i] |= msbin[i] >> 4;
         ieee[i-1] |= msbin[i] << 4;
         }
     ieee[0] |= msbin[0] >> 4;

   /* IEEE has a half byte less for its mantissa.  If the msbin */
   /* number has anything in this last half byte, then there is */
   /* an overflow.                                              */
     if (msbin[0] & 0x0f)
         return 1;
     else
         return 0;
     }

  int _dieeetomsbin(double *src8, double *dest8)
     {
     unsigned char ieee[8];
     unsigned char *msbin = (unsigned char *)dest8;
     unsigned char sign = 0x00;
     unsigned char any_on = 0x00;
     unsigned int msbin_exp = 0x0000;
     int i;

     /* Make a clobberable copy of the source number */
     strncpy((char *)ieee,(char *)src8,8);

     for (i=0; i<8; i++) msbin[i] = 0;

     /* If all are zero in src8, the msbin should be zero */
     for (i=0; i<8; i++) any_on |= ieee[i];
     if (!any_on) return 0;

     sign = ieee[7] & 0x80;
     msbin[6] |= sign;
     msbin_exp = (unsigned)(ieee[7] & 0x7f) * 0x10;
     msbin_exp += ieee[6] >> 4;

     if (msbin_exp-0x3ff > 0x80) return 1;

     msbin[7] = msbin_exp - 0x3ff + 0x80 + 1;

     /* The ieee mantissa must be shifted up 3 bits */
     ieee[6] &= 0x0f; /* mask out the exponent in the second byte
     */
     for (i=6; i>0; i--)
         {
         msbin[i] |= ieee[i] << 3;
         msbin[i] |= ieee[i-1] >> 5;
         }

     msbin[0] |= ieee[0] << 3;

     return 0;
     }


  DISCLAIMER: You have the right to use this technical information
  subject to the terms of the No-Nonsense License Statement that
  you received with the Borland product to which this information
  pertains.