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

📄 techkline.cpp.svn-base

📁 股票软件源码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*
	Cross Platform Core Code.

	Copyright(R) 2001-2002 Balang Software.
	All rights reserved.

*/

#include	"StdAfx.h"
#include	"../Include/Stock.h"
#include	"../Include/Technique.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifdef	_DEBUG
#define	new	DEBUG_NEW
#endif

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

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

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

void CKLine::SetDefaultParameters( )
{
}

void CKLine::AttachParameters( CKLine & src )
{
}

BOOL CKLine::IsValidParameters( )
{
	return TRUE;
}

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

/***
	得到K线价格的从nStart到nEnd的最小值和最大值
*/
BOOL CKLine::GetMinMaxInfo( int nStart, int nEnd, double *pdMin, double *pdMax )
{
	STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );

	double	dMin	=	-1;
	double	dMax	=	1;
	for( int k=nStart; k<=nEnd; k++ )
	{
		KDATA	& kd	=	m_pKData->ElementAt(k);
		if( nStart == k || dMin > kd.m_fLow )	dMin	=	(double)kd.m_fLow;
		if( nStart == k || dMax < kd.m_fHigh )	dMax	=	(double)kd.m_fHigh;
	}
	dMin	-=	fabs(dMin) * 0.01;
	dMax	+=	fabs(dMax) * 0.01;
	if( dMin <= 0 )
		dMin	=	0;
	if( dMax - dMin < 0.03 )
		dMax	=	dMin + 0.03;

	if( pdMin )		*pdMin	=	dMin;
	if( pdMax )		*pdMax	=	dMax;
	return TRUE;
}

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

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

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

void CMA::SetDefaultParameters( )
{
	m_nType	=	typeMA;
	m_adwMADays.RemoveAll();
	m_adwMADays.Add( 5 );
	m_adwMADays.Add( 10 );
	m_adwMADays.Add( 20 );
	m_itsGoldenFork	=	ITS_BUYINTENSE;
	m_itsDeadFork	=	ITS_SELLINTENSE;
	m_itsLong		=	ITS_BUY;
	m_itsShort		=	ITS_SELL;
}

void CMA::AttachParameters( CMA & src )
{
	m_nType	=	src.m_nType;
	m_adwMADays.Copy( src.m_adwMADays );
	m_itsGoldenFork	=	src.m_itsGoldenFork;
	m_itsDeadFork	=	src.m_itsDeadFork;
	m_itsLong		=	src.m_itsLong;
	m_itsShort		=	src.m_itsShort;
}

BOOL CMA::IsValidParameters( )
{
	STT_VALID_DAYSARRAY( m_adwMADays );
	return ( (typeMA == m_nType || typeEXPMA == m_nType)
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork)
		&& VALID_ITS(m_itsLong) && VALID_ITS(m_itsShort) );
}

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

int CMA::GetSignal( int nIndex, UINT * pnCode )
{
	// 金叉或者死叉
	int	nSignal	=	GetForkSignal( nIndex, m_adwMADays, m_itsGoldenFork, m_itsDeadFork, pnCode );
	if( ITS_ISBUY(nSignal) || ITS_ISSELL(nSignal) )
		return nSignal;
	// 趋势
	return GetTrendIntensity( nIndex, m_adwMADays, m_itsLong, m_itsShort, pnCode );
}

BOOL CMA::GetMinMaxInfo(int nStart, int nEnd,
				   double *pdMin, double *pdMax )
{
	return AfxGetMinMaxInfo( nStart, nEnd, pdMin, pdMax, this, m_adwMADays );
}

/***
	两种:
	1. MA
	    MA = n日收盘价的平均值	
	2. EXPMA
	    EXPMA(1) = CLOSE(1)
		EXPMA(i) = (1-α)EXPMA(i-1) + αCLOSE(i)
		其中 α = 2 / (n+1)
*/
BOOL CMA::Calculate( double * pValue, int nIndex, int nDays, BOOL bUseLast )
{
	STT_ASSERT_CALCULATE( m_pKData, nIndex, nDays );

	int	nCount	=	0;
	if( nDays > nIndex+1 )
		return FALSE;

	double	dResult	=	0;
	int	k = 0;
	switch( m_nType )
	{
	case typeMA:
		return m_pKData->GetMA( pValue, nIndex, nDays );
		break;
	case typeEXPMA:
		if( bUseLast && pValue )
		{
			if( 0 == nIndex )
				dResult	=	m_pKData->MaindataAt(nIndex);
			else
				dResult	=	(*pValue)*(nDays-1)/(nDays+1) + m_pKData->MaindataAt(nIndex) * 2./(nDays+1);
		}
		else
		{
			for( k=0; k<=nIndex; k++ )
			{
				if( 0 == k )
					dResult	=	m_pKData->MaindataAt(k);
				else
					dResult	=	dResult*(nDays-1)/(nDays+1) + m_pKData->MaindataAt(k) * 2./(nDays+1);
			}
		}
		if( pValue )
			*pValue	=	dResult;
		break;
	default:
		SP_ASSERT( FALSE );
	}
	return TRUE;
}

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

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

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

void CBBI::SetDefaultParameters( )
{
	m_nMA1Days	=	3;
	m_nMA2Days	=	6;
	m_nMA3Days	=	12;
	m_nMA4Days	=	24;
	m_itsGoldenFork	=	ITS_BUY;
	m_itsDeadFork	=	ITS_SELL;
}

