通达信V6.1概念板块分类文件格式分析

通达信V6概念板块分类文件格式分析

文件位置

/jcb_zxjt/T0002/hq_cache/ block.dat

 

数据格式

1)、文件头部信息

数据含义

数据类型

备注

文件信息

Char[64]

 

板块索引信息起始位置

Integer

 

板块记录信息起始位置

Integer

 

未知

Integer * 3

 

 

2)、板块索引信息,开始于0x0054h

数据含义

数据类型

备注

索引名称

Char[64]

 

未知

Integer * 9

 

注意:

1)、每个板块索引信息占的长度为100个字节。

 

3)、板块记录信息,开始于0x0180h

数据含义

数据类型

备注

板块数量

word

起始位置为0x180h

 

板块记录结构

数据含义

数据类型

备注

板块名称

Char [9]

 

证券数量

word

 

板块级别

word

 

证券代码

Char [7] * 400

 

注意:

1)、第一个版块的起始位置为0x182h

2)、每个板块占的长度为2813个字节。

3)、每个板块最多包括400只股票。(2813 -9 - 2 - 2) / 7 =  400

 

 

示例代码

示例:显示板块数据文件信息
单元:uDataBuffer

备注:uDataBuffer单元代码在“大智慧Level2日线数据文件格式分析”文档中。

 

单元:uBlockData

unit uBlockData;

 

interface

 

uses

    uDataBuffer;

 

type

    TFileHead_Block = packed record

        FileInfo: array[0..63] of char; //--文件信息

        BlockIndexStart: Integer; //--板块索引信息起始位置

        BlockDataStart: Integer; //--板块记录信息起始位置

        Unknown: array[0..2] of Integer; //--未知

    end;

    PFileHead_Block = ^TFileHead_Block;

 

    TIndexRecord_Block = packed record

        IndexName: array[0..63] of char; //--索引名称

        Unknown: array[0..8] of Integer; //--未知

    end;

    PIndexRecord_Block = ^TIndexRecord_Block;

 

    TStockCode = array[0..6] of char;

 

    TDataRecord_Block = packed record

        BlockName: array[0..8] of char; //--板块名称

        StockCount: word; //--证券数量

        BlockLevel: word; //--板块级别

        StockCodes: array[0..399] of TStockCode; //--证券代码

    end;

    PDataRecord_Block = ^TDataRecord_Block;

 

    TStockDataStream_Block = class(TCustomStringBuffer)

    private

        FFileHead: TFileHead_Block;

        FIndexCount: Integer;

        FIndexSize: Integer;

        FDataCount: word;

        FDataSize: Integer;

        function GetDatas(Index: Integer): PDataRecord_Block;

        function GetHead: PFileHead_Block;

        function GetIndexs(Index: Integer): PIndexRecord_Block;

    protected

        procedure ClearBuffer; override;

        procedure DoBufferChange; override;

    public

        constructor Create;

        //---

        property Head: PFileHead_Block read GetHead;

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

        property DataCount: word read FDataCount;

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

        property IndexCount: Integer read FIndexCount;

    end;

 

implementation

 

constructor TStockDataStream_Block.Create;

begin

    inherited;

    //---

    FIndexSize := sizeof(TIndexRecord_Block);

    FDataSize := sizeof(TDataRecord_Block);

end;

 

procedure TStockDataStream_Block.ClearBuffer;

begin

    inherited;

    //---

    FIndexCount := 0;

    FDataCount := 0;

end;

 

