NumPy学习笔记 二
《NumPy学习笔记》系列将记录学习NumPy过程中的动手笔记,前期的参考书是《Python数据分析基础教程 NumPy学习指南》第二版、《数学分析》第四版(华东师范大学数学系)、《概率论与数理统计》(陈希孺,中科大出版)、《概率论与数理统计》第二版(茆诗松、程依明等编)、《组合最优化:理论与方法》(现代数学译丛23)。笔记二主要记录数据获取,沪深证券市场的A股股票数据。
获取的股票数据周期包括5分钟、15分钟、30分钟、60分钟、日、周、月、45日、季度、年;股票数据内容包括日期时间、开盘价、最高价、最低价、收盘价、成交量、成交金额。
获取数据的途径有很多种,上交所、深交所、各大财经网站上均有数据,利用爬虫技术基本均可信手拈来;还有一些公开的财经API可以利用;再者就是编写证券行情软件的插件来获取。本随笔就主要讲述用C++语言开发选股插件来转储数据,证券行情软件采用通达信软件,该种方式稳定可靠、数据精确。
通达信的官方网站提供了免费行情软件的下载(http://www.tdx.com.cn/page_83.html)
下载最新免费版金融终端V7.37,安装后下载自1990年1月1日至今的所有数据(沪深日线、沪深分钟线):
(通达信最新的免费版在windows 10操作系统上显示日期有bug)
然后在帮助中心--用户红宝书(http://help.tdx.com.cn/book.asp)下载最新的通达信插件选股编程规范。
压缩包内包含示例程序MyPlugin及插件选股编程规范文档。
MyPlugin是用古老的VC6编写的,可以用vs2010或以上版本打开,修改一个历史编译缺陷(VC6编译器是可以编过的):
WORD AfxRightData(float*pData,WORD nMaxData) //获取有效数据位置
{
for(WORD nIndex=0;nIndex<nMaxData&&!memcmp(&pData[nIndex],g_nAvoidMask,4);nIndex++);
return(nIndex);
}
该插件工程比较简单,通过示例代码及文档可以快速了解如何编写通达信插件,在此不赘述。
主要讲下转载数据的思路:
- 首先创建转储数据的文件夹
struct DataPeriodDesc { int iPeriod; //数据周期 const char* desc; //周期描述 const char* Suffix; //文件后缀 }; static DataPeriodDesc periodDescArray[] = { {PER_MIN5,"5分钟" ,"\5min"}, {PER_MIN15,"15分钟" ,"\15min"}, {PER_MIN30,"30分钟" ,"\30min"}, {PER_HOUR,"小时" ,"\h"}, {PER_DAY,"日" ,"\d"}, {PER_WEEK,"周" ,"\w"}, {PER_MONTH,"月" ,"\m"}, {PER_DAYN,"45日" ,"\45d"}, {PER_SEASON,"季" ,"\s"}, {PER_YEAR,"年" ,"\y"}, }; if(bFirstTime) { bFirstTime = FALSE; BOOL bCallReturn = FALSE; //构建新的目录结构 bCallReturn = CreateDirectoryA(pSavePath,NULL); for (int i=0;i<ARRAYSIZE(periodDescArray);i++) { CHAR subFolderName [MAX_PATH] = {0}; StringCchCopyA(subFolderName,MAX_PATH,pSavePath); StringCchCatA(subFolderName,MAX_PATH,periodDescArray[i].Suffix); bCallReturn = CreateDirectoryA(subFolderName,NULL); } //转储大盘数据 nRet = InputInfoThenCalc1("999999", 1, Value, DataType, nDataNum, nTQ, unused); }
屏蔽InputInfoThenCalc2,转储的范围是本地全部数据。
BOOL InputInfoThenCalc2(char * Code,short nSetCode,int Value[4],short DataType,NTime time1,NTime time2,BYTE nTQ,unsigned long unused) //选取区段 { BOOL nRet = FALSE; nRet = InputInfoThenCalc1(Code,nSetCode,Value,DataType,0,nTQ,unused); return nRet; }
设置两个二值输入参数,控制插件转储数据的级别。分钟级转储日线级别以下的数据;日级转储日线及以上的数据。
InputInfoThenCalc1函数种根据选定的级别,遍历本地数据,将数据存储到文件。
LPHISDAT pHisDat = NULL; CHAR buf[4096] = {0}; for (int index_p=0;index_p<ARRAYSIZE(periodDescArray);index_p++) { long lnum = g_pFuncCallBack(Code,nSetCode,periodDescArray[index_p].iPeriod,NULL,-1,tmpTime,tmpTime,nTQ,0); if (lnum <0) { goto Exit; } if (periodDescArray[index_p].iPeriod>= PER_DAY && Value[1] == 0) { continue; } else if (periodDescArray[index_p].iPeriod< PER_DAY && Value[0] == 0) { continue; } //读取数据 SafeDeletes(pHisDat); pHisDat = new HISDAT[lnum]; long readnum = g_pFuncCallBack(Code,nSetCode,periodDescArray[index_p].iPeriod,pHisDat,lnum,tmpTime,tmpTime,nTQ,0); //保存到文件夹中 CHAR subFolderName [MAX_PATH] = {0}; StringCchCopyA(subFolderName,MAX_PATH,pSavePath); StringCchCatA(subFolderName,MAX_PATH,periodDescArray[index_p].Suffix); StringCchCatA(subFolderName,MAX_PATH,"\"); StringCchCatA(subFolderName,MAX_PATH,Code); if (nTQ==1) //精确复权 { StringCchCatA(subFolderName,MAX_PATH,"_fq"); } else if (nTQ == 0) { StringCchCatA(subFolderName,MAX_PATH,"_bfq"); } StringCchCatA(subFolderName,MAX_PATH,".csv"); HANDLE hFile = CreateFileA(subFolderName, // name of the write GENERIC_WRITE|GENERIC_READ, // open for writing 0, // do not share NULL, // default security CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template if (hFile != INVALID_HANDLE_VALUE) { NTime timeLastDay = {0}; for(int index=0;index<readnum;index++) { if(periodDescArray[index_p].iPeriod>=PER_DAY) { //if (pHisDat[index].Time>timeLastDay) { StringCchPrintfA(buf,ARRAYSIZE(buf),"%4d%02d%02d,%f,%f,%f,%f,%f,%f ", pHisDat[index].Time.year, pHisDat[index].Time.month, pHisDat[index].Time.day, pHisDat[index].Open, pHisDat[index].High, pHisDat[index].Low, pHisDat[index].Close, pHisDat[index].fVolume, pHisDat[index].Amount ); } /* else { continue; }*/ } else if(periodDescArray[index_p].iPeriod < PER_DAY) { StringCchPrintfA(buf,ARRAYSIZE(buf),"%4d%02d%02d %02d%02d,%f,%f,%f,%f,%f,%f ", pHisDat[index].Time.year,pHisDat[index].Time.month,pHisDat[index].Time.day,pHisDat[index].Time.hour,pHisDat[index].Time.minute, pHisDat[index].Open, pHisDat[index].High, pHisDat[index].Low, pHisDat[index].Close, pHisDat[index].fVolume, pHisDat[index].Amount ); } size_t len = 0; StringCbLengthA(buf,ARRAYSIZE(buf),&len); WriteFile(hFile,buf,len,NULL,NULL); } } SafeCloseHandle(hFile); SafeDeletes(pHisDat); } Exit: SafeDeletes(pHisDat); return nRet;
成功转载数据后,利用numpy读取指数最低价及收盘价:
l,c=np.loadtxt(‘999999_fq.csv’,delimiter=’,’,usecols=(3,4),unpack=True)