void CBBI::AttachParameters( CBBI & src )
{
	m_nMA1Days	=	src.m_nMA1Days;
	m_nMA2Days	=	src.m_nMA2Days;
	m_nMA3Days	=	src.m_nMA3Days;
	m_nMA4Days	=	src.m_nMA4Days;
	m_itsGoldenFork	=	src.m_itsGoldenFork;
	m_itsDeadFork	=	src.m_itsDeadFork;
}

BOOL CBBI::IsValidParameters( )
{
	return ( VALID_DAYS( m_nMA1Days ) && VALID_DAYS( m_nMA2Days )
		&& VALID_DAYS( m_nMA3Days ) && VALID_DAYS( m_nMA4Days )
		&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}

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

int CBBI::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;
	if( nIndex <= 0 )
		return ITS_NOTHING;

	double	dLiminalLow = 0, dLiminalHigh = 0;
	if( !IntensityPreparePrice( nIndex, pnCode, 0, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.4, 0.6 ) )
		return ITS_NOTHING;

	double	dBBINow = 0, dBBILast = 0;
	if( !Calculate( &dBBILast, nIndex-1, FALSE )
		|| !Calculate( &dBBINow, nIndex, FALSE ) )
		return ITS_NOTHING;

	double	dNowHigh	=	m_pKData->ElementAt(nIndex).m_fHigh;
	double	dNowLow		=	m_pKData->ElementAt(nIndex).m_fLow;
	double	dNowClose	=	m_pKData->ElementAt(nIndex).m_fClose;
	double	dLastHigh	=	m_pKData->ElementAt(nIndex-1).m_fHigh;
	double	dLastLow	=	m_pKData->ElementAt(nIndex-1).m_fLow;
	double	dLastClose	=	m_pKData->ElementAt(nIndex-1).m_fClose;

	if( dNowClose < dLiminalLow && dLastLow < dBBILast && dNowLow > dBBINow )
	{	// 低位趋势向上
		if( pnCode )	*pnCode	=	ITSC_GOLDENFORK;
		return m_itsGoldenFork;
	}
	if( dNowClose > dLiminalHigh && dLastHigh > dBBILast && dNowHigh < dBBINow )
	{	// 高位趋势向下
		if( pnCode )	*pnCode	=	ITSC_DEADFORK;
		return m_itsDeadFork;
	}
	return	ITS_NOTHING;
}

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

/***
	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;
}

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

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

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

void CBOLL::SetDefaultParameters( )
{
	m_dMultiUp		=	2;
	m_dMultiDown	=	2;
	m_nMADays		=	20;
	m_itsSupport	=	ITS_BUY;
	m_itsResistance	=	ITS_SELL;
}

void CBOLL::AttachParameters( CBOLL & src )
{
	m_dMultiUp		=	src.m_dMultiUp;
	m_dMultiDown	=	src.m_dMultiDown;
	m_nMADays		=	src.m_nMADays;
	m_itsSupport	=	src.m_itsSupport;
	m_itsResistance	=	src.m_itsResistance;
}

BOOL CBOLL::IsValidParameters( )
{
	return ( m_dMultiUp > 0 && m_dMultiDown > 0 && VALID_DAYS( m_nMADays )
		&& VALID_ITS(m_itsSupport) && VALID_ITS(m_itsResistance) );
}

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

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

	double	dMA = 0, dUp = 0, dDown = 0;
	if( !Calculate( &dMA, &dUp, &dDown, nIndex, FALSE ) )
		return ITS_NOTHING;

	double	dClose	=	m_pKData->ElementAt(nIndex).m_fClose;

	if( dClose < dDown )
	{	// 跌破支撑位
		if( pnCode )	*pnCode	=	ITSC_SUPPORT;
		return m_itsSupport;
	}
	if( dClose > dUp )
	{	// 涨过阻力位
		if( pnCode )	*pnCode	=	ITSC_RESISTANCE;
		return m_itsResistance;
	}
	return	ITS_NOTHING;
}

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

/***
	布林带是以股价平均线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;
}

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

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

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

void CPV::SetDefaultParameters( )
{
}

void CPV::AttachParameters( CPV & src )
{
}

BOOL CPV::IsValidParameters( )
{
	return TRUE;
}

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

int CPV::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;
	// 无买卖信号
	return	ITS_NOTHING;
}

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

/***
	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;
}

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

CSAR::CSAR( CKData * pKData )
	: CTechnique( pKData )
{
	SetDefaultParameters( );

	m_bCurUp	=	m_bFirstUp;
	m_bTurn		=	FALSE;
	m_dCurAF	=	m_dAFStep;
	m_dCurHigh	=	-1;
	m_dCurLow	=	-1;
}

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

void CSAR::SetDefaultParameters( )
{
	m_nInitDays	=	4;
	m_bFirstUp	=	TRUE;
	m_dAFStep	=	0.02;
	m_dAFMax	=	0.2;
	m_itsBuy	=	ITS_BUY;
	m_itsSell	=	ITS_SELL;
}

void CSAR::AttachParameters( CSAR & src )
{
	m_nInitDays	=	src.m_nInitDays;
	m_bFirstUp	=	src.m_bFirstUp;
	m_dAFStep	=	src.m_dAFStep;
	m_dAFMax	=	src.m_dAFMax;
	m_itsBuy	=	src.m_itsBuy;
	m_itsSell	=	src.m_itsSell;
}

BOOL CSAR::IsValidParameters( )
{
	return ( VALID_DAYS(m_nInitDays) && m_bFirstUp >= 0 && m_dAFStep > 0 && m_dAFMax > 0

⌨️ 快捷键说明

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