大智慧日线数据文件格式分析

文件位置

/dzh2/data/sh/DAY.DAT

/dzh2/data/sz/DAY.DAT

/dzh2/data/hs/DAY.DAT

 

数据格式

说明:数据格式几乎与分析家相同

 

1)、文件头部信息

起止地址

数据内容

数据含义

数据类型

00 - 03

F4 9B 13 FC

文件标志

int

04 - 07

00 06 00 00

未知

int

08 - 0B

00 00 00 00

保留

int

0C - 0F

97 04 00 00

证券总数

int

10 - 13

00 18 00 00

总块数

int

14 - 17

DB 17 00 00

已用块数

int

 

2)、股票数据分配记录,开始于0x0018h

起止地址

数据内容

数据含义

数据类型

18 - 21

31 41 30 30 30...FF

证券代码

byte[10]

22 - 25

B0 09 00 00

日线记录数

int

26 - 57

00 00 BA 03...FF FF

记录块号

word [25]

 

3)、股票数据记录块,开始于0x41000

起止地址

数据内容

数据含义

数据类型

41000 - 41003

80 47 B2 2B

日期

int

41004 - 41007

B9 1E 25 41

开盘价

float

41008 - 4100B

CD CC 4C 41

最高价

float

4100C - 4100F

EC 51 18 41

最低价

float

41010 - 41013

9A 99 41 41

收盘价

float

41014 - 41017

80 06 B2 47

成交量

float

41018 - 4101B

40 1C BC 4C

成交金额

float

4101C - 4101D

00 00

上涨家数

word

4101E - 4101F

00 00

下跌家数

word

 

注意:

1)、起止地址、数据内容为十六进制,数据类型为 Delphi 下之定义。

2)、从18h开始至40017h64byte为一条股票数据分配记录,含义如上表18h - 57h所示;

3)、从41000h开始每8KB为一股票数据存储块,每个股票数据存储块共存储256条日线记录,每一条记录的长度为32 byte(含义如上表;上涨家数及下跌家数只对指数有效);

4)、从41000h开始的8KB1024 * 8 = 8192)为第0号数据存储块,以后类推;

5)、系统对每个股票日线数据存储以存储块为单位进行分配。

记录块号计算方法:

char[0] = 0x00              第一个记录块起始地址为:41000h + 0x0000 * 0x2000 = 41000h

char[1] = 0x03BA  第二个记录块起始地址为:41000h + 0x03BA * 0x2000 = 0x00077F78

6)、具体应用实例分析家数据管理程序。

7) 、日期字段的意义为:实际日期 = StrToDate(^1970-01-01^)+(日期字段 div 86400);即“日期字段”除以8640060s * 60m * 24h = 86400s)所得数为实际日期距19700101的天数。

 

示例代码

示例:显示日线数据文件信息

说明:显示大智慧日线数据文件中头部信息、块索引信息、数据记录信息。

unit uDataBuffer;

 

interface

 

uses

    SysUtils,Classes;

 

type

    TCustomStringBuffer = class

    private

        FBuffer: PChar;

        FBufferSize: Integer;

        FContent: string;

        function GetContent: string;

        procedure SetBufferSize(Value: Integer);

        procedure SetContent(const Value: string);

    protected

        procedure DoBufferChange; virtual;

        procedure ClearBuffer; virtual;

    public

        constructor Create;

        //---

        function ReadFile(const AFileName: string): Boolean;

        function SaveFile(const AFileName: string; const Append: Boolean = false):

            Boolean;

        //---

        property Buffer: PChar read FBuffer;

        property BufferSize: Integer read FBufferSize write SetBufferSize;

        property Content: string read GetContent write SetContent;

    end;

    TRecordStream = class(TCustomStringBuffer)

    private

        FCount: Integer;

        FDataSize: Integer;

        function GetDatas(Index: Integer): Pointer;

        procedure SetCount(const Value: Integer);

    protected

        procedure ClearBuffer; override;

        procedure DoBufferChange; override;

        //---

        property Datas[Index: Integer]: Pointer read GetDatas;

        property DataSize: Integer write FDataSize;

    public

        property Count: Integer read FCount write SetCount;

    end;

 

function OpenToFile(const AFileName: string; const AMode: Integer; const AIsAppend: Boolean = false): integer;

function ReadFormFile(const AFileName: string): string;

function SaveToFile(const AFileName,AContent: string; const AIsAppend: Boolean

    = false): Boolean;

 

implementation

 

function OpenToFile(const AFileName: string; const AMode: Integer; const AIsAppend: Boolean = false): integer;

const

    CNT_OpenCount = 20;

    CNT_OpenOutTime = 30;

    //---

    function _OpenWrite: integer;

    var

        i,AFileHandle: integer;

        APath: string;

    begin

        if FileExists(AFileName) then

        begin

            for i := 0 to CNT_OpenCount do

            begin

                if AIsAppend then

                    AFileHandle := FileOpen(AFileName,fmOpenWrite or fmShareExclusive)

                else

                    AFileHandle := FileCreate(AFileName);

                if AFileHandle < 0 then

                    sleep(CNT_OpenOutTime)

                else

                    Break;

            end;

        end

        else

        begin

            APath := ExtractFilePath(AFileName);

            if not DirectoryExists(APath) then

                ForceDirectories(APath);

            //---

            AFileHandle := FileCreate(AFileName);

        end;

        //---

        Result := AFileHandle;

    end;

    //---

    function _OpenRead: integer;

    var

        i,AFileHandle: integer;

    begin

        Result := -1;

        //---

        if not FileExists(AFileName) then

            Exit;

        //---

        for i := 0 to CNT_OpenCount do

        begin

            AFileHandle := FileOpen(AFileName,fmOpenRead or fmShareDenyNone);

            if AFileHandle < 0 then

                sleep(CNT_OpenOutTime)

            else

                Break;

        end;

        //---

        Result := AFileHandle;

    end;

begin

    Result := -1;

    //---

    if Trim(AFileName) = '' then

        Exit;

    //---

    if AMode = fmOpenWrite then

        Result := _OpenWrite

    else

        Result := _OpenRead;

end;

 

function ReadFormFile(const AFileName: string): string;

var

    AFileHandle,ABufferSize: integer;

begin

    Result := '';

    //---

    AFileHandle := OpenToFile(AFileName,fmOpenRead);

    if AFileHandle < 0 then

        Exit;

    //---

    try

        ABufferSize := FileSeek(AFileHandle,0,soFromEnd);

        if ABufferSize = 0 then

            Exit;

        //---

        SetLength(Result,ABufferSize);

        //---

        FileSeek(AFileHandle,0,soFromBeginning);

        FileRead(AFileHandle,Pchar(Result)^,ABufferSize);

    finally

        FileClose(AFileHandle);

    end;

end;

 

function SaveToFile(const AFileName,AContent: string; const AIsAppend: Boolean

    = false): Boolean;

var

    AFileHandle: integer;

begin

    result := false;

    //---

    if Length(AContent) = 0 then

        Exit;

    //---

    try

        AFileHandle := OpenToFile(AFileName,fmOpenWrite,AIsAppend);

        if AFileHandle < 0 then

            Exit;

        //---

        try

            if AIsAppend then

                FileSeek(AFileHandle,0,soFromEnd)

            else

                FileSeek(AFileHandle,0,soFromBeginning);

            FileWrite(AFileHandle,Pchar(AContent)^,Length(AContent));

        finally

            FileClose(AFileHandle);

        end;

        //---

        Result := true;

    except

        on E: Exception do

        begin

            Result := false;

        end;

    end;

end;

 

procedure TCustomStringBuffer.ClearBuffer;

begin

    FBufferSize := 0;

end;

 

constructor TCustomStringBuffer.Create;

begin

    FBufferSize := 0;

end;

 

procedure TCustomStringBuffer.DoBufferChange;

begin

    FBuffer := PChar(FContent);

end;

 

function TCustomStringBuffer.GetContent: string;

begin

    if FBufferSize = 0 then

        Result := ''

    else

        Result := FContent;

end;

 

function TCustomStringBuffer.ReadFile(const AFileName: string): Boolean;

begin

    self.Content := ReadFormFile(AFileName);

    Result := self.BufferSize > 0;

end;

 

function TCustomStringBuffer.SaveFile(const AFileName: string; const Append:

    Boolean = false): Boolean;

begin

    result := SaveToFile(AFileName,self.Content,Append);

end;

 

procedure TCustomStringBuffer.SetBufferSize(Value: Integer);

begin

    FBufferSize := Value;

    if FBufferSize < 0 then

        FBufferSize := 0;

    //---

    if FBufferSize > 0 then

        SetLength(FContent,Value);

    //---

    DoBufferChange;

end;

 

procedure TCustomStringBuffer.SetContent(const Value: string);

begin

    FContent := Value;

    FBufferSize := Length(FContent);

    //---

    DoBufferChange;

end;

 

procedure TRecordStream.ClearBuffer;

begin

    inherited;

    //---

    FCount := 0;

end;

 