procedure TStockDataStream_Block.DoBufferChange;

    //---

    function _ReadFileHead: Boolean;

    begin

        Result := self.BufferSize >= SizeOf(FFileHead);

        if Result then

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

    end;

    //---

    function _ReadIndex: Boolean;

    var

        ABlockIndexLen: integer;

    begin

        Result := self.BufferSize >= FFileHead.BlockDataStart;

        if Result then

        begin

            ABlockIndexLen := (FFileHead.BlockDataStart - FFileHead.BlockIndexStart);

            FIndexCount := ABlockIndexLen div FIndexSize;

            //---

            Result := ABlockIndexLen = FIndexSize * FIndexCount;

        end;

    end;

    //---

    function _ReadData: Boolean;

        //---

        function _GetDataCount: Boolean;

        var

            p: Pchar;

        begin

            Result := self.BufferSize >= FFileHead.BlockDataStart + SizeOf(FDataCount);

            if Result then

            begin

                p := self.Buffer;

                inc(p,FFileHead.BlockDataStart);

                Move(p^,FDataCount,SizeOf(FDataCount));

                //---

                Result := FDataCount > 0;

            end;

        end;

        //---

        function _CheckDataLen: Boolean;

        begin

            Result := self.BufferSize = FFileHead.BlockDataStart + SizeOf(FDataCount) + FDataSize * FDataCount;

        end;

    begin

        Result := _GetDataCount and _CheckDataLen;

    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_Block.GetDatas(Index: Integer): PDataRecord_Block;

begin

    Result := Pointer(self.Buffer + FFileHead.BlockDataStart + SizeOf(FDataCount) + FDataSize * Index);

end;

 

function TStockDataStream_Block.GetHead: PFileHead_Block;

begin

    Result := @FFileHead;

end;

 

function TStockDataStream_Block.GetIndexs(Index: Integer): PIndexRecord_Block;

begin

    Result := Pointer(self.Buffer + FFileHead.BlockIndexStart + FIndexSize * Index);

end;

 

end.

 

 

单元:Unit1

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 ShowData_Block(const AFile: string; const AListBox: TListBox);

    public

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

    end;

 

var

    Form1: TForm1;

 

implementation

 

uses uDayData,uCacheDayData,uZstData,uBlockData;

 

{$R *.dfm}

 

procedure TForm1.FormCreate(Sender: TObject);

begin

    with RadioGroup1.Items do

    begin

        clear;

        Add('概念板块数据');

    end;

    RadioGroup1.ItemIndex := 0;

    //---

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

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

    with self.OpenDialog1 do

    begin

        if Execute then

            self.ShowData(FileName,ListBox1);

    end;

end;

 

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

begin

    case RadioGroup1.ItemIndex of

        0: ShowData_Block(AFile,AListBox);

    end;

end;

 

procedure TForm1.ShowData_Block(const AFile: string;

    const AListBox: TListBox);

var

    AStream: TStockDataStream_Block;

    //---

    procedure _ShowHead;

    var

        i: integer;

    begin

        with AListBox.Items,AStream.Head^ do

        begin

            Add(Format('文件信息:%s', [FileInfo]));

            Add(Format('板块索引起始位置:%d', [BlockIndexStart]));

            Add(Format('板块记录起始位置:%d', [BlockDataStart]));

            //---

            for i := low(Unknown) to high(Unknown) do

                Add(Format('未知:%d', [Unknown[i]]));

        end;

    end;

    //---

    procedure _ShowIndex;

    var

        j,AIndex: Integer;

    begin

        with AListBox.Items,AStream do

        begin

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

            //---

            for AIndex := 0 to IndexCount - 1 do

            begin

                with Indexs[AIndex]^ do

                begin

                    Add(Format('索引名称:%s', [IndexName]));

                    //---

                    for j := low(Unknown) to high(Unknown) do

                        Add(Format('未知:%d', [Unknown[j]]));

                end;

            end;

        end;

    end;

    //---

    procedure _ShowData;

    var

        ABlockIndex,AStockIndex: Integer;

    begin

        with AListBox.Items,AStream do

        begin

            Add('--------板块---------');

            //---

            Add(Format('板块数量:%d', [DataCount]));

            if DataCount > 0 then

                Add(Format('板块数据大小:%d', [sizeof(Datas[ABlockIndex]^) * DataCount]));

            Add(' ');

            //---

            for ABlockIndex := 0 to DataCount - 1 do

            begin

                with Datas[ABlockIndex]^ do

                begin

                    Add(Format('板块%d 板块名称:%s 证券数量:%d 板块级别:%d', [ABlockIndex + 1,BlockName,StockCount,BlockLevel]));

                    for AStockIndex := low(StockCodes) to high(StockCodes) do

                        Add(Format('%.3d 代码:%s', [AStockIndex + 1,StockCodes[AStockIndex]]));

                end;

            end;

        end;

    end;

begin

    AStream := TStockDataStream_Block.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
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值