예제 #1
0
/***
	VP = N日内成交量增加日的总成交量
	VQ = N日内成交量减少日的总成交量
	VRSI = 100 * VP / (VP+VQ)
*/
BOOL CNVRSI::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	dUV = 0, dV = 0, dResult = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		if( m_pKData->ElementAt(k).m_fVolume > m_pKData->ElementAt(k-1).m_fVolume )
			dUV	+=	m_pKData->ElementAt(k).m_fVolume;
		dV	+=	m_pKData->ElementAt(k).m_fVolume;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( dV < 1e-4 )
				dResult	=	50;
			else
				dResult	=	100. * dUV / dV;
			if( pValue )	*pValue	=	dResult;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #2
0
/***
	A = 当天收盘价 - 当天开盘价
	B = 当天最高价 - 当天最低价
	C = A÷B×V(成交量)
	WVAD = 累计n天的C值
*/
BOOL CWVAD::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nDays > nIndex+1 )
		return FALSE;

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

	int	nCount	=	0;
	double	dResult = 0;
	for( int k=nIndex; k>=0; k-- )
	{
		KDATA	kd	=	m_pKData->ElementAt(k);
		if( kd.m_fHigh > kd.m_fLow )
			dResult	+=	(((double)kd.m_fClose) - kd.m_fOpen)*kd.m_fVolume/(((double)kd.m_fHigh)-kd.m_fLow);

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )	*pValue	=	dResult;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}
	return FALSE;
}
예제 #3
0
/***
	布林带是以股价平均线MA为中心线,上方阻力线MA+αSn和下方支撑线MA-αSn之间的带状区域
	其中 Sn为n日收盘价的标准差
*/
BOOL CBOLL::Calculate( double * pdMA, double * pdUp, double * pdDown, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );
	
	if( m_nMADays < 2 )
		return FALSE;

	if( LoadFromCache( nIndex, pdMA, pdUp, pdDown ) )
		return TRUE;

	double	dMA = 0, dUp = 0, dDown = 0, dS = 0;

	if( !m_pKData->GetMA( &dMA, nIndex, m_nMADays ) )
		return FALSE;

	int	nCount	=	0;
	for( int k=nIndex; k>=0; k-- )
	{
		dS	+=	(m_pKData->MaindataAt(k) - dMA) * (m_pKData->MaindataAt(k) - dMA);
		nCount	++;
		if( nCount == m_nMADays )
			break;
	}

	dS	=	sqrt( dS / (m_nMADays-1) );

	dUp		=	dMA + m_dMultiUp * dS;
	dDown	=	dMA - m_dMultiDown * dS;
	if( pdMA )		*pdMA	=	dMA;
	if( pdUp )		*pdUp	=	dUp;
	if( pdDown )	*pdDown	=	dDown;

	StoreToCache( nIndex, pdMA, pdUp, pdDown );
	return TRUE;
}
예제 #4
0
/***
	PV就是当日成交均价,成交额除以成交量
*/
BOOL CPV::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

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

	KDATA	kd	=	m_pKData->ElementAt(nIndex);
	if( kd.m_fVolume <= 1e-4 || kd.m_fAmount <= 1e-4 )
		return  FALSE;
	
	int		nCount	=	0;
	double	average	=	((double)(kd.m_fAmount)) / kd.m_fVolume;
	while( average < kd.m_fLow && nCount < 10 )	{	average	*=	10;	nCount ++;	}
	while( average > kd.m_fHigh && nCount < 20 )	{	average	/=	10;	nCount ++;	}
	if( average < kd.m_fLow )		//	说明是指数
		average	=	(kd.m_fOpen+kd.m_fHigh+kd.m_fLow+kd.m_fClose)/4;

	double	dPV	=	average;
	if( pValue )
		*pValue	=	dPV;

	StoreToCache( nIndex, pValue );
	return TRUE;
}
예제 #5
0
/***
	TR 为以下三者中的最大值
		最高价-最低价,(昨日收盘价-今日最高价)的绝对值,昨日收盘价-昨日最低价

	ATR = TR的N日平均
*/
BOOL CATR::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	dATR = 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	dTR	=	fabs(((double)kd.m_fHigh)-kd.m_fLow);
		if( fabs(((double)kdLast.m_fClose)-kd.m_fHigh) > dTR )
			dTR	=	fabs(((double)kdLast.m_fClose)-kd.m_fHigh);
		if( fabs(((double)kdLast.m_fClose)-kdLast.m_fLow) > dTR )
			dTR	=	fabs(((double)kdLast.m_fClose)-kdLast.m_fLow);

		dATR	+=	dTR;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )	*pValue	=	dATR/m_nDays;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}
	return FALSE;
}
예제 #6
0
/***
	BBI = 4 个 不同日期的MA 的平均值
*/
BOOL CBBI::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;
	
	double	dResult	=	0;
	double	dTemp	=	0;

	if( !m_pKData->GetMA( &dTemp, nIndex, m_nMA1Days ) )
		return FALSE;
	dResult	+=	dTemp;

	if( !m_pKData->GetMA( &dTemp, nIndex, m_nMA2Days ) )
		return FALSE;
	dResult	+=	dTemp;

	if( !m_pKData->GetMA( &dTemp, nIndex, m_nMA3Days ) )
		return FALSE;
	dResult	+=	dTemp;

	if( !m_pKData->GetMA( &dTemp, nIndex, m_nMA4Days ) )
		return FALSE;
	dResult	+=	dTemp;

	dResult	=	dResult / 4;
	if( pValue )
		*pValue	=	dResult;

	StoreToCache( nIndex, pValue );
	return TRUE;
}
예제 #7
0
/***
	A = 当日最高价 - 当日最低价
	B = 2 * 当日收盘价 - 当日最高价 - 当日最低价
	C = 当日成交量 * B / A
	AD = N日内C的总和
*/
BOOL CAD::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nDays > nIndex+1 )
		return FALSE;

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

	double	dAD = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=0; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);

		if( kd.m_fHigh-kd.m_fLow > 1e-4 )
			dAD	+=	kd.m_fVolume * (((double)kd.m_fClose)-kd.m_fLow-kd.m_fHigh+kd.m_fClose)/(((double)kd.m_fHigh)-kd.m_fLow);

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )	*pValue	=	dAD;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #8
0
/***
	CI = (当日收盘价 - 当日开盘价)/(当日最高价 - 当日最低价)
*/
BOOL CCI::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );
	
	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;

	KDATA	kd		=	m_pKData->ElementAt(nIndex);
	if( kd.m_fHigh-kd.m_fLow < 1e-4)
		return FALSE;
	double	dCI	=	(((double)kd.m_fClose)-kd.m_fOpen)/(((double)kd.m_fHigh)-kd.m_fLow);