procedure TRecordStream.DoBufferChange;

    //---

    procedure _RefreshCount;

    begin

        FCount := FBufferSize div FDataSize;

        if FDataSize * FCount <> FBufferSize then

            self.ClearBuffer;

    end;

begin

    inherited;

    //---

    if FDataSize <= 0 then

        self.ClearBuffer

    else

        _RefreshCount;

end;

 

function TRecordStream.GetDatas(Index: Integer): Pointer;

begin

    Result := FBuffer + Index * FDataSize;

end;

 

procedure TRecordStream.SetCount(const Value: Integer);

begin

    FCount := Value;

    if FCount < 0 then

        FCount := 0;

    //---

    self.BufferSize := FDataSize * FCount;

end;

 

end.

 

unit uDayData;

 

interface

 

uses

    uDataBuffer;

 

const

    CNT_BlockSize = 1024 * 8;

 

type

    TFileHead_Day = packed record

        FileSign: Integer; //--文件标志

        FileInfo1: Integer;

        FileInfo2: Integer;

        StockCount: Integer; //--证券总数

        BlockTotalCount: Integer; //--总块数

        BlockUseCount: Integer; //--已用块数

    end;

    PTFileHead_Day = ^TFileHead_Day;

 

    TIndexRecord_Day = packed record

        StockCode: array[0..9] of char; //--证券代码

        RecordCount: Integer; //--日线记录数

        BlockIndexs: array[0..24] of word; //--记录块号

    end;

    PTIndexRecord_Day = ^TIndexRecord_Day;

 

    TDataRecord_Day = packed record

        rq: Integer; //--日期

        kp: single; //--开盘

        zg: single; //--最高

        zd: single; //--最低

        sp: single; //--收盘

        sl: single; //--成交数量

        je: single; //--成交金额

        zj: Word; //--上涨家数

        dj: Word; //--下跌家数

    end;

    PTDataRecord_Day = ^TDataRecord_Day;

 

    {日线数据}

    TStockDataStream_Day = class(TCustomStringBuffer)

    private

        FFileHead: TFileHead_Day;

        FIndexCount: Integer;

        FIndexSize: Integer;

        FIndexStartAddress: Pchar;

        FDataCount: Integer;

        FDataSize: Integer;

        FDataStartAddress: Pchar;

        function GetDatas(Index: Integer): PTDataRecord_Day;

        function GetHead: PTFileHead_Day;

        function GetIndexs(Index: Integer): PTIndexRecord_Day;

    protected

        procedure ClearBuffer; override;

        procedure DoBufferChange; override;

    public

        constructor Create;

        //---

        property Head: PTFileHead_Day read GetHead;

        property Datas[Index: Integer]: PTDataRecord_Day read GetDatas;

        property DataCount: Integer read FDataCount;

        property Indexs[Index: Integer]: PTIndexRecord_Day read GetIndexs;

        property IndexCount: Integer read FIndexCount;

    end;

 

implementation

 

constructor TStockDataStream_Day.Create;

begin

    inherited;

    //---

    FIndexSize := sizeof(TIndexRecord_Day);

    FDataSize := sizeof(TDataRecord_Day);

end;

 

procedure TStockDataStream_Day.ClearBuffer;

begin

    inherited;

    //---

    FIndexCount := 0;

    FDataCount := 0;

end;

 

procedure TStockDataStream_Day.DoBufferChange;

const

    CNT_IndexStartAddress = $00018;

    CNT_DataStartAddress = $41000;

    //---

    function _ReadFileHead: Boolean;

    begin

        Result := self.BufferSize > CNT_IndexStartAddress;

        if Result then

            Move(self.Buffer^,FFileHead,SizeOf(FFileHead));

    end;

    //---

    function _ReadIndex: Boolean;

    begin

        FIndexStartAddress := self.Buffer + CNT_IndexStartAddress;

        FIndexCount := FFileHead.StockCount;

        Result := self.BufferSize > CNT_IndexStartAddress + SizeOf(TIndexRecord_Day) * FIndexCount;

    end;

    //---

    function _ReadData: Boolean;

    begin

        FDataStartAddress := self.Buffer + CNT_DataStartAddress;

        FDataCount := (CNT_BlockSize * FFileHead.BlockUseCount) div SizeOf(TDataRecord_Day);

        Result := self.BufferSize >= CNT_DataStartAddress + SizeOf(TDataRecord_Day) * FDataCount;

    end;

begin

    inherited;

    //---

    if FDataSize <= 0 then

        self.ClearBuffer

    else

    begin

        if not (_ReadFileHead and _ReadIndex and _ReadData) then

            self.ClearBuffer;

    end;

end;

 

