摘要:
1.AfxGetDB() 建立CStDatabase全局变量
G:\stock\TskingVS2019\src\Client\StkLib\Src\AfxCore.cpp
CStDatabase & AfxGetDB()
{
if( g_pdb ) return *g_pdb;
static CStDatabase g_stdatabase;
return g_stdatabase;
}
2.调用IStStore::CreateStore( rootpath, nDBType );创建一个实例
G:\stock\TskingVS2019\src\Client\StkLib\Src\StStore.cpp
//从实现了IStStore接口的类中,选择一个创建实例
IStStore* IStStore::CreateStore(const char* rootpath, int nDBType)
{
IStStore* pRet = NULL;
switch (nDBType)
{
//----custom extend start by freeman 2019/06/08----
case dbtypeDzhProvider:
if (CDzhProvider::GetAccurateRoot(rootpath, accurateroot, 1024))
pRet = new CDzhProvider(accurateroot, TRUE);
break;
//---------end----
default:
return NULL;
}
return pRet;
}
//自己写的数据接口要用此函数注册 2019/06/08 by freeman
BOOL CStDatabase::AddAssistantRootPath( const char * rootpath, int nDBType )
{
IStStore * pStore = IStStore::CreateStore( rootpath, nDBType );
if( NULL == pStore )
return FALSE;
m_aptrAssistant.Add( pStore );
return TRUE;
}
初始化数据库时逐个创建实例
G:\stock\TskingVS2019\src\Client\StkLib\Src\AfxCore.cpp
BOOL AfxInitializeDB( LPSTR lpErr, UINT nMaxSize )
{
if( lpErr && nMaxSize > 0 )
memset( lpErr, 0, nMaxSize );
//功能:创建子目录。根据设定的主目录,检查存放数据的子目录是否存在,如果不存在子目录,则创建子目录
if( !CStDatabase::CreateSelfDB( AfxGetProfile().GetSelfDBPath() ) )
{
if( lpErr ) strncpy( lpErr, db_errcreateselfdb, min(nMaxSize-1,strlen(db_errcreateselfdb)) );
return FALSE;
}
//指定主用哪个自有数据库,这里指定的是selfdb。可选用selfdb,qianlong、shenglong中的哪个为主,取数时的时候,只有指定的IStStore::dbtypeSelfDB取不到数时,才会用循环从其他几个注册了的数据库接口来获取数据
//if( !AfxGetDB().SetRootPath( AfxGetProfile().GetSelfDBPath(), IStStore::dbtypeSelfDB ) ) //0ld
if (!AfxGetDB().SetRootPath(AfxGetProfile().GetSelfDBPath(), IStStore::dbtypeDzhProvider))//将主用类从IStStore::dbtypeSelfDB 改为自己写的IStStore::dbtypeDzhProvider
{
if( lpErr ) strncpy( lpErr, db_errrootpath, min(nMaxSize-1,strlen(db_errrootpath)) );
return FALSE;
}
//注册qianlong的实现,取数时的时候,只有指定的数据接口(如:IStStore::dbtypeSelfDB)取不到数时,才会用循环从其他几个注册了的数据库接口通过循环来获取数据
CSPString strQianlongPath = AfxGetProfile().GetQianlongPath();
if( strQianlongPath.GetLength() > 0
&& !AfxGetDB().AddAssistantRootPath( strQianlongPath, IStStore::dbtypeQianlong ) )
{
if( lpErr ) strncpy( lpErr, db_errqianlongpath, min(nMaxSize-1,strlen(db_errqianlongpath)) );
return FALSE;
}
return TRUE;
}
2.CStDatabase管理其它几个类,并调用其它几个类获取数据
2.stkui通过调取CStDatabase获取数据
|-selfdb.cpp
stkui->CStDatabase->|-qianlong.cpp
|-shenglong.cpp
|-
第一部分 读取本地磁盘中数据的类
G:\stock\TskingVS2019\src\Client\StkLib\Include\Database.h中定义了IStStore接口
class IStStore:读取K线数据的通用接口,各种类读取物理文件返回的数据都要转换为IStStore要求的格式。
以下为接口的三个实现
qianlong.cpp,
selfdb.cpp,
shenglong.cpp
都实现此接口中的函数(实现其中一部分函数,物理文件读写部分)
CStDatabase:注册所有的实现了IStStore接口类,然后从中设置一个作为主用类,在此类不能提供数的情况下,再循环调用其它类获取数据。此类和实际物理文件数据无关,只和IStStore有关。
AfxGetStockContainer().Load(&AfxGetDB():AfxGetDB()即CStDatabase类,从这里面装载数据到股票容器。
StockContainer的数据来自->CStDatabase->CStDatabase管理各种物理文件读取接口类 IStStore,向StockContainer统一数据格式->各种IStStore实现类,转换成IStStore统一格式。
1.本地物理文件数据读写接口IStStore
G:\stock\TskingVS2019\src\Client\StkLib\Include\Database.h中定义了IStStore接口
/***
读取K线数据的通用接口,各种格式的读取K线数据类必须从此类继承
*/
class IStStore
{
public:
enum DBTypes { // 数据格式类型,目前只支持typeSelfDB(自有格式)和typeQianlong(钱龙格式)
dbtypeUnknown = 0x01,
dbtypeSelfDB = 0x02,
dbtypeQianlong = 0x03,
dbtypeShenglong = 0x04,
};
static BOOL IsValidDataType( int nType );
static int GetSupportedDataType ( CDBType * pdbtype, int maxsize );
static IStStore * CreateStore( const char * rootpath, int nDBType = dbtypeUnknown ); // 给出根目录和类型,新建一个对象
virtual int IsOK( ) { return m_bIsOK; }
virtual const char * GetRootPath( ); // 得到当前对象的根目录
virtual int GetDBType( ) = 0; // 得到当前对象的数据类型
virtual const char * GetDBTypeName( ) = 0; // 得到当前对象的数据类型名称
virtual int GetMaxStockNumber( ) = 0; // 得到股票数量
virtual int LoadCodetable( CStockContainer & container ) = 0; // 读取所有股票的信息
virtual int StoreCodetable( CStockContainer & container ) = 0; // 保存代码表
virtual int LoadKDataCache( CStockContainer & container, PROGRESS_CALLBACK fnCallback, void *cookie, int nProgStart, int nProgEnd ) = 0; // 读取所有股票的最近日线数据缓冲
virtual int LoadBasetable( CStockContainer & container ) = 0; // 读取某一股票的财务资料表,包括每股收益,每股净资产等,见CBaseData
virtual int StoreBasetable( CStockContainer & container ) = 0; // 保存某一股票的财务资料表
virtual int LoadBaseText( CStock *pstock ) = 0; // 读取某一股票的基本资料文本
virtual int LoadKData( CStock *pstock, int nKType ) = 0; // 读取某一股票的某个周期的K线数据
virtual int LoadDRData( CStock *pstock ) = 0; // 读取某一股票的除权除息资料
virtual int StoreDRData( CStock *pstock ) = 0; // 保存某一股票的除权除息资料
virtual int LoadReport( CStock *pstock ) = 0; // 读取某一股票的行情刷新数据
virtual int LoadMinute( CStock *pstock ) = 0; // 读取某一股票的行情分时数据
virtual int LoadOutline( CStock *pstock ) = 0; // 读取某一股票的行情额外数据
virtual int StoreReport( REPORT * pReport, int nCount, BOOL bBigTrade ) = 0; // 保存行情刷新数据
virtual int StoreMinute( MINUTE * pMinute, int nCount ) = 0; // 保存行情分时数据
virtual int StoreOutline( OUTLINE * pOutline, int nCount ) = 0; // 保存行情分时数据
virtual int InstallCodetbl( const char * filename, const char *orgname ) = 0; // 安装下载的代码表
virtual int InstallCodetblBlock( const char * filename, const char *orgname ) = 0; // 安装下载的板块表
virtual int InstallCodetblFxjBlock( const char * filename, const char *orgname ) = 0; // 安装下载的分析家板块表
virtual int InstallKData( CKData & kdata, BOOL bOverwrite = FALSE ) = 0; // 安装K线数据
virtual int InstallKDataTy( const char * stkfile, int nKType, PROGRESS_CALLBACK fnCallback, void *cookie ) = 0; // 安装下载的K线通用格式数据包
virtual int InstallKDataFxj( const char * dadfile, int nKType, PROGRESS_CALLBACK fnCallback, void *cookie ) = 0; // 安装下载的K线分析家格式通用数据包
virtual int InstallDRData( CDRData & drdata ) = 0; // 安装除权除息数据
virtual int InstallDRDataClk( const char * filename, const char *orgname ) = 0; // 安装下载的除权除息数据,一只股票一个文件
virtual int InstallDRDataFxj( const char * fxjfilename ) = 0; // 安装分析家除权除息数据
virtual int InstallBasetable( const char * filename, const char *orgname ) = 0; // 安装财务数据
virtual int InstallBasetableTdx( const char * filename ) = 0; // 安装通达信财务数据
virtual int InstallBasetableFxj( const char * filename ) = 0; // 安装分析家财务数据
virtual int InstallBaseText( const char * filename, const char *orgname ) = 0; // 安装下载的基本资料数据,一只股票一个文件
virtual int InstallBaseText( const char * buffer, int nLen, const char *orgname ) = 0; // 安装基本资料数据
virtual int InstallNewsText( const char * filename, const char *orgname ) = 0; // 安装新闻数据文件
virtual int InstallNewsText( const char * buffer, int nLen, const char *orgname ) = 0; // 安装新闻数据
virtual BOOL GetFileName( CSPString &sFileName, int nDataType,
CStockInfo * pInfo = NULL, int nKType = CKData::ktypeDay ) = 0; // 得到某种数据的文件名称
protected:
BOOL m_bIsOK;
char m_szRootPath[1024];
};
接口实现
1.\Src\StStore.cpp实现了接口函数中的一部分
///////////////////////////////////////////////////////////////////////////////////////////
// class IStStore
BOOL IStStore::IsValidDataType( int nType )
{
return ( dbtypeSelfDB == nType || dbtypeQianlong == nType
|| dbtypeShenglong == nType );
}
2.
下面的实现读取物理文件部分
1.class CQianlong : public IStStore
2.class CSelfDB : public CQianlong 因为CQianlong已经实现了IStStore接口,如果有自己的数据文件,就用自己的数据文件;如果没有自己的数据文件,就使用乾隆的数据文件
第二部分 技术指标的计算类
工程StkLib介绍
这个工程是实现股票数据结构、技术指标计算的动态连接库,代码与平台无关。
其中比较重要的几个文件如下:
Database.h 读取数据文件接口定义
QianLong.h 钱龙格式数据文件接口定义
SelfDB.h 自有格式数据文件接口定义,除了除权数据和行情数据外,
其他与钱龙一样
Stock.h 股票数据结构定义
Technique.h 技术指标类定义
Container.h 股票信息数据CStockInfo的数组类
Express.h 股票列表视图的列变量定义,以及自定义列的表达式计算
Strategy.h 策略定义
Profile.h 记录软件的用户配置并保存
BaseData.cpp 基本资料数据结构类实现
Database.cpp 数据文件读写实现
DRData.cpp 除权数据结构数组类实现
KData.cpp K线数据结构数组类实现
Report.cpp 行情数据结构数组类实现
Minute.cpp 行情分时数据结构数组类实现
Outline.cpp 行情额外数据结构数组类实现
QianLong.cpp 钱龙数据文件读写实现
SelfDB.cpp 自有格式数据文件读写实现
Stock.cpp 股票数据结构实现
StStore.cpp 数据文件读写实现
TechCL.cpp 自有技术指标
TechEnergy.cpp 能量类技术指标
TechKLine.cpp K线叠加类技术指标
Technique.cpp 技术指标基类
TechSwing.cpp 摆动类技术指标
TechTrend.cpp 趋势类技术指标
TechOther.cpp 其它类技术指标
Container.cpp 股票信息数据CStockInfo的数组类实现
Express.cpp 股票列表视图的列变量定义,以及自定义列的表达式计算实现
Strategy.cpp 策略定义实现
Profile.cpp 记录软件的用户配置并保存
有关详细的说明,参看源文件中的注释。
工程StkLib的几个全局静态变量:
g_stockcontainer:AfxGetStockContainer()可以得到该变量的引用,该
变量记录所有股票的行情信息和基本信息,CStockInfo的数组。
g_domaincontainer:AfxGetDomainContainer()可以得到该变量的引用,
该变量记录所有板块的信息。
g_groupcontainer:AfxGetGroupContainer()可以得到该变量的引用,该
变量记录所有分组的信息。
g_stdatabase:AfxGetDB()可以得到该变量的引用,该变量实现了本软件的
数据文件接口。
g_stprofile:AfxGetProfile()可以得到该变量的引用,该变量记录当前软
件的一些设置。
第四部分 数据转换
4.1分时线转K线minute.ToKData( kdataNew )
int CSelfDB::LoadKData( CStock *pstock, int nKType )
{
// WILLCHECK
int ret = CQianlong::LoadKData( pstock, nKType );
if( CKData::ktypeMin5 == nKType && LoadMinute( pstock ) > 0 )
{
CKData & kdataMin5 = pstock->GetKDataMin5();
CMinute & minute = pstock->GetMinute();
CKData kdataNew;
if( minute.ToKData( kdataNew ) && CKData::ktypeMin5 == kdataNew.GetKType() )
{
kdataMin5.MergeKData( &kdataNew );
}
return kdataMin5.GetSize();
}
return ret;
}
第五部分 第三方软件对StkLib的引用的实现步骤
G:\stock\TskingVS2019\src\Client\StkLib\Include\StkLib.h
#ifndef STKLIB_DLL
#if defined(STKLIB_STATIC)
#if defined (_DEBUG)
#pragma comment(lib,"StkLib30dStatic.lib")
#pragma message("Automatically linking with StkLib30dStatic.lib")
#else
#pragma comment(lib,"StkLib30Static.lib")
#pragma message("Automatically linking with StkLib30Static.lib")
#endif
#elif defined(_DEBUG)
#pragma comment(lib,"StkLib30d.lib")
#pragma message("Automatically linking with StkLib30d.dll")
#else
#pragma comment(lib,"StkLib30.lib")
#pragma message("Automatically linking with StkLib30.dll")
#endif
#endif
#if !defined(STKLIB_STATIC)
#ifdef STKLIB_DLL
#define STKLIB_API __declspec(dllexport)
#else
#define STKLIB_API __declspec(dllimport)
#endif
#else
#define STKLIB_API
#endif
int CSelfDB::LoadKData( CStock *pstock, int nKType )
{
// WILLCHECK
int ret = CQianlong::LoadKData( pstock, nKType );
if( CKData::ktypeMin5 == nKType && LoadMinute( pstock ) > 0 )
{
CKData & kdataMin5 = pstock->GetKDataMin5();
CMinute & minute = pstock->GetMinute();
CKData kdataNew;
if( minute.ToKData( kdataNew ) && CKData::ktypeMin5 == kdataNew.GetKType() )
{
kdataMin5.MergeKData( &kdataNew );
}
return kdataMin5.GetSize();
}
return ret;
}
和socket的用法相同,包含stklib.h即可。
新项目使用stklib.lib库步骤
step 1:新建一个MFC项目
step 2:KLinePrint:将要引用的stklib.h头文件所在的目录添加到vs2019包含目录里
src/KLinePrint/KLinePrint.vcxproj
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>G:\stock\TskingVS2019Server\src\Client\StkLib\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
step 3:拷贝stklibd30.lib 到工程主目录下
G:\stock\TskingVS2019Server\src\KLinePrint
G:\stock\TskingVS2019Server\src\KLinePrint 的目录
2019/08/12 07:12 <DIR> .
2019/08/12 07:12 <DIR> ..
2019/08/12 06:40 <DIR> Debug
2019/08/12 05:46 1,510 framework.h
2019/08/12 06:07 102,160 KLinePrint.aps
2019/08/12 05:46 4,456 KLinePrint.cpp
2019/08/12 05:46 541 KLinePrint.h
2019/08/12 05:46 18,736 KLinePrint.rc
2019/08/12 06:33 11,042 KLinePrint.vcxproj
2019/08/12 06:33 2,837 KLinePrint.vcxproj.filters
2019/08/12 06:33 236 KLinePrint.vcxproj.user
2019/08/12 05:46 2,794 KLinePrintDoc.cpp
2019/08/12 05:46 928 KLinePrintDoc.h
2019/08/12 05:46 1,603 KLinePrintView.cpp
2019/08/12 05:46 892 KLinePrintView.h
2019/08/12 05:46 1,898 MainFrm.cpp
2019/08/12 05:46 715 MainFrm.h
2019/08/12 05:46 158 pch.cpp
2019/08/12 05:46 544 pch.h
2019/08/12 05:46 <DIR> res
2019/08/12 05:46 474 Resource.h
2019/08/12 06:33 39 stdafx.cpp
2019/08/12 06:33 926 stdafx.h
2019/08/05 06:00 408,624 StkLib30D.exp
2019/08/05 06:00 685,234 StkLib30D.lib
2019/08/12 07:12 0 t.txt
2019/08/12 05:46 299 targetver.h