C++读入通达信日线及1分钟数据

C++读入通达信日线及1分钟数据

通达信日线、1分钟数据调用后,便于使用数据进行回测。

struct dayData //通达信日线数据结构,32个字节
{
    int date;//4字节
    int open;//4字节
    int high;//4字节
    int low;//4字节
    int close;//4字节
    float amount;//4字节
    int vol;//4字节
    int x;//4字节,备用数据
};

void 读入日线数据(CString &sj)//参数sj把数据传回调用程序
{
    //二进制文件读入
    FILE* fp;
    int nLen;
    dayData* data = new dayData[50000];//在堆中开数组,大小不受限制,理论上可以无限大

    char filename[30] = "sh600968.day";//读入日线文件名称

    if ((fp = fopen(filename, "rb+")) == NULL)//打开文件进行二进制读入
    {
        printf("文件打开失败!Fail to open file!");
        exit(0);
    }
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp) / 32;//获取文件大小
    fseek(fp, 0, SEEK_SET);//重新回到文件起始位置

    nLen = fread(data, size, 32, fp);//使用fread读入数据

    for (int i = 0; i < 10; i++)//根据需要,把数据连成一个字符串,此处测试10个数据用于调试
    {    //把数据连接成一个字符串,进行数据传递
        CString str = L"";//把数据转换为CString类型
        str.Format(L"%d", data[i].date);
        sj.Append(str + L"|");
        str.Format(L"%.2f", double(data[i].open)/100);
        sj.Append(str + L"|");
        str.Format(L"%.2f", double(data[i].high) / 100);
        sj.Append(str + L"|");
        str.Format(L"%.2f", double(data[i].low) / 100);
        sj.Append(str + L"|");
        str.Format(L"%.2f", double(data[i].close) / 100);
        sj.Append(str + L"|");
        str.Format(L"%.0f", data[i].amount);
        sj.Append(str + L"|");
        str.Format(L"%d", data[i].vol/100);
        sj.Append(str + L";");
    }
    //        TracePrint(L"%s", sj);//自定义的输出函数,观察结果
    fclose(fp);
    delete[] data;//释放所开的内存空间
    data = nullptr;//指向空指针
}

struct lc1Data //通达信1分钟数据结构,32个字节
{
    short date;//2字节
    short time;//2字节
    float open;//4字节
    float high;//4字节
    float low;//4字节
    float close;//4字节
    float amount;//4字节
    int vol;//4字节
    int x;//4字节
};

void 读入1分钟数据(CString &sj)//参数sj把数据传回调用程序
{
    //二进制文件读入
    FILE* fp;
    int nLen;
    lc1Data* data = new lc1Data[50000];//在堆中开数组,大小不受限制,理论上可以无限大
 //   char filename[30] = "sh600968.day";//读入日线文件名称
    char filename[30] = "sz000001.lc1";//读入1分钟线的文件名称
    lc1Data sj1[100];
    if ((fp = fopen(filename, "rb+")) == NULL)//打开文件进行二进制读入
    {
        printf("文件打开失败!Fail to open file!");
        exit(0);
    }
    fseek(fp, 0, SEEK_END);
    int size = ftell(fp) / 32;//获取文件大小
    fseek(fp, 0, SEEK_SET);//重新回到文件起始位置

    nLen = fread(data, size, 32, fp);//使用fread读入数据

    for (int i = 0; i < 10; i++)//根据需要,把数据连成一个字符串,此处测试10个数据用于调试
    {    //把数据连接成一个字符串,进行数据传递
        CString str=L"";//把数据转换为CString类型
        str.Format(L"%d", data[i].date);
        sj.Append(str+L"|");
        str.Format(L"%d", data[i].time);
        sj.Append(str + L"|");
        str.Format(L"%.2f", data[i].open);
        sj.Append(str + L"|");
        str.Format(L"%.2f", data[i].high);
        sj.Append(str + L"|");
        str.Format(L"%.2f", data[i].low);
        sj.Append(str + L"|");
        str.Format(L"%.2f", data[i].close);
        sj.Append(str + L"|");
        str.Format(L"%.2f", data[i].amount);
        sj.Append(str + L"|");
        str.Format(L"%d", data[i].vol);
        sj.Append(str + L";");
    }
//        TracePrint(L"%s", sj);//自定义的输出函数,观察结果

    fclose(fp);
    delete[] data;//释放所开的内存空间
    data = nullptr;//指向空指针
}
void C超短回测Dlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    CString dataM1=L"";
    CStringArray data0;
    读入1分钟数据(dataM1);
    TracePrint(L"%s", dataM1);//自定义的输出函数,观察结果
    Split(dataM1, L";", data0);//利用自定义函数拆分字符串为成为字符串数组
}


