⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strategy.cpp

📁 股软 通达信行情接收接口, 包括美元汇率
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if( AfxGetStockContainer().GetStockInfo( m_stocks.ElementAt(i), &info ) )
//#ifdef CLKLAN_ENGLISH_US
//			strStock	+=	info.GetStockCode();
//#else
			strStock	+=	info.GetStockName();
//#endif
		else
			strStock	+=	m_stocks.ElementAt(i);
	}
	if( strStock.GetLength() == 0 )
		strStock	=	strategy_noselectedstock;
	else if( m_stocks.GetSize() > nStockShowCount )
		strStock	+=	"...";
	strStock	+=	";    ";

	CSPString	strTech;
	for(  i=0; i<m_anTechsBuy.GetSize() && i<nTechShowCount; i++ )
	{
		if( strTech.GetLength() > 0 )
			strTech	+=	",";
		strTech	+=	AfxGetSTTShortName(m_anTechsBuy[i]);
	}
	if( strTech.GetLength() == 0 )
		strTech	=	strategy_noselectedtech;
	else if( m_anTechsBuy.GetSize() > nTechShowCount )
		strTech	+=	"...";
	
	return strStock + strTech;
}
// 交易费率、操作条件等
CRateParam &	CStrategy::GetRateParam( )			{	return m_rate;			}
COpParam &		CStrategy::GetOpParam( )				{	return m_opparam;		}
CTechParameters & CStrategy::GetTechParametersBuy( )	{	return m_paramBuy;		}
CTechParameters & CStrategy::GetTechParametersSell( )	{	return m_paramSell;		}
CTechParameters & CStrategy::GetTechParametersLongTrend( )	{	return m_paramLongTrend;		}
CTechParameters & CStrategy::GetTechParametersIndexTrend( )	{	return m_paramIndexTrend;		}
CSPDWordArray &	CStrategy::GetSelectedTechsBuy( )		{	return m_anTechsBuy;	}
CSPDWordArray &	CStrategy::GetSelectedTechsSell( )		{	return m_anTechsSell;	}
CSPDWordArray &	CStrategy::GetSelectedTechsLongTrend( )	{	return m_anTechsLongTrend;	}
CSPDWordArray &	CStrategy::GetSelectedTechsIndexTrend( )	{	return m_anTechsIndexTrend;	}

/////////////////////////////////////////////////////////////////////////
// Cache
// 准备数据,读取K线数据,长周期K线数据,生成技术指标对象
BOOL CStrategy::PrepareData( SIMULATION_CALLBACK fnCallback, void * cookie )
{
	if( m_techstocks.GetSize() == m_stocks.GetSize() )
		return TRUE;

	ClearCache( );

	// m_techstocks.m_kdataIndex m_techstocks.m_infoIndex
	if( m_opparam.m_bIndexTrend )	// 指数K线数据
	{
		CStockInfo	infoIndex;
		if( AfxGetStockContainer().GetStockInfo( STKLIB_CODE_MAIN, &infoIndex ) )
		{
			m_techstocks.m_infoIndex	=	infoIndex;
			
			CStock	stockIndex;
			stockIndex.SetStockInfo( &infoIndex );
			stockIndex.SetDatabase( &AfxGetDB() );
			stockIndex.PrepareData( CStock::dataK, m_opparam.m_nKTypeIndex );
			CKData	&	kdataIndex		=	stockIndex.GetKData(m_opparam.m_nKTypeIndex);
			kdataIndex.SetMaindataType( m_opparam.m_nMaindataType );
			m_techstocks.m_kdataIndex	=	kdataIndex;

			// m_techstocks.m_techsIndex
			for( int j=0; j<m_anTechsIndexTrend.GetSize(); j++ )
			{
				CTechnique * pTech	=	CTechnique::CreateTechnique( m_anTechsIndexTrend[j], &(m_techstocks.m_kdataIndex) );
				m_paramIndexTrend.FindParameters( m_anTechsIndexTrend[j], pTech );
				m_techstocks.m_techsIndex.Add( pTech );
			}
		}
	}
	
	m_techstocks.SetSize( m_stocks.GetSize() );
	int	nStockCount	=	0;
	for( int i=0; i<m_stocks.GetSize(); i++ )	// 读取每一只备选股票的数据
	{
		CStockInfo	info;
		if( AfxGetStockContainer().GetStockInfo( m_stocks.ElementAt(i), &info ) )
		{
			// CTechStock::m_info;
			CTechStock	temp;
			temp.m_info	=	info;
			
			m_techstocks.SetAt( nStockCount, temp );
			CTechStock & techstock	=	m_techstocks.ElementAt(nStockCount);
			nStockCount	++;
			
			// CTechStock::m_kdata
			CStock	stock;
			stock.SetStockInfo( &info );
			AfxPrepareStockData( &AfxGetDB(), stock, m_opparam.m_nKType, CKData::formatXDRdown, m_opparam.m_nMaindataType, FALSE, FALSE );
			techstock.m_kdata	=	stock.GetKData(m_opparam.m_nKType);

			// CTechStock::m_techs
			techstock.SetAutoDelete( TRUE );
			for( int j=0; j<m_anTechsBuy.GetSize(); j++ )
			{
				CTechnique * pTech	=	CTechnique::CreateTechnique( m_anTechsBuy[j], &(techstock.m_kdata) );
				m_paramBuy.FindParameters( m_anTechsBuy[j], pTech );
				techstock.m_techs.Add( pTech );
			}

			// CTechStock::m_kdataLong
			if( m_opparam.m_bLongTrend )
			{
				AfxPrepareStockData( &AfxGetDB(), stock, m_opparam.m_nKTypeLong, CKData::formatXDRdown, m_opparam.m_nMaindataType, FALSE, FALSE );
				techstock.m_kdataLong	=	stock.GetKData( m_opparam.m_nKTypeLong );

				// CTechStock::m_techsLong
				for( int j=0; j<m_anTechsLongTrend.GetSize(); j++ )
				{
					CTechnique * pTech	=	CTechnique::CreateTechnique( m_anTechsLongTrend[j], &(techstock.m_kdataLong) );
					m_paramLongTrend.FindParameters( m_anTechsLongTrend[j], pTech );
					techstock.m_techsLong.Add( pTech );
				}
			}
		}

		DWORD	dwProgress	=	(DWORD)((i+1)*STRATEGY_MAXF_PROGRESS / m_stocks.GetSize());
		if( fnCallback && !fnCallback( SIMULATION_PROGRESS, dwProgress, NULL, cookie ) )
		{
			ClearCache( );
			nStockCount	=	0;
			break;
		}
	}

	m_techstocks.SetSize( nStockCount );

	if( fnCallback )
		fnCallback( SIMULATION_PROGRESS, STRATEGY_MAX_PROGRESS, NULL, cookie );

	return ( m_techstocks.GetSize() == m_stocks.GetSize() );
}

// 清除每个指标保存的上次趋势值
void CStrategy::ClearLastIntensity( )
{
	for( int i=0; i<m_techstocks.GetSize(); i++ )
	{
		CTechStock & techstock	=	m_techstocks.ElementAt(i);
			
		for( int nTech=0; nTech<techstock.m_techs.GetSize(); nTech++ )
		{
			CTechnique * pTech	=	(CTechnique *)techstock.m_techs.ElementAt(nTech);
			if( pTech )
				pTech->ClearLastIntensity();
		}
	}
}

void CStrategy::ClearCache( )
{
	m_techstocks.Clear();
}

CTechStockContainer & CStrategy::GetTechStockContainer( )
{
	return m_techstocks;
}

////////////////////////////////////////////////////////////////////////
// Simulation
// 策略模拟:重新设定
void CStrategy::SimuReset( )
{
	SimuSetStatusInit( );
	m_SimuCurrentTime	=	m_opparam.GetBeginTime( );
	m_SimuCurrentCash	=	m_opparam.m_nStartAmount;
	m_SimuOpRecord.RemoveAll();
	m_SimuNextOp.RemoveAll();
	m_SimuStockOwn.RemoveAll();
	m_SimuAssetSerial.RemoveAll();

	SP_ASSERT( m_opparam.IsValid() );
}
// 策略模拟:进入下一个交易日
BOOL CStrategy::SimuGotoNextTime( )
{
	CSPTime	tmNext;
	if( m_opparam.GetNextTradeTime( m_SimuCurrentTime, tmNext )
		&& m_opparam.IsInTimeZones( tmNext ) )
	{
		m_SimuCurrentTime	=	tmNext;
		return TRUE;
	}
	return FALSE;
}
// 策略模拟:模拟的当前时间
CSPTime CStrategy::SimuGetCurrentTime( )
{
	return m_SimuCurrentTime;
}
// 策略模拟:模拟的当前资金
double CStrategy::SimuGetCurrentCash( )
{
	return m_SimuCurrentCash;
}
// 策略模拟:操作执行,bTimeStrict表示是否严格遵守计划时间
BOOL CStrategy::SimuOperate( OPRECORD record, BOOL bTimeStrict )
{
	if( ! m_opparam.IsInTimeZones( record.time ) )
		return FALSE;
	if( bTimeStrict && m_SimuOpRecord.GetSize() > 0 && record.time < m_SimuOpRecord.ElementAt(m_SimuOpRecord.GetSize()-1).time )
		return FALSE;
	CStockInfo	info;
	if( strlen(record.szCode)>0
		&& ( !AfxGetStockContainer().GetStockInfo( record.szCode, &info )
		|| !info.IsValidStock() ) )
		return FALSE;

	double	dAmount		=	record.dwShare * record.dSharePrice;
	double	dRateCost	=	record.dRateCost;
	if( STRATEGY_OPTYPE_BUY == record.lOpType )			// 买入
	{
		if( m_SimuCurrentCash < dAmount+dRateCost )
			return FALSE;
		if( !m_SimuStockOwn.AddStock( info, record.dwShare, record.dSharePrice ) )
			return FALSE;
		m_SimuCurrentCash	-=	(dAmount+dRateCost);
	}
	else if( STRATEGY_OPTYPE_SELL == record.lOpType )	// 卖出
	{
		if( !m_SimuStockOwn.RemoveStock( info, record.dwShare ) )
			return FALSE;
		m_SimuCurrentCash	+=	(dAmount-dRateCost);
	}
	else if( STRATEGY_OPTYPE_ADDSTOCK == record.lOpType )// 添加股票
	{
		if( !m_SimuStockOwn.AddStock( info, record.dwShare, record.dSharePrice ) )
			return FALSE;
	}
	else if( STRATEGY_OPTYPE_REMOVESTOCK == record.lOpType )// 移除股票
	{
		if( !m_SimuStockOwn.RemoveStock( info, record.dwShare ) )
			return FALSE;
	}
	else if( STRATEGY_OPTYPE_ADDCASH == record.lOpType )	// 添加资金
	{
		m_SimuCurrentCash	+=	record.dSharePrice;
	}
	else if( STRATEGY_OPTYPE_REMOVECASH == record.lOpType ) // 移除资金
	{
		if( m_SimuCurrentCash < record.dSharePrice )
			return FALSE;
		m_SimuCurrentCash	-=	record.dSharePrice;
	}
	else
		return FALSE;

	// Record
	m_SimuOpRecord.Add( record );
	return TRUE;
}
// 策略模拟:操作记录
COpRecordContainer & CStrategy::SimuGetOpRecord( )
{
	return m_SimuOpRecord;
}
// 策略模拟:下一步操作
COpRecordContainer & CStrategy::SimuGetNextOp( )
{
	return m_SimuNextOp;
}
// 策略模拟:当前拥有股票
CStockOwnContainer & CStrategy::SimuGetStockOwn( )
{
	return m_SimuStockOwn;
}
// 策略模拟:总资产序列
CAssetSerialContainer & CStrategy::SimuGetAssetSerial( )
{
	return m_SimuAssetSerial;
}
// 策略模拟:当前进度
DWORD CStrategy::SimuGetCurrentProgress( DWORD dwProgressMax )
{
	return m_opparam.GetProgress( m_SimuCurrentTime, dwProgressMax );
}
// 策略模拟:给定时间的总资产
double CStrategy::SimuGetAsset( CSPTime tmCur )
{
	double	dAsset	=	0;
	if( m_techstocks.GetSumAsset( tmCur, m_SimuStockOwn, &dAsset ) )	// 计算总资产
	{
		dAsset	+=	m_SimuCurrentCash;

		ASSETSERIAL	serial;
		memset( &serial, 0, sizeof(serial) );
		serial.time		=	tmCur.GetTime();
		serial.dAsset	=	dAsset;
		serial.dCash	=	m_SimuCurrentCash;
		m_SimuAssetSerial.SortInsert( serial );
		return dAsset;
	}
	else
	{
		for( int i=m_SimuAssetSerial.GetSize()-1; i>=0; i-- )
		{
			ASSETSERIAL & serial	=	m_SimuAssetSerial.ElementAt(i);
			if( serial.time <= tmCur.GetTime() )
				return serial.dAsset;
		}
	}
	return m_opparam.m_nStartAmount;	// 初始总资产
}
// 策略模拟:当前收益
double CStrategy::SimuGetCurrentYield( )
{
	if( m_opparam.m_nStartAmount > 0 )
		return STRATEGY_BASEF_YIELD * SimuGetAsset(m_SimuCurrentTime) / m_opparam.m_nStartAmount;
	return STRATEGY_BASEF_YIELD;
}
// 策略模拟:当前指数上涨多少
double CStrategy::SimuGetCurrentYieldIndexPercent( )
{
	CSPTime	sptmBegin( m_opparam.GetBeginTime().GetTime() );
	CSPTime	sptmNow( m_SimuCurrentTime.GetTime() );
	DWORD	dateBegin	=	sptmBegin.ToStockTimeDay();
	DWORD	dateNow		=	sptmNow.ToStockTimeDay();
	
	CKData & kdata	=	AfxGetStockMain().GetKData(m_opparam.m_nKType);
	int	nIndexBegin	=	kdata.GetAboutIndexByDate( dateBegin );
	int	nIndexNow	=	kdata.GetAboutIndexByDate( dateNow );
	if( -1 == nIndexBegin || -1 == nIndexNow )
		return 0;

	if( kdata.ElementAt(nIndexBegin).m_fClose < 1e-4 )
		return 0;

	double	dYield	=	((double)kdata.ElementAt(nIndexNow).m_fClose) - kdata.ElementAt(nIndexBegin).m_fClose;
	dYield	=	dYield / kdata.ElementAt(nIndexBegin).m_fClose;

	return dYield;
}
// 策略模拟:当前收益百分数
double CStrategy::SimuGetCurrentYieldPercent( )
{
	return ( SimuGetCurrentYield() - STRATEGY_BASEF_YIELD ) / STRATEGY_BASEF_YIELD;
}
// 策略模拟:执行下一步操作计划
BOOL CStrategy::SimuOperateNextop( CSPTime tmCur, COpRecordContainer & nextop, CTechStock & techstock )
{
	for( int j=0; j<nextop.GetSize(); j++ )	// 每个计划依次执行
	{
		OPRECORD &	record	=	nextop.ElementAt(j);
		if( STRATEGY_OPTYPE_BUY != record.lOpType && STRATEGY_OPTYPE_SELL != record.lOpType )
			continue;

		if( tmCur.GetTime() >= record.time
			&& techstock.m_info.IsEqualTo( CStock::marketUnknown, record.szCode ) )
		{
			if( techstock.IsStopTrading(tmCur) )	// 停牌吗
			{
				CSPTime	tmNext;
				if( m_opparam.GetNextTradeTime(tmCur, tmNext) )
					record.time	=	tmNext.GetTime();	// 下次再执行
				continue;
			}

			double	dPriceOK	=	record.dSharePrice;
			if( techstock.GetPriceOK( record.lOpType, tmCur, record.dwShare, record.dSharePrice, &dPriceOK ) )	// 成交价
			{
				record.time			=	tmCur.GetTime();
				record.dSharePrice	=	dPriceOK;
				record.dRateCost	=	record.dwShare * record.dSharePrice * m_rate.GetRate(techstock.m_info);
				SimuOperate( record );
			}
			else if( STRATEGY_OPTYPE_SELL == record.lOpType )	// 如果是卖出而没有成功,则顺延下一个交易日,直至卖出
			{
				CSPTime	tmNext;
				if( m_opparam.GetNextTradeTime(tmCur, tmNext) )
					record.time	=	tmNext.GetTime();
				if( techstock.GetClosePrice(tmCur,&dPriceOK) )
					record.dSharePrice	=	dPriceOK * m_opparam.m_dSellMulti;
				continue;
			}
			nextop.RemoveAt(j);
			j --;
		}
	}
	return TRUE;
}
// 策略模拟:模拟运行
BOOL CStrategy::SimuRun( SIMULATION_CALLBACK fnCallback, void * cookie )
{
	// TIMEZONES
	// 准备数据
	if( !PrepareData( fnCallback, cookie ) )
		return FALSE;

	ClearLastIntensity( );

	DWORD	dwShare = 0;		// Temp Data
	double	dSharePrice = 0;	// Temp Data
	CSPTime	tmOp;				// Temp Data

	do	{
		CSPTime	tmCur	=	SimuGetCurrentTime();	// 模拟当前时间

		// Process
		for( int i=0; i<m_techstocks.GetSize(); i++ )	// 每只股票依次判断
		{
			CTechStock & techstock	=	m_techstocks.ElementAt(i);

			// Operate
			SimuOperateNextop( tmCur, m_SimuNextOp, techstock );	// 执行今天的操作计划

			// Judge Whether to operate, if yes, save to nextop
			STOCKOWN	own;
			memset( &own, 0, sizeof(own) );
			if( m_SimuStockOwn.HasThisStock( techstock.m_info, &own ) )	// 如果已经有这支股票,判断是否卖出
			{
				if( m_techstocks.GetShouldSellShare( techstock, tmCur, own, m_opparam, &tmOp, &dwShare, &dSharePrice ) )
				{	// 如果要卖出,加入下一步操作计划,下一个交易日执行
					m_SimuNextOp.AddRecordUniqueStock( STRATEGY_OPTYPE_SELL, tmOp, techstock.m_info.GetStockCode(), dwShare, dSharePrice, dwShare*dSharePrice*m_rate.GetRate(techstock.m_info) );
				}
			}
			else	// 判断是否买入
			{
				if( m_techstocks.GetShouldBuyShare( techstock, tmCur, m_SimuCurrentCash, m_rate , m_opparam, m_SimuStockOwn.GetSize(), &tmOp, &dwShare, &dSharePrice )
					&& ( m_SimuStockOwn.GetSize() + m_SimuNextOp.GetBuyRecordCount() < m_opparam.m_nStoreDiv || m_SimuNextOp.HasBuyStock(techstock.m_info.GetStockCode()) ) )
				{	// 如果要买入,加入下一步操作计划,下一个交易日执行
					m_SimuNextOp.AddRecordUniqueStock( STRATEGY_OPTYPE_BUY, tmOp, techstock.m_info.GetStockCode(), dwShare, dSharePrice, dwShare*dSharePrice*m_rate.GetRate(techstock.m_info) );
				}
			}
		}

		// 进度显示
		DWORD	dwProgress	=	SimuGetCurrentProgress( STRATEGY_MAX_PROGRESS );
		double	dYield		=	SimuGetCurrentYield( );
		if( fnCallback && !fnCallback( SIMULATION_PROGRESS, dwProgress, NULL, cookie ) )
			return FALSE;
		if( fnCallback && !fnCallback( SIMULATION_YIELD, (DWORD)dYield, NULL, cookie ) )
			return FALSE;

	} while( SimuGotoNextTime() );	// 模拟的下一个交易日

	if( fnCallback )
		fnCallback( SIMULATION_PROGRESS, STRATEGY_MAX_PROGRESS, NULL, cookie );
	return TRUE;
}

////////////////////////////////////////////////////////////////////////
// Real
// 策略实战:重新设定
void CStrategy::RealReset( )
{
	CSPTime	tmLatest	=	CSPTime::GetCurrentTime();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -