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

📄 techswing.cpp

📁 股软 通达信行情接收接口, 包括美元汇率
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}

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

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

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

	double	dMTM, dMA;
	if( !Calculate( &dMTM, &dMA, nIndex, FALSE ) )
		return ITS_NOTHING;

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

	return	ITS_NOTHING;
}

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

/***
	MTM = C/Cn
	其中:C为当日收市价,Cn为N日前收市价,
	N为设定参数,一般选设10日,亦可在6日至14日之间选择。
*/
BOOL CMTM::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->MaindataAt(nIndex-m_nDays) > 0 )
	{
		if( pValue )
			*pValue	=	100. * m_pKData->MaindataAt(nIndex) / m_pKData->MaindataAt(nIndex-m_nDays);
		StoreToCache( nIndex, pValue );
		return TRUE;
	}
	return FALSE;
}

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

//////////////////////////////////////////////////////////////////////
//	CDMI
CDMI::CDMI( )
{
	SetDefaultParameters( );
	m_pdDMICache		=	NULL;
	m_pnDMICacheIndex	=	NULL;
	m_nDMICacheCurrent	=	-1;
}

CDMI::CDMI( CKData * pKData )
	: CTechnique( pKData )
{
	SetDefaultParameters( );
	m_pdDMICache		=	NULL;
	m_pnDMICacheIndex	=	NULL;
	m_nDMICacheCurrent	=	-1;
}

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

void CDMI::SetDefaultParameters( )
{
	m_nDays			=	7;
}

void CDMI::AttachParameters( CDMI & src )
{
	m_nDays			=	src.m_nDays;
}

BOOL CDMI::IsValidParameters( )
{
	return ( VALID_DAYS(m_nDays) );
}

void CDMI::Clear( )
{
	CTechnique::Clear( );

	if( m_pdDMICache )
	{
		delete	[]	m_pdDMICache;
		m_pdDMICache	=	NULL;
	}
	if( m_pnDMICacheIndex )
	{
		delete	[]	m_pnDMICacheIndex;
		m_pnDMICacheIndex	=	NULL;
	}
	m_nDMICacheCurrent	=	-1;
}

/***
	求出真正波幅TR,TR是下列三者中绝对值最大的一个:
		昨收盘-今 最高、昨收盘-今最低、今最高-今最低
	
	+DM = 今最高-昨最高
	-DM = 昨最低-今最低
*/
BOOL CDMI::CalculateDM( double *pDMPlus, double *pDMMinus, double *pTR, int nIndex )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );

	if( nIndex < 1 )
		return FALSE;

	double	dDMPlus = 0, dDMMinus = 0, dTR = 0;
	KDATA	kdNow	=	m_pKData->ElementAt(nIndex);
	KDATA	kdLast	=	m_pKData->ElementAt(nIndex-1);

	dDMPlus		=	max( 0, ((double)kdNow.m_fHigh) - kdLast.m_fHigh );
	dDMMinus	=	max( 0, ((double)kdLast.m_fLow) - kdNow.m_fLow );

	dTR	=	max( fabs(((double)kdNow.m_fClose)-kdNow.m_fLow), fabs(((double)kdNow.m_fHigh)-kdLast.m_fClose) );
	dTR	=	max( dTR, fabs(((double)kdNow.m_fLow)-kdLast.m_fClose) );

	if( pDMPlus )	*pDMPlus	=	dDMPlus;
	if( pDMMinus )	*pDMMinus	=	dDMMinus;
	if( pTR )		*pTR		=	dTR;
	return TRUE;
}

/***
	TRn = N天TR之和
	+DMn = N天+DM之和
	-DMn = N天-DM之和
	+DI = (+DMn ÷ TRn)×100
	-DI = (-DMn ÷ TRn)×100
	DI差 = +DI-(-DI)
	DI和 = +DI+(-DI)
	DX = (DI差÷DI和)×100
*/
BOOL CDMI::CalculateDIDX( double *pDIPlus, double *pDIMinus, double *pDX, int nIndex, int nDays )
{
	STT_ASSERT_CALCULATE( m_pKData, nIndex, nDays );
	
	if( m_nDays > nIndex )
		return FALSE;

	double	dDX, dADX = 0;
	double	dDIPlus = 0, dDIMinus = 0, dTRSum = 0;
	int	nCount	=	0;
	for( int k=nIndex; k>=1; k-- )
	{
		double	dDMPlus = 0, dDMMinus = 0, dTR = 0;
		if( !CalculateDM( &dDMPlus, &dDMMinus, &dTR, k ) )
			return FALSE;

		dDIPlus		+=	dDMPlus;
		dDIMinus	+=	dDMMinus;
		dTRSum		+=	dTR;

		nCount	++;
		if( nCount == nDays )
		{
			if( fabs(dTRSum) < 1e-4 || fabs(dDIPlus+dDIMinus) < 1e-4 )
				return FALSE;
			dDIPlus		=	(dDIPlus * 100/dTRSum);
			dDIMinus	=	(dDIMinus * 100/dTRSum);
			dDX	=	fabs(dDIPlus-dDIMinus) * 100 / (dDIPlus+dDIMinus);
			if( pDIPlus )	*pDIPlus	=	dDIPlus;
			if( pDIMinus )	*pDIMinus	=	dDIMinus;
			if( pDX )	*pDX	=	dDX;
			return TRUE;
		}
	}
	return FALSE;
}

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

	if( nIndex <= 0 )
		return ITS_NOTHING;

	double	dDIPlus, dDIMinus, dADX, dADXR;
	double	dDIPlusLast, dDIMinusLast, dADXLast, dADXRLast;
	if( !Calculate( &dDIPlusLast, &dDIMinusLast, &dADXLast, &dADXRLast, nIndex-1, FALSE )
		|| !Calculate( &dDIPlus, &dDIMinus, &dADX, &dADXR, nIndex, FALSE ) )
		return ITS_NOTHING;

	if( dDIPlusLast < dDIMinusLast && dDIPlus > dDIMinus )
	{
		if( pnCode )	*pnCode	=	ITSC_GOLDENFORK;
		return m_itsGoldenFork;
	}
	if( dDIMinusLast < dDIPlusLast && dDIMinus > dDIPlus )
	{
		if( pnCode )	*pnCode	=	ITSC_DEADFORK;
		return m_itsDeadFork;
	}
*/
	// 无买卖信号
	return	ITS_NOTHING;
}

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

/***
	求出真正波幅TR,TR是下列三者中绝对值最大的一个:
		昨收盘-今 最高、昨收盘-今最低、今最高-今最低
	
	+DM = 今最高-昨最高
	-DM = 昨最低-今最低

	TRn = N天TR之和
	+DMn = N天+DM之和
	-DMn = N天-DM之和
	+DI = (+DMn ÷ TRn)×100
	-DI = (-DMn ÷ TRn)×100
	DI差 = +DI-(-DI)
	DI和 = +DI+(-DI)
	DX = (DI差÷DI和)×100

	ADX = DX的平滑均值
	ADXR = ADX的均值
*/
BOOL CDMI::Calculate( double * pDIPlus, double * pDIMinus, double *pADX, double *pADXR, int nIndex, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE1( m_pKData, nIndex );
	
	if( m_nDays > nIndex )
		return FALSE;

	if( LoadFromCache( nIndex, pDIPlus, pDIMinus, pADX, pADXR ) )
		return TRUE;

	double	dDX = 0, dADX = 0, dADXR = 0;
	if( !CalculateDIDX( pDIPlus, pDIMinus, &dDX, nIndex, m_nDays ) )
		return FALSE;

	if( NULL == m_pdDMICache )
	{
		m_pdDMICache		=	new double[m_nDays];
		m_pnDMICacheIndex	=	new	int[m_nDays];
		if( NULL == m_pdDMICache || NULL == m_pnDMICacheIndex )
			return FALSE;
		for( int i=0; i<m_nDays; i++ )
			m_pnDMICacheIndex[i]	=	-1;
		m_nDMICacheCurrent	=	-1;
	}

	if( bUseLast && pADX )
	{
		// Calculate ADX and ADXR
		dADX	=	( (m_nDays-1)*(*pADX) + dDX ) / m_nDays;
		for( int i=0; i<m_nDays; i++ )
		{
			if( m_pnDMICacheIndex[i] == nIndex-m_nDays )
			{
				dADXR	=	(m_pdDMICache[i] + dADX) / 2;
				break;
			}
		}

		// Save ADX to cache
		m_nDMICacheCurrent	++;
		if( m_nDMICacheCurrent < 0 || m_nDMICacheCurrent >= m_nDays )
			m_nDMICacheCurrent	=	0;
		m_pdDMICache[m_nDMICacheCurrent]	=	dADX;
		m_pnDMICacheIndex[m_nDMICacheCurrent]	=	nIndex;

		if( pADX )	*pADX	=	dADX;
		if( pADXR )	*pADXR	=	dADXR;
		StoreToCache( nIndex, pDIPlus, pDIMinus, pADX, pADXR );
		return TRUE;
	}
	else
	{
		double	factor = 1;
		int k;
		for( k=nIndex; k > 0; k-- )
		{
			factor	*=	((double)(m_nDays-1))/m_nDays;
			if( factor < 0.001 )
				break;
		}
		double	dADXLast = 0;
		BOOL	bHasADXR = FALSE;
		for( ; k<=nIndex; k++ )
		{
			if( !CalculateDIDX( NULL, NULL, &dDX, k, m_nDays ) )
				continue;

			// Calculate ADX and ADXR
			dADX	=	( (m_nDays-1)*dADX + dDX )/m_nDays;
			if( k == nIndex-m_nDays )
			{
				dADXLast	=	dADX;
				bHasADXR	=	TRUE;
			}

			// Save ADX to cache
			m_nDMICacheCurrent	++;
			if( m_nDMICacheCurrent < 0 || m_nDMICacheCurrent >= m_nDays )
				m_nDMICacheCurrent	=	0;
			m_pdDMICache[m_nDMICacheCurrent]	=	dADX;
			m_pnDMICacheIndex[m_nDMICacheCurrent]	=	k;
		}
		dADXR	=	(dADX + dADXLast) / 2;
		if( pADX )				*pADX	=	dADX;
		if( pADXR && bHasADXR )	*pADXR	=	dADXR;
		StoreToCache( nIndex, pDIPlus, pDIMinus, pADX, pADXR );
		return TRUE;
	}
	return FALSE;
}

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

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

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

void CROC::SetDefaultParameters( )
{
	m_nDays		=	10;
	m_nMADays	=	10;

	m_itsGoldenFork			=	ITS_BUY;
	m_itsDeadFork			=	ITS_SELL;
}

void CROC::AttachParameters( CROC & src )
{
	m_nDays		=	src.m_nDays;
	m_nMADays	=	src.m_nMADays;

	m_itsGoldenFork			=	src.m_itsGoldenFork;
	m_itsDeadFork			=	src.m_itsDeadFork;
}

BOOL CROC::IsValidParameters( )
{
	return ( VALID_DAYS(m_nDays) && VALID_DAYS(m_nMADays)
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}

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

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

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

	double	dROC, dMA;
	if( !Calculate( &dROC, &dMA, nIndex, FALSE ) )
		return ITS_NOTHING;

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

	return	ITS_NOTHING;
}

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

/***
	ROC=(今收盘-前N日收盘)÷前N日的收盘×100 
*/
BOOL CROC::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->MaindataAt(nIndex-m_nDays) <= 0
		|| m_pKData->MaindataAt(nIndex) <= 0 )
		return FALSE;

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

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

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

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

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

void CCCI::SetDefaultParameters( )
{
	m_nDays		=	14;
	m_dQuotiety	=	0.015;
	m_nMADays	=	10;

	m_itsGoldenFork	=	ITS_BUY;
	m_itsDeadFork	=	ITS_SELL;
}

void CCCI::AttachParameters( CCCI & src )
{
	m_nDays		=	src.m_nDays;
	m_dQuotiety	=	src.m_dQuotiety;
	m_nMADays	=	src.m_nMADays;

	m_itsGoldenFork	=	src.m_itsGoldenFork;
	m_itsDeadFork	=	src.m_itsDeadFork;
}

BOOL CCCI::IsValidParameters( )
{
	return ( VALID_DAYS(m_nDays) && m_dQuotiety > 0 && VALID_DAYS(m_nMADays)
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}

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

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

	double	dCCI;
	if( !Calculate( &dCCI, nIndex, FALSE ) )
		return ITS_NOTHING;

	int	nForkSignal	=	GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );

	if( dCCI < -100 && nForkSignal == m_itsGoldenFork )
	{	// 低位金叉
		if( pnCode )	*pnCode	=	ITSC_GOLDENFORK;
		return m_itsGoldenFork;
	}
	if( dCCI > 100 && nForkSignal == m_itsDeadFork )
	{	// 高位死叉
		if( pnCode )	*pnCode	=	ITSC_DEADFORK;
		return m_itsDeadFork;
	}

	return	ITS_NOTHING;
}

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

/***
	TP = 收盘价+收盘价+最高价+最低价
	A是TP的N日均值
	D是TP与A的离差均值
	CCI=(C-D)/(0.015D)
*/
BOOL CCCI::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	dTP = 0, dMATP = 0, dD = 0;
	int	nCount	=	0, k=0;
	for(  k=nIndex; k>=0; k-- )
	{
		KDATA	kd	=	m_pKData->ElementAt(k);
		double	dTemp	=	(kd.m_fHigh+kd.m_fClose+kd.m_fClose+kd.m_fLow)/4;
		if( nIndex == k )
			dTP	=	dTemp;
		dMATP	+=	dTemp;

		nCount	++;
		if( nCount == m_nDays )
			break;
	}
	dMATP	=	dMATP / m_nDays;

	nCount	=	0;
	for(  k=nIndex; k>=0; k-- )
	{
		KDATA	kd	=	m_pKData->ElementAt(k);
		double	dTemp	=	(kd.m_fHigh+kd.m_fClose+kd.m_fClose+kd.m_fLow)/4;
		dD		+=	fabs(dTemp-dMATP);

		nCount	++;
		if( nCount == m_nDays )
			break;
	}

	dD	=	dD / m_nDays;
	if( fabs(dD) < 1e-4 )
		return FALSE;
	if( pValue )

⌨️ 快捷键说明

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