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

📄 techenergy.cpp.svn-base

📁 股票软件源码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
	VROC =   ---------------------- * 100
	              今日成交量
*/
BOOL CVROC::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nDays > nIndex )
		return FALSE;
	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;

	if( m_pKData->ElementAt(nIndex-m_nDays).m_fVolume <= 0
		|| m_pKData->ElementAt(nIndex).m_fVolume <= 0 )
		return FALSE;

	double	x	=	m_pKData->ElementAt(nIndex).m_fVolume;
	double	y	=	m_pKData->ElementAt(nIndex-m_nDays).m_fVolume;
	if( pValue )
		*pValue	=	(x - y) * 100 / y;
	StoreToCache( nIndex, pValue );
	return TRUE;
}

BOOL CVROC::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
	return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}

//////////////////////////////////////////////////////////////////////
//	COBV
COBV::COBV( )
{
	SetDefaultParameters( );
}

COBV::COBV( CKData * pKData )
	: CTechnique( pKData )
{
	SetDefaultParameters( );
}

COBV::~COBV()
{
	Clear( );
}

void COBV::SetDefaultParameters( )
{
	m_itsDeviateOnBottom	=	ITS_BUY;
	m_itsDeviateOnTop		=	ITS_SELL;
}

void COBV::AttachParameters( COBV & src )
{
	m_itsDeviateOnBottom	=	src.m_itsDeviateOnBottom;
	m_itsDeviateOnTop		=	src.m_itsDeviateOnTop;
}

BOOL COBV::IsValidParameters( )
{
	return ( VALID_ITS(m_itsDeviateOnBottom) && VALID_ITS(m_itsDeviateOnTop) );
}

void COBV::Clear( )
{
	CTechnique::Clear( );
}

int COBV::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;
	PrepareCache( 0, -1, FALSE );

	if( IsDeviateOnBottom( nIndex, m_pdCache1, m_pdCache2 ) )
	{	// 底背离
		if( pnCode )	*pnCode	=	ITSC_DEVIATEONBOTTOM;
		return m_itsDeviateOnBottom;
	}
	if( IsDeviateOnTop( nIndex, m_pdCache1, m_pdCache2 ) )
	{	// 顶背离
		if( pnCode )	*pnCode	=	ITSC_DEVIATEONTOP;
		return m_itsDeviateOnTop;
	}

	return	ITS_NOTHING;
}

BOOL COBV::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
	return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
}

/***
	当日收盘价比前一日收盘价高,其成交量记为正数
	当日收盘价较前一日收盘价低,其成交量记为负数
	累计每日之正或负成交量,即得OBV值
*/
BOOL COBV::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;

	// Calculate
	double	dValueNew = 0;
	if( bUseLast && pValue )
	{
		if( 0 == nIndex )
			dValueNew	=	m_pKData->ElementAt(nIndex).m_fVolume;
		else if( m_pKData->MaindataAt(nIndex) > m_pKData->MaindataAt(nIndex-1) )
			dValueNew	=	*pValue + m_pKData->ElementAt(nIndex).m_fVolume;
		else if( m_pKData->MaindataAt(nIndex) < m_pKData->MaindataAt(nIndex-1) )
			dValueNew	=	*pValue - m_pKData->ElementAt(nIndex).m_fVolume;
		else
			dValueNew	=	*pValue;

		StoreToCache( nIndex, &dValueNew );
	}
	else
	{
		for( int k=0; k<=nIndex; k++ )
		{
			if( 0 == k )
				dValueNew	=	m_pKData->ElementAt(k).m_fVolume;
			else if( m_pKData->MaindataAt(k) > m_pKData->MaindataAt(k-1) )
				dValueNew	+=	m_pKData->ElementAt(k).m_fVolume;
			else if( m_pKData->MaindataAt(k) < m_pKData->MaindataAt(k-1) )
				dValueNew	-=	m_pKData->ElementAt(k).m_fVolume;

			StoreToCache( k, &dValueNew );
		}
	}

	if( pValue )
		*pValue	=	dValueNew;
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
//	CMOBV
CMOBV::CMOBV( )
{
	SetDefaultParameters( );
}

CMOBV::CMOBV( CKData * pKData )
	: COBV( pKData )
{
	SetDefaultParameters( );
}

CMOBV::~CMOBV()
{
	Clear( );
}

void CMOBV::SetDefaultParameters( )
{
	COBV::SetDefaultParameters();
	m_nDays1	=	12;
	m_nDays2	=	26;
	m_itsGoldenFork		=	ITS_BUY;
	m_itsDeadFork		=	ITS_SELL;
}

void CMOBV::AttachParameters( CMOBV & src )
{
	COBV::AttachParameters( src );
	m_nDays1	=	src.m_nDays1;
	m_nDays2	=	src.m_nDays2;
	m_itsGoldenFork		=	src.m_itsGoldenFork;
	m_itsDeadFork		=	src.m_itsDeadFork;
}

BOOL CMOBV::IsValidParameters( )
{
	return ( COBV::IsValidParameters()
		&& VALID_DAYS(m_nDays1) && VALID_DAYS(m_nDays2)
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}

void CMOBV::Clear( )
{
	CTechnique::Clear( );
}

int CMOBV::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;
	if( !m_pKData || nIndex < 0 || nIndex >= m_pKData->GetSize() )
		return ITS_NOTHING;

	PrepareCache( 0, -1, FALSE );
	
	int	nMaxDays	=	max( m_nDays1 , m_nDays2 );
	double	dLiminalLow = 0, dLiminalHigh = 0;
	if( !IntensityPreparePrice( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.5, 0.5 ) )
		return ITS_NOTHING;

	double	dPriceNow	=	m_pKData->MaindataAt(nIndex);

	if( dPriceNow < dLiminalLow
		&& ( IsGoldenFork( nIndex, m_pdCache1, m_pdCache2 ) || IsGoldenFork( nIndex, m_pdCache2, m_pdCache3 ) ) )
	{	// 低位金叉
		if( pnCode )	*pnCode	=	ITSC_GOLDENFORK;
		return m_itsGoldenFork;
	}
	if( dPriceNow > dLiminalHigh
		&& ( IsDeadFork( nIndex, m_pdCache1, m_pdCache2 ) || IsDeadFork( nIndex, m_pdCache2, m_pdCache3 ) ) )
	{	// 高位死叉
		if( pnCode )	*pnCode	=	ITSC_DEADFORK;
		return m_itsDeadFork;
	}

	return	ITS_NOTHING;
}

BOOL CMOBV::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
	return AfxGetMinMaxInfo3( nStart, nEnd, pdMin, pdMax, this );
}

/***
	*pValue1  = 当日OBV
	*pValue2  = m_nDays1日OBV平均值
	*pValue3  = m_nDays2日OBV平均值
*/
BOOL CMOBV::Calculate( double * pValue1, double * pValue2, double * pValue3, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	int	nMaxDays	=	max(m_nDays1,m_nDays2);
	if( nMaxDays > nIndex+1 )
		return FALSE;

	if( LoadFromCache( nIndex, pValue1, pValue2, pValue3 ) )
		return TRUE;

	double	dOBV = 0, dMOBV1 = 0, dMOBV2 = 0;
	int	nCount	=	0;
	BOOL	bHasLast	=	bUseLast;
	for( int k=nIndex; k>=0; k-- )
	{
		double	dTemp = 0;
		if( bUseLast && nIndex == k && pValue1 )
			dTemp	=	*pValue1;
		if( COBV::Calculate( &dTemp, k, bUseLast && nIndex == k && pValue1 ) )
		{
			if( nIndex == k )
				dOBV	=	dTemp;
			if( nCount < m_nDays1 )
				dMOBV1	+=	dTemp;
			if( nCount < m_nDays2 )
				dMOBV2	+=	dTemp;

			nCount	++;
			if( nCount >= m_nDays1 && nCount >= m_nDays2 )
			{
				if( pValue1 )	*pValue1	=	dOBV;
				if( pValue2 )	*pValue2	=	dMOBV1 / m_nDays1;
				if( pValue3 )	*pValue3	=	dMOBV2 / m_nDays2;
				StoreToCache( nIndex, pValue1, pValue2, pValue3 );
				return TRUE;
			}
		}
	}

	return FALSE;
}

//////////////////////////////////////////////////////////////////////
//	CMFI
CMFI::CMFI( )
{
	SetDefaultParameters( );
}

CMFI::CMFI( CKData * pKData )
	: CTechnique( pKData )
{
	SetDefaultParameters( );
}

CMFI::~CMFI()
{
	Clear( );
}

void CMFI::SetDefaultParameters( )
{
	m_nDays		=	10;
	m_itsLong	=	ITS_BUY;
	m_itsShort	=	ITS_SELL;
}

void CMFI::AttachParameters( CMFI & src )
{
	m_nDays		=	src.m_nDays;
	m_itsLong	=	src.m_itsLong;
	m_itsShort	=	src.m_itsShort;
}

BOOL CMFI::IsValidParameters( )
{
	return ( VALID_DAYS(m_nDays) && VALID_ITS(m_itsLong) && VALID_ITS(m_itsShort) );
}

void CMFI::Clear( )
{
	CTechnique::Clear( );
}

int CMFI::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;

	double	dValue = 0;
	if( !Calculate( &dValue, nIndex, FALSE ) )
		return ITS_NOTHING;

	if( dValue <= 20 )
	{	// 低位
		if( pnCode )	*pnCode	=	ITSC_LONG;
		return m_itsLong;
	}
	if( dValue >= 80 )
	{	// 高位
		if( pnCode )	*pnCode	=	ITSC_SHORT;
		return m_itsShort;
	}
	return	ITS_NOTHING;
}

BOOL CMFI::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
	if( pdMin )	*pdMin	=	0;
	if( pdMax )	*pdMax	=	100;
	return TRUE;
}

/***
	PMF 和 NMF 如下计算:

		TP = (High+Low+Close)/3   当日的中间价

		PMF = n日内,TP上涨日的 (TP*成交量) 之和。
		NMF = n日内,TP下降日的 (TP*成交量) 之和。	

	MFI = 100 * PMF / (PMF + NMF)
	备注:MR = PMF/NMF
*/
BOOL CMFI::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );
	
	if( m_nDays > nIndex )
		return FALSE;

	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;

	double	dPMF = 0, dNMF = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);
		KDATA	kdLast	=	m_pKData->ElementAt(k-1);
		double	dTP		= (kd.m_fHigh+kd.m_fLow+kd.m_fClose)/3.;
		double	dTPLast = (kdLast.m_fHigh+kdLast.m_fLow+kdLast.m_fClose)/3.;
		if( dTP > dTPLast )
			dPMF	+=	dTP * kd.m_fVolume;
		if( dTPLast > dTP )
			dNMF	+=	dTP * kd.m_fVolume;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( fabs(dPMF+dNMF) < 1e-4 )
				return FALSE;
			if( pValue )	*pValue	=	100 * dPMF / (dPMF + dNMF);
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}

//////////////////////////////////////////////////////////////////////
//	CVMACD
CVMACD::CVMACD( )
{
	SetDefaultParameters( );
}

CVMACD::CVMACD( CKData * pKData )
	: CMACD( pKData )
{
	SetDefaultParameters( );
}

CVMACD::~CVMACD()
{
	Clear( );
}

/***
	成交量的MACD
	EMA  = 短期移动均值
	EMA2 = 长期移动均值
	DIF  = 短期移动均值 - 长期移动均值
	DEA  = DIF的移动平滑值
	柱状线值 = DIF - DEA
*/
BOOL CVMACD::Calculate( double *pdEMA1, double *pdEMA2, double *pdDIF, double *pdDEA,
					int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nEMA1Days > nIndex+1 || m_nEMA2Days > nIndex+1 || m_nDIFDays > nIndex+1 )
		return FALSE;

	if( LoadFromCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA ) )
		return TRUE;

	// Calculate EMA1, EMA2, DIF, DEA
	double	dEMA1New = 0, dEMA2New = 0, dDIFNew = 0, dDEANew = 0;
	if( bUseLast && pdEMA1 && pdEMA2 && pdDEA )
	{
		dEMA1New	=	(*pdEMA1)*(m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->ElementAt(nIndex).m_fVolume/(m_nEMA1Days+1);
		dEMA2New	=	(*pdEMA2)*(m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->ElementAt(nIndex).m_fVolume/(m_nEMA2Days+1);
		dDIFNew		=	dEMA1New-dEMA2New;
		dDEANew		=	(*pdDEA)*(m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew/(m_nDIFDays+1);
	}
	else
	{
		double	factor1 = 1, factor2 = 1;
		int k;
		for( k=nIndex; k > 0; k-- )
		{
			factor1		*=	((double)(m_nEMA1Days-1))/(m_nEMA1Days+1);
			factor2		*=	((double)(m_nEMA2Days-1))/(m_nEMA2Days+1);
			if( factor1 < 0.001 && factor2 < 0.001 )	// 太久以前的数据影响很小,忽略不计
				break;
		}
		dEMA1New	=	m_pKData->ElementAt(k).m_fVolume;
		dEMA2New	=	m_pKData->ElementAt(k).m_fVolume;
		dDIFNew		=	dEMA1New - dEMA2New;
		dDEANew		=	dDIFNew;
		for( ; k<=nIndex; k++ )
		{
			dEMA1New	=	dEMA1New * (m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->ElementAt(k).m_fVolume/(m_nEMA1Days+1);
			dEMA2New	=	dEMA2New * (m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->ElementAt(k).m_fVolume/(m_nEMA2Days+1);
			dDIFNew		=	dEMA1New - dEMA2New;
			dDEANew		=	dDEANew * (m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew / (m_nDIFDays+1);
		}
	}

	if( pdEMA1 )		*pdEMA1	=	dEMA1New;
	if( pdEMA2 )		*pdEMA2	=	dEMA2New;
	if( pdDIF )			*pdDIF	=	dDIFNew;
	if( pdDEA )			*pdDEA	=	dDEANew;
	StoreToCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA );
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
//	CWVAD
CWVAD::CWVAD( )
{
	SetDefaultParameters( );
}

CWVAD::CWVAD( CKData * pKData )
	: CTechnique( pKData )
{
	SetDefaultParameters( );
}

CWVAD::~CWVAD()
{
	Clear( );
}

void CWVAD::SetDefaultParameters( )
{
	m_nDays		=	24;
	m_itsLong				=	ITS_BUY;
	m_itsShort				=	ITS_SELL;
}

void CWVAD::AttachParameters( CWVAD & src )
{
	m_nDays		=	src.m_nDays;
	m_itsLong				=	src.m_itsLong;
	m_itsShort				=	src.m_itsShort;
}

BOOL CWVAD::IsValidParameters( )
{
	return ( VALID_DAYS( m_nDays )
		&& VALID_ITS(m_itsLong) && VALID_ITS(m_itsShort) );
}

void CWVAD::Clear( )
{
	CTechnique::Clear( );
}

int CWVAD::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;

	int	nMaxDays	=	m_nDays;
	double	dLiminalLow = 0, dLiminalHigh = 0;
	if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh ) )
		return ITS_NOTHING;

	if( nIndex <= 0 )
		return ITS_NOTHING;

	double	dLast, dNow;
	if( !Calculate( &dLast, nIndex-1, FALSE )
		|| !Calculate( &dNow, nIndex, FALSE ) )
		return ITS_NOTHING;

	if( dNow < dLiminalLow )
	{	// 低位
		if( pnCode )	*pnCode	=	ITSC_LONG;
		return m_itsLong;
	}
	if( dNow > dLiminalHigh  )
	{	// 高位
		if( pnCode )	*pnCode	=	ITSC_SHORT;
		return m_itsShort;
	}

	return	ITS_NOTHING;
}

BOOL CWVAD::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
	return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );

⌨️ 快捷键说明

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