策略为王源代码分析-stkLIb工程

Published

摘要:

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