void C超短回测Dlg::OnBnClickedButton2()
{
    // TODO: 在此添加控件通知处理程序代码
    CString dataDay=L"";
    CStringArray data0;
    读入日线数据(dataDay);
    TracePrint(L"%s", dataDay);//自定义的输出函数,观察结果
    Split(dataDay, L";", data0);//利用自定义函数拆分字符串为成为字符串数组
}

        又研究了一下,有一个更好的解决方案,实现回传数据,输入指定的股票代码与日期,立即得到相应日期的数据;

void 读入1分钟数据(CString gpdm,CString sellDate, CString &sj)//参数sj把数据传回调用程序

{

lc1Data* data = new lc1Data[50000];//在堆中开数组,大小不受限制,理论上可以无限大

CString str;

CFile file;

CString FilePath = L"";

CString filename = L"";

int rq = (_ttoi(sellDate.Left(4)) - 2036) * 2048 + _ttoi(sellDate.Right(4));//字符串日期转换后的数字

CString fn = L"";

if (gpdm.Left(1) == "6") filename.Append(数据下载路径 + "\\sh\\minline\\sh" + gpdm + ".lc1");

if (gpdm.Left(1) == "3" || gpdm.Left(1) == "0") filename.Append(数据下载路径 + "\\sz\\minline\\sz" + gpdm + ".lc1");

BOOL isOpenOK = file.Open(FilePath + filename, CFile::modeRead);

CString strState;

if (FALSE == isOpenOK)

{

strState.Format(L"文件:【" + FilePath + filename + L"】打开失败!");

MessageBox(NULL,strState,0,0);

return;

}

int size = (DWORD)file.GetLength(); //确定文件大小

int nRet = file.Read(data, size);//读入数据

file.Close();//数据读入结束后,关闭文件

int iPos = -1;

for (int i = 0; i < size; i++)  //找到指定日期的位置

if (data[i].date == rq)

{

iPos = i;

break;

}

for (int i = iPos - 241; i < iPos + 240; i++)//根据需要,把数据连成一个字符串,此处测试10个数据用于调试

{

//指定日期当天与前一交易日,数据连接成一个字符串,进行数据传递

CString str = L"";//把数据转换为CString类型

str.Format(L"%.f", floor(double(data[i].date) / 2048) + 2036);

sj.Append(str);

str.Format(L"%.f", (double(data[i].date) - floor(double(data[i].date) / 2048) * 2048));

sj.Append(str + L"|");

str.Format(L"%02.0f", floor(double(data[i].time) / 60));

sj.Append(str);

str.Format(L"%02d", int(double(data[i].time - floor(double(data[i].time) / 60) * 60)));

sj.Append(str + L"|");

str.Format(L"%.2f", data[i].open);

sj.Append(str + L"|");

str.Format(L"%.2f", data[i].high);

sj.Append(str + L"|");

str.Format(L"%.2f", data[i].low);

sj.Append(str + L"|");

str.Format(L"%.2f", data[i].close);

sj.Append(str + L"|");

str.Format(L"%.2f", data[i].amount);

sj.Append(str + L"|");

str.Format(L"%d", data[i].vol);

sj.Append(str + L";");

}

// TracePrint(L"%s", sj);//自定义的输出函数,观察结果

delete[] data;//释放所开的内存空间

data = nullptr;//指向空指针

}

void C超短回测Dlg::OnBnClickedButton1()

{

// TODO: 在此添加控件通知处理程序代码

// CString gpdm = L"600873";

CString gpdm = L"000001";

CString sellDate = L"20221018";

CString dataM1=L"";

CStringArray data0;

读入1分钟数据(gpdm,sellDate,dataM1);

TracePrint(L"%s", dataM1);//自定义的输出函数,观察结果

Split(dataM1, L";", data0);//利用自定义函数拆分字符串为成为字符串数组

}

你可能感兴趣的:(c++,c语言,程序人生,1024程序员节)