function TStockDataStream_Day.GetDatas(Index: Integer): PTDataRecord_Day;

begin

    Result := Pointer(FDataStartAddress + FDataSize * Index);

end;

 

function TStockDataStream_Day.GetHead: PTFileHead_Day;

begin

  Result := @FFileHead;

end;

 

function TStockDataStream_Day.GetIndexs(Index: Integer): PTIndexRecord_Day;

begin

    Result := Pointer(FIndexStartAddress + FIndexSize * Index);

end;

 

end.

 

unit Unit1;

 

interface

 

uses

    Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,

    Dialogs,StdCtrls,ExtCtrls;

 

type

    TForm1 = class(TForm)

        Button1: TButton;

        ListBox1: TListBox;

        GroupBox1: TGroupBox;

        OpenDialog1: TOpenDialog;

        RadioGroup1: TRadioGroup;

        Panel1: TPanel;

        procedure FormCreate(Sender: TObject);

        procedure Button1Click(Sender: TObject);

    private

        procedure ShowHqData(const AFile: string; const AListBox: TListBox);

    public

        procedure ShowData(const AFile: string; const AListBox: TListBox);

    end;

 

var

    Form1: TForm1;

 

implementation

 

uses uDayData;

 

{$R *.dfm}

 

procedure TForm1.FormCreate(Sender: TObject);

begin

    SendMessage(ListBox1.Handle,LB_SetHorizontalExtent,2000,longint(0));

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

    with self.OpenDialog1 do

    begin

        if Execute then

            ShowData(FileName,ListBox1);

    end;

end;

 

procedure TForm1.ShowData(const AFile: string; const AListBox: TListBox);

begin

    case RadioGroup1.ItemIndex of

        0: ShowHqData(AFile,AListBox);

    end;

end;

 

procedure TForm1.ShowHqData(const AFile: string; const AListBox: TListBox);

var

    AStream: TStockDataStream_Day;

    //---

    procedure _ShowHead;

    begin

        with AStream.Head^ do

            AListBox.Items.Add(Format('文件标志:%d 股票数量:%d 总块数:%d 已用块数:%d', [FileSign,StockCount,BlockTotalCount,BlockUseCount]));

    end;

    //---

    procedure _ShowIndex;

    var

        i,j: Integer;

        AText: string;

    begin

        with AListBox.Items,AStream do

        begin

            Add('--------索引---------');

            //---

            for i := 0 to IndexCount - 1 do

            begin

                with Indexs[i]^ do

                begin

                    AText := '';

                    for j := Low(BlockIndexs) to High(BlockIndexs) do

                    begin

                        if BlockIndexs[j] <> $FFFF then

                            AText := Format('%s  %.2d', [AText,BlockIndexs[j]]);

                    end;

                    //---

                    Add(Format('%.3d  证券代码:%s  记录数量:%d  记录块号:%s', [i,StockCode,RecordCount,AText]));

                end;

            end;

        end;

    end;

    //---

    procedure _ShowData;

    var

        i,ABlockID,ACurBlockID: Integer;

        AStartDate: TDate;

        ACurDate: string;

    begin

        AStartDate := StrToDate('1970-01-01');

        //---

        with AListBox.Items,AStream do

        begin

            ABlockID := 0;

            Add(Format('--------%d---------', [ABlockID]));

            //---

            for i := 0 to DataCount - 1 do

            begin

                with Datas[i]^ do

                begin

                    ACurBlockID := i * SizeOf(TDataRecord_Day) div CNT_BlockSize;

                    if ABlockID <> ACurBlockID then

                    begin

                        ABlockID := ACurBlockID;

                        Add(Format('--------%d---------', [ABlockID]));

                    end;

                    //---

                    if rq > 0 then

                        ACurDate := DateToStr(AStartDate + rq div 86400)

                    else

                        ACurDate := '0';

                    Add(Format('%.3d  %s  %.2f  %.2f  %.2f  %.2f  %.2f  %.2f  %d  %d', [i,ACurDate,

                        kp,zg,zd,sp,sl,je,zj,dj]));

                end;

            end;

            //---

            Add('*****************');

            Add(Format('--------已用块%d---------', [ABlockID]));

        end;

    end;

begin

    AStream := TStockDataStream_Day.Create;

    try

        with AListBox.Items do

        begin

            BeginUpdate;

            Clear;

            with AStream do

            begin

                if ReadFile(AFile) then

                begin

                    _ShowHead;

                    _ShowIndex;

                    _ShowData;

                end;

            end;

            EndUpdate;

        end;

    finally

        AStream.Free;

    end;

end;

 

end.

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值