/*
	if( nIndex > 0 )
	{
		KDATA	kdLast	=	m_pKData->ElementAt(nIndex-1);
		if( max(kd.m_fOpen,kd.m_fClose) > kdLast.m_fClose*1.08 && kd.m_fHigh>kdLast.m_fClose)
			dCI	+=	(2.*kd.m_fClose-kd.m_fLow-kdLast.m_fClose)/(((double)kd.m_fHigh)-kdLast.m_fClose);
		if( kd.m_fOpen < kdLast.m_fClose*0.92 )
			dCI	+=	(2.*kd.m_fLow-kd.m_fHigh-kdLast.m_fClose)/(((double)kd.m_fClose)-kd.m_fLow);
	}
*/
	dCI	=	kd.m_fVolume * dCI;
	if( pValue )
		*pValue	=	dCI;
	StoreToCache( nIndex, pValue );
	return TRUE;
}
예제 #9
0
/***
	TP = (收盘价+收盘价+最高价+最低价)/4
	HLC = N日TP平均值
*/
BOOL CHLC::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );
	
	if( m_nDays > nIndex+1 )
		return FALSE;

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

	double	dMATP = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=0; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);
		double	dTP		= (kd.m_fHigh+kd.m_fLow+kd.m_fClose*2)/4.;
		dMATP	+=	dTP;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )	*pValue	=	dMATP / m_nDays;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}
	return FALSE;
}
예제 #10
0
/***
	DMH = N日内最高价大于昨日最高价日的 (最高价-昨日最高价)
	DML = N日内最低价小于昨日最低价日的 (昨日最低价-最低价)
	DMKI = DMH / (DMH+DML)
*/
BOOL CDMKI::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	dDMH = 0, dDML = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);
		KDATA	kdLast	=	m_pKData->ElementAt(k-1);
		if( kd.m_fHigh > kdLast.m_fHigh )
			dDMH	+=	(((double)kd.m_fHigh)-kdLast.m_fHigh);
		if( kd.m_fLow < kdLast.m_fLow )
			dDML	+=	(((double)kdLast.m_fLow)-kd.m_fLow);

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

	return FALSE;
}
예제 #11
0
/***
	     n日中上涨日成交量+1/2最近n日总成交量
	VR = ————————————---------—- ×100
	     n日中下跌日成交量+1/2最近n日总成交量
*/
BOOL CVR::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	dINTV = 0, dDETV = 0, dTV = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		double	dAmount	=	m_pKData->ElementAt(k).m_fVolume;
		if( m_pKData->MaindataAt(k) > m_pKData->MaindataAt(k-1) )
			dINTV	+=	dAmount;
		if( m_pKData->MaindataAt(k) < m_pKData->MaindataAt(k-1) )
			dDETV	+=	dAmount;
		dTV	+=	dAmount;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( dDETV + dTV/2 < 1e-4 )
				return FALSE;
			if( pValue )	*pValue	=	(dINTV + dTV/2) * 100 /(dDETV + dTV/2);
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #12
0
/***
	A = (今天最高 + 今天最低)÷ 2
	B = (前一天最高 + 前一天最低)÷2
	C = 今天最高 - 今天最低
	EM = (A-B)×C÷今天成交额
	EMV = 累计n天的EM值
*/
BOOL CEMV::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	dEMV = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);
		KDATA	kdLast	=	m_pKData->ElementAt(k-1);
		if( 0 == kd.m_fVolume )
			return FALSE;
		double	dDIF = 0;
		dDIF	=	(kd.m_fHigh+kd.m_fLow)/2 - (((double)kdLast.m_fHigh)+kdLast.m_fLow)/2;
		dEMV	+=	dDIF * (kd.m_fHigh-kd.m_fLow) / kd.m_fVolume;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )
				*pValue	=	dEMV / m_nDays;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #13
0
// 计算指标值和均值
BOOL CTechnique::CalculateMA( double * pValue, double * pMA, int nIndex, BOOL bUseLast, int nMADays )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( nMADays > nIndex+1 )
		return FALSE;

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

	double	dValue = 0, dMA = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=0; k-- )
	{
		double	dTemp = 0;
		if( Calculate( &dTemp, k, FALSE ) )
		{
			if( nIndex == k )
				dValue	=	dTemp;
			dMA	+=	dTemp;

			nCount	++;
			if( nCount == nMADays )
			{
				dMA	=	dMA / nMADays;
				if( pValue )	*pValue	=	dValue;
				if( pMA )		*pMA	=	dMA;
				StoreToCache( nIndex, pValue, pMA );
				return TRUE;
			}
		}
	}
	return FALSE;
}
예제 #14
0
/***
	A = 今最高 - 昨收盘
	B = 今最低 - 昨最低
	C = 今最高 - 昨最低
	D = 昨收盘 - 昨开盘
	E = 今收盘 - 昨收盘
	F = 今收盘 - 昨开盘
	G = 昨收盘 - 昨开盘
	X = E + 1/(2F) + G
	K = A、B二者之间较大者
	比较A、B、C三者的大小
		若A大,则R = A+1/(2B)+1/(4D)
		若B大,则R = B+1/(2A)+1/(4D)
		若C大,则R = C+1/(4D)
	L = 3
	SI = 50·X·K/(R·L)
	ASI = N日SI之和
*/
BOOL CASI::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	dASI = 0;
	double	A, B, C, D, E, F, G;
	double	R, X, K, SI;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		KDATA	kd		=	m_pKData->ElementAt(k);
		KDATA	kdLast	=	m_pKData->ElementAt(k-1);
		A	=	fabs(((double)kd.m_fHigh) - kdLast.m_fClose);
		B	=	fabs(((double)kd.m_fLow) - kdLast.m_fClose);
		C	=	fabs(((double)kd.m_fHigh) - kdLast.m_fLow);
		D	=	fabs(((double)kdLast.m_fClose) - kdLast.m_fOpen);
		E	=	((double)kd.m_fClose) - kdLast.m_fClose;
		F	=	((double)kd.m_fClose) - kd.m_fOpen;
		G	=	((double)kdLast.m_fClose) - kdLast.m_fOpen;

		if( fabs(A) < 1e-4 || fabs(B) < 1e-4 || fabs(D) < 1e-4 || fabs(F) < 1e-4 )
			continue;

		if( A >= B && A >= C )
			R	=	A + 1/(2*B) + 1/(4*D);
		else if( B >= A && B >= C )
			R	=	B + 1/(2*A) + 1/(4*D);
		else
			R	=	C + 1/(4*D);

		if( fabs(R) < 1e-4 )
			continue;

		X	=	E + 1/(2*F) + G;
		K	=	( A > B ? A : B );
		SI	=	X * K * 50 / (3*R);

		dASI	+=	SI;

		nCount	++;
		if( nCount == m_nDays )
		{
			if( pValue )	*pValue	=	dASI;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #15
0
// 是否顶背离
BOOL CTechnique::IsDeviateOnTop( int nIndex, double * pdValue1, double * pdValue2 )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( !m_pKData->IsNewValue( nIndex, TRUE, ITS_DAYS_DEVIATE ) )
		return FALSE;

	if( IsNewValue( nIndex, TRUE, ITS_DAYS_DEVIATE, pdValue1, pdValue2 ) )
		return FALSE;

	return TRUE;
}
예제 #16
0
/***
	成交量的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;
}
예제 #17
0
/***
	NVI初值 = 100
	如果今天成交量比昨日小 NVI = 前一日NVI + 100 * 涨跌幅 否则,NVI = 前一天NVI
*/
BOOL CNVI::Calculate( double * pValue, double *pMA, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	// Calculate
	if( m_nMADays > nIndex+1 )
		return FALSE;

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

	double	dValueNew = 0, dMANew = 0;
	if( bUseLast && pValue && pMA )
	{
		if( 0 == nIndex )
			dValueNew	=	100;
		else if( m_pKData->ElementAt(nIndex).m_fVolume < m_pKData->ElementAt(nIndex-1).m_fVolume
				&& m_pKData->MaindataAt(nIndex-1) > 1e-4 && m_pKData->MaindataAt(nIndex) > 1e-4 )
			dValueNew	=	(*pValue) * m_pKData->MaindataAt(nIndex) / m_pKData->MaindataAt(nIndex-1);
		else
			dValueNew	=	*pValue;
		dMANew	=	(*pMA) * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
		StoreToCache( nIndex, &dValueNew, &dMANew );
	}
	else
	{
		for( int k=0; k<=nIndex; k++ )
		{
			if( 0 == k )
				dValueNew	=	100;
			else if( m_pKData->ElementAt(k).m_fVolume < m_pKData->ElementAt(k-1).m_fVolume
					&& m_pKData->MaindataAt(k-1) > 1e-4 && m_pKData->MaindataAt(k) > 1e-4 )
				dValueNew	=	dValueNew * m_pKData->MaindataAt(k) / m_pKData->MaindataAt(k-1);

			if( 0 == k )
				dMANew	=	dValueNew;
			else
				dMANew	=	dMANew * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
			
			StoreToCache( k, &dValueNew, &dMANew );
		}
	}

	if( pValue )	*pValue	=	dValueNew;
	if( pMA )		*pMA	=	dMANew;
	return TRUE;
}
예제 #18
0
/***
	DIF1 = 今日最高价 - 2日前最高价
	DIF2 = 今日最低价 - 2日前最低价
	A = N日内除满足以下情况日的(DIF1+DIF2)之和
		1. 2日前最高价 小于 7日前收盘价
		2. 2日前最高价 小于 8日前收盘价
		3. 今日前最高价 小于 5日前最低价
		4. 今日前最高价 小于 6日前最低价
		5. 2日前最低价 小于 7日前收盘价
		6. 2日前最低价 小于 8日前收盘价
		7. 今日前最低价 小于 5日前最高价
		8. 今日前最低价 小于 6日前最高价
	REIA = N日的DIF1绝对值之和 + N日的DIF2绝对值之和
	REI  = A / REIA
*/
BOOL CREI::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nDays+7 > nIndex )
		return FALSE;

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

	double	dREI = 0, dREIA = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=8; k-- )
	{
		double	dDIF1 = 0, dDIF2 = 0;
		int		num1 = 1, num2 = 1;
		dDIF1	=	((double)m_pKData->ElementAt(k).m_fHigh) - m_pKData->ElementAt(k-2).m_fHigh;
		dDIF2	=	((double)m_pKData->ElementAt(k).m_fLow) - m_pKData->ElementAt(k-2).m_fLow;
		if( m_pKData->ElementAt(k-2).m_fHigh < m_pKData->ElementAt(k-7).m_fClose
			&& m_pKData->ElementAt(k-2).m_fHigh < m_pKData->ElementAt(k-8).m_fClose
			&& m_pKData->ElementAt(k).m_fHigh < m_pKData->ElementAt(k-5).m_fLow
			&& m_pKData->ElementAt(k).m_fHigh < m_pKData->ElementAt(k-6).m_fLow )
			num1	=	0;
		if( m_pKData->ElementAt(k-2).m_fLow > m_pKData->ElementAt(k-7).m_fClose
			&& m_pKData->ElementAt(k-2).m_fLow > m_pKData->ElementAt(k-8).m_fClose
			&& m_pKData->ElementAt(k).m_fLow > m_pKData->ElementAt(k-5).m_fHigh
			&& m_pKData->ElementAt(k).m_fLow > m_pKData->ElementAt(k-6).m_fHigh )
			num2	=	0;
		dREI	+=	(dDIF1+dDIF2) * num1 * num2;
		dREIA	+=	fabs(dDIF1) + fabs(dDIF2);

		nCount	++;
		if( nCount == m_nDays )
		{
			if( fabs(dREIA) < 1e-4 )
				return FALSE;
			if( pValue )
				*pValue	=	dREI / dREIA;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}
	
	return FALSE;
}
예제 #19
0
/***
	TP = (昨日收盘价+昨日收盘价+昨日最高价+昨日最低价)/4
	AH = TP + 昨日最高价 - 昨日最低价
	AL = TP - 最日最高价 + 昨日最低价
	NH = TP + TP - 最日最低价
	NL = TP + TP - 最日最高价
*/
BOOL CCDP::Calculate( double * pAH, double * pNH, double * pAL, double * pNL, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( nIndex < 1 )
		return FALSE;

	if( LoadFromCache( nIndex, pAH, pNH, pAL, pNL ) )
		return TRUE;

	KDATA	kdLast	=	m_pKData->ElementAt(nIndex-1);
	double	dTP	=	(kdLast.m_fHigh+kdLast.m_fLow+kdLast.m_fClose*2)/4.;
	if( pAH )	*pAH	=	(dTP + kdLast.m_fHigh - kdLast.m_fLow);
	if( pNH )	*pNH	=	(dTP + dTP - kdLast.m_fLow);
	if( pAL )	*pAL	=	(dTP - kdLast.m_fHigh + kdLast.m_fLow);
	if( pNL )	*pNL	=	(dTP - kdLast.m_fHigh + dTP);
	StoreToCache( nIndex, pAH, pNH, pAL, pNL );
	return TRUE;
}
예제 #20
0
/***
	*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;
}
예제 #21
0
/***
	VP = N日内成交量增加日的平均成交量
	VQ = N日内成交量减少日的平均成交量
	VRSI = 100 * VP / (VP+VQ)
*/
BOOL CVRSI::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	dVP = 0, dVQ = 0, dResult = 0;
	int	nCount = 0, p = 0, q = 0;
	for( int k=nIndex; k>=1; k-- )
	{
		if( m_pKData->MaindataAt(k) >= m_pKData->MaindataAt(k-1) )
		{
			dVP	+=	m_pKData->ElementAt(k).m_fVolume;
			p	++;
		}
		else
		{
			dVQ	+=	m_pKData->ElementAt(k).m_fVolume;
			q	++;
		}

		nCount	++;
		if( nCount == m_nDays )
		{
			if( p > 0 )	dVP	=	dVP / p;
			if( q > 0 )	dVQ	=	dVQ / q;
			if( dVQ < 1e-4 )
				dResult	=	100;
			else
				dResult	=	100 - 100. / (1 + dVP / dVQ);
			if( pValue )	*pValue	=	dResult;
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
	}

	return FALSE;
}
예제 #22
0
/***
	          今日成交量-n日前成交量
	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;
}
예제 #23
0
/***
	当日收盘价比前一日收盘价高,其成交量记为正数
	当日收盘价较前一日收盘价低,其成交量记为负数
	累计每日之正或负成交量,即得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;
}
예제 #24
0
/***
	         今日收盘 - N日前收盘
	PCNT = ———————————— × 100%
	              昨日收盘
*/
BOOL CPCNT::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;
	
	int	nDays	=	1;	//	same as ROC with m_nDays==1
	if( nDays > nIndex )
		return FALSE;

	double	dROC = 0;
	if( m_pKData->MaindataAt(nIndex-nDays) <= 0
		|| m_pKData->MaindataAt(nIndex) <= 0 )
		return FALSE;

	double	x	=	m_pKData->MaindataAt(nIndex);
	double	y	=	m_pKData->MaindataAt(nIndex-nDays);
	if( pValue )
		*pValue	=	(x - y) * 100 / y;
	StoreToCache( nIndex, pValue );
	return TRUE;
}
예제 #25
0
/***
	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;
}
예제 #26
0
BOOL CSAR::CalculateSAR( double * pValue, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nInitDays > nIndex + 1 )
		return FALSE;

	double	dResult	=	0;
	if( bUseLast && pValue && nIndex > 0 && !m_bTurn )
	{
		KDATA	kd	=	m_pKData->ElementAt(nIndex-1);
		if( m_bCurUp )
		{
			dResult	=	(*pValue) + m_dCurAF * (kd.m_fHigh - (*pValue) );
			if( kd.m_fHigh > m_dCurHigh )
			{
				m_dCurHigh	=	kd.m_fHigh;
				m_dCurAF	=	m_dCurAF + m_dAFStep;
				if( m_dCurAF > m_dAFMax )
					m_dCurAF	=	m_dAFMax;
			}
			if( m_pKData->ElementAt(nIndex).m_fLow < dResult )
				m_bTurn		=	TRUE;
		}
		else
		{
			dResult	=	(*pValue) - m_dCurAF * ((*pValue) - kd.m_fLow );
			if( kd.m_fLow < m_dCurLow )
			{
				m_dCurLow	=	kd.m_fLow;
				m_dCurAF	=	m_dCurAF + m_dAFStep;
				if( m_dCurAF > m_dAFMax )
					m_dCurAF	=	m_dAFMax;
			}
			if( m_pKData->ElementAt(nIndex).m_fHigh > dResult )
				m_bTurn		=	TRUE;
		}
	}
	else
	{
		for( int k=nIndex; k>=nIndex-m_nInitDays+1; k-- )
		{
			KDATA	kd	=	m_pKData->ElementAt(k);
			if( nIndex == k )
			{
				m_dCurHigh	=	kd.m_fHigh;
				m_dCurLow	=	kd.m_fLow;
			}
			else if( kd.m_fHigh > m_dCurHigh )
				m_dCurHigh	=	kd.m_fHigh;
			else if( kd.m_fLow < m_dCurLow )
				m_dCurLow	=	kd.m_fLow;
		}
		if( m_bTurn )
			m_bCurUp	=	! m_bCurUp;
		else
			m_bCurUp	=	m_bFirstUp;
		m_bTurn		=	FALSE;
		m_dCurAF	=	m_dAFStep;
		if( m_bCurUp )
			dResult	=	m_dCurLow;
		else
			dResult	=	m_dCurHigh;
	}

	if( pValue )
		*pValue	=	dResult;
	return TRUE;
}
예제 #27
0
// 将计算好的数据保存至缓冲区
BOOL CTechnique::StoreToCache( int nIndex, double * pValue1, double *pValue2, double *pValue3, double * pValue4, double * pValue5 )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( m_nLength <= 0 || m_nIndexStart < 0 )
	{
		m_nLength		=	( NULL!=m_pKData ? m_pKData->GetSize() : 0 );
		if( m_nLength > 0 )
			m_nIndexStart	=	0;
	}
	if( m_nLength <= 0 || m_nIndexStart <  0 )
		return FALSE;
	
	// Realocate
	if( pValue1 )
	{
		if( !m_pdCache1 )
			m_pdCache1		=	new double[m_nLength];
		if( !m_pbHasCache1 )
		{
			m_pbHasCache1	=	new BOOL[m_nLength];
			if( !m_pbHasCache1 )	return FALSE;
			for( int i=0; i<m_nLength; i++ )
				m_pbHasCache1[i]	=	FALSE;
		}
		if( NULL == m_pbHasCache1 || NULL == m_pdCache1 )
			return FALSE;
	}
	if( pValue2 )
	{
		if( !m_pdCache2 )
			m_pdCache2		=	new double[m_nLength];
		if( !m_pbHasCache2 )
		{
			m_pbHasCache2	=	new BOOL[m_nLength];
			if( !m_pbHasCache2 )	return FALSE;
			for( int i=0; i<m_nLength; i++ )
				m_pbHasCache2[i]	=	FALSE;
		}
		if( NULL == m_pbHasCache2 || NULL == m_pdCache2 )
			return FALSE;
	}
	if( pValue3 )
	{
		if( !m_pdCache3 )
			m_pdCache3		=	new double[m_nLength];
		if( !m_pbHasCache3 )
		{
			m_pbHasCache3	=	new BOOL[m_nLength];
			if( !m_pbHasCache3 )	return FALSE;
			for( int i=0; i<m_nLength; i++ )
				m_pbHasCache3[i]	=	FALSE;
		}
		if( NULL == m_pbHasCache3 || NULL == m_pdCache3 )
			return FALSE;
	}
	if( pValue4 )
	{
		if( !m_pdCache4 )
			m_pdCache4		=	new double[m_nLength];
		if( !m_pbHasCache4 )
		{
			m_pbHasCache4	=	new BOOL[m_nLength];
			if( !m_pbHasCache4 )	return FALSE;
			for( int i=0; i<m_nLength; i++ )
				m_pbHasCache4[i]	=	FALSE;
		}
		if( NULL == m_pbHasCache4 || NULL == m_pdCache4 )
			return FALSE;
	}
	if( pValue5 )
	{
		if( !m_pdCache5 )
			m_pdCache5		=	new double[m_nLength];
		if( !m_pbHasCache5 )
		{
			m_pbHasCache5	=	new BOOL[m_nLength];
			if( !m_pbHasCache5 )	return FALSE;
			for( int i=0; i<m_nLength; i++ )
				m_pbHasCache5[i]	=	FALSE;
		}
		if( NULL == m_pbHasCache5 || NULL == m_pdCache5 )
			return FALSE;
	}

	if( nIndex < m_nIndexStart || nIndex-m_nIndexStart>=m_nLength )
		return FALSE;

	// Store	
	if( pValue1 && m_pdCache1 && m_pbHasCache1 )
	{
		m_pdCache1[nIndex-m_nIndexStart]		=	*pValue1;
		m_pbHasCache1[nIndex-m_nIndexStart]		=	TRUE;
	}
	if( pValue2 && m_pdCache2 && m_pbHasCache2 )
	{
		m_pdCache2[nIndex-m_nIndexStart]		=	*pValue2;
		m_pbHasCache2[nIndex-m_nIndexStart]		=	TRUE;
	}
	if( pValue3 && m_pdCache3 && m_pbHasCache3 )
	{
		m_pdCache3[nIndex-m_nIndexStart]		=	*pValue3;
		m_pbHasCache3[nIndex-m_nIndexStart]		=	TRUE;
	}
	if( pValue4 && m_pdCache4 && m_pbHasCache4 )
	{
		m_pdCache4[nIndex-m_nIndexStart]		=	*pValue4;
		m_pbHasCache4[nIndex-m_nIndexStart]		=	TRUE;
	}
	if( pValue5 && m_pdCache5 && m_pbHasCache5 )
	{
		m_pdCache5[nIndex-m_nIndexStart]		=	*pValue5;
		m_pbHasCache5[nIndex-m_nIndexStart]		=	TRUE;
	}
	return TRUE;
}