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

📄 techkline.cpp.svn-base

📁 股票软件源码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
		&& VALID_ITS(m_itsBuy) && VALID_ITS(m_itsSell) );
}

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

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

int CSAR::GetSignal( int nIndex, UINT * pnCode )
{
	if( pnCode )	*pnCode	=	ITSC_NOTHING;
	Clear( );
	double dValue;
	if( !Calculate( &dValue, nIndex, FALSE ) )
		return ITS_NOTHING;

	if( m_bTurn && !m_bCurUp )
	{	// 反转向上
		if( pnCode )	*pnCode	=	ITSC_LONG;
		return m_itsBuy;
	}
	if( m_bTurn && m_bCurUp )
	{	// 反转向下
		if( pnCode )	*pnCode	=	ITSC_SHORT;
		return m_itsSell;
	}
	return	ITS_NOTHING;
}

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

/***
	计算SAR值
	先选定时间,判断价格是在上涨还是在下跌。
	若是看涨,则进场第一天的SAR必须是近期内的最低价,是看跌 则进场第一天的SAR必须是近期内的最高价。
	本处为缺省定义为看涨。

	进场第二天的SAR则为第一天的最高价(看涨时)或最低价(看跌时)与第一天的SAR的差距乘上调整系数,
	再加上第一天的SAR就可求得。
	按逐步递推的方法,每日的SAR可归纳如下: SAR(N)= SAR(N-1)+ AF * [ EP(N-1)-SAR(N-1)]
	其中SAR(N)为第N日的SAR值,AF是调整系数,EP为极点价
	
	第一个调整系数AF为0.02,若每隔一天的最高价比前一天的最高价还高,则AF递增0.02,若未创新高,
则AF沿用前一天的数值,但调整系数最高不超过0.2。
	若是买进期间,计算出某日的SAR比当日或前一日的最低价还高,则应以当日或者前一日的最低价为某日之SAR,
卖出期间也对应服从类似原则。
*/
BOOL CSAR::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
	if( LoadFromCache( nIndex, pValue ) )
		return TRUE;

	if( bUseLast && pValue && nIndex > 0 )
	{
		if( CalculateSAR( pValue, nIndex, bUseLast ) )
		{
			StoreToCache( nIndex, pValue );
			return TRUE;
		}
		return FALSE;
	}
	else
	{
		double	dResult;
		BOOL	bHasLast	=	FALSE;
		for( int k=0; k<=nIndex; k++ )
		{
			if( CalculateSAR( &dResult, k, bHasLast ) )
			{
				bHasLast	=	TRUE;
				StoreToCache( k, &dResult );
			}
		}
		if( !bHasLast )
			return FALSE;
		if( pValue )
			*pValue	=	dResult;
		return TRUE;
	}
}

//////////////////////////////////////////////////////////////////////
//	CDJ
CStock		CDJ::m_stockSha;
CStock		CDJ::m_stockSzn;
CSPString	CDJ::m_strCodeOrg;
CDJ::CDJ( )
{
	SetDefaultParameters( );
}

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

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

void CDJ::SetDefaultParameters( )
{
	m_strCodeSha	=	STKLIB_CODE_MAIN;
	m_strCodeSzn	=	STKLIB_CODE_MAINSZN;
}

void CDJ::AttachParameters( CDJ & src )
{
	m_strCodeSha	=	src.m_strCodeSha;
	m_strCodeSzn	=	src.m_strCodeSzn;
}

BOOL CDJ::IsValidParameters( )
{
	return ( m_strCodeSha.GetLength() > 0 && m_strCodeSzn.GetLength() > 0 );
}

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

/***
	K线叠加图,准备叠加K线的数据
*/
BOOL CDJ::PrepareStockData(CStDatabase * pDatabase, const char * szCodeOrg,
						   int nCurKType, int nCurKFormat, int nCurMaindataType,
						   DWORD dwAutoResumeDRBegin, int nAutoResumeDRLimit )
{
	SP_ASSERT( pDatabase );

	// bReload and kdayMain
	BOOL	bReload	=	(NULL!=szCodeOrg && 0!=strncmp(szCodeOrg,m_strCodeOrg,m_strCodeOrg.GetLength()) );
	m_strCodeOrg	=	szCodeOrg;

	// m_stockSha
	m_stockSha.SetStockCode( CStock::marketSHSE, m_strCodeSha );
	AfxPrepareStockData( pDatabase, m_stockSha, nCurKType, nCurKFormat, nCurMaindataType, FALSE, bReload );

	// m_stockSzn
	m_stockSzn.SetStockCode( CStock::marketSZSE, m_strCodeSzn );
	AfxPrepareStockData( pDatabase, m_stockSzn, nCurKType, nCurKFormat, nCurMaindataType, FALSE, bReload );
	
	return TRUE;
}

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

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

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

void CCW::SetDefaultParameters( )
{
	m_dChangeHand	=	1.5;
}

void CCW::AttachParameters( CCW & src )
{
	m_dChangeHand	=	src.m_dChangeHand;
}

BOOL CCW::IsValidParameters( )
{
	return ( m_dChangeHand > 0 );
}

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

/***
	根据换手率m_dChangeHand和终止日,计算起始日
*/
BOOL CCW::GetRange( int & nStart, int & nEnd, CStockInfo & info )
{
	if( !m_pKData || m_pKData->GetSize() <= 0 )
		return FALSE;
	if( nEnd < 0 || nEnd >= m_pKData->GetSize() )
		nEnd	=	m_pKData->GetSize()-1;
	
	BOOL	bIndex = FALSE;
	double	dShareCurrency = 0;
	if( !info.GetShareCurrency( &dShareCurrency ) || dShareCurrency < 1e+6 )
		bIndex	=	TRUE;

	if( bIndex )
		dShareCurrency	=	100 * m_dChangeHand;
	else
		dShareCurrency	*=	m_dChangeHand;

	double	dVol	=	0;
	int k;
	for( k=nEnd; k>=0; k-- )
	{
		if( bIndex )
			dVol	+=	1;
		else
			dVol	+=	m_pKData->ElementAt(k).m_fVolume;

		if( dVol > dShareCurrency )
			break;
	}
	nStart	=	k;
	if( nStart < 0 )
		nStart	=	0;
	return TRUE;
}

BOOL CCW::GetMinMaxInfo(int nStart, int nEnd, double dMinPrice, double dMaxPrice, double dStep,
				double *pdMinVolume, double *pdMaxVolume )
{
	STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
	if( dMinPrice >= dMaxPrice || dStep < 1e-4 )
		return FALSE;

	double	dMinVolume = 0, dMaxVolume = 0, dVolume = 0;
	BOOL	bFirst	=	TRUE;
	for( double dPrice = dMinPrice; dPrice < dMaxPrice; dPrice += dStep )
	{
		if( CalculateCW( &dVolume, nStart, nEnd, dPrice, dStep ) )
		{
			if( bFirst || dVolume < dMinVolume )	dMinVolume	=	dVolume;
			if( bFirst || dVolume > dMaxVolume )	dMaxVolume	=	dVolume;
			bFirst	=	FALSE;
		}
	}

	dMinVolume	-=	fabs(dMinVolume)*0.01;
	dMaxVolume	+=	fabs(dMaxVolume)*0.01;
	if( dMaxVolume - dMinVolume < 3 )
		dMaxVolume	=	dMinVolume + 3;
	if( pdMinVolume )		*pdMinVolume	=	dMinVolume;
	if( pdMaxVolume )		*pdMaxVolume	=	dMaxVolume;

	return !bFirst;
}

/***
	筹码分布图,计算价格区间包括dPrice的日线的成交量
*/
BOOL CCW::CalculateCW( double *pdVolume, int nStart, int nEnd, double dPrice, double dStep )
{
	STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );

	double	dVolume	=	0;
	for( int k=nStart; k<=nEnd; k++ )
	{
		KDATA	kd	=	m_pKData->ElementAt(k);
		if( kd.m_fHigh-kd.m_fLow > 1e-4
			&& kd.m_fLow < dPrice && kd.m_fHigh > dPrice )
		{
			// 均匀分布 dVolAve
			double	dVolAve = kd.m_fVolume;
			if( dStep < kd.m_fHigh-kd.m_fLow )
				dVolAve	=	kd.m_fVolume * dStep / (kd.m_fHigh-kd.m_fLow);

			// 三角分布
			double	dFactor	=	min(dPrice-kd.m_fLow, kd.m_fHigh-dPrice);
			dVolume	+=	dVolAve * dFactor * 4 / (kd.m_fHigh-kd.m_fLow);
		}
	}
	
	if( pdVolume )
		*pdVolume	=	dVolume;
	return TRUE;
}

/***
	筹码分布图计算,计算筹码分布
*/
BOOL CCW::CalculateCW(	int nStart, int nEnd, CStockInfo & info, double dStep,
						CSPDWordArray & adwPrice, CSPDWordArray & adwVolume,
						double * pdMinVolume, double * pdMaxVolume, double * pdTotalVolume, double * pdVolPercent )
{
	STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
	if( dStep < 1e-4 )
		return FALSE;

	float dMinPrice = 0, dMaxPrice = 0;
	if( !m_pKData->GetMinMaxInfo( nStart, nEnd, &dMinPrice, &dMaxPrice ) )
		return FALSE;

	// Calculate
	int nMaxCount = (int)((dMaxPrice-dMinPrice)/dStep) + 10;
	adwPrice.SetSize( 0, nMaxCount );
	adwVolume.SetSize( 0, nMaxCount );
	double	dMinVolume = 0, dMaxVolume = 0, dTotalVolume = 0, dVolume = 0;
	BOOL	bFirst	=	TRUE;
	for( double dPrice = dMinPrice; dPrice < dMaxPrice; dPrice += dStep )
	{
		if( CalculateCW( &dVolume, nStart, nEnd, dPrice, dStep ) )
		{
			if( bFirst || dVolume < dMinVolume )	dMinVolume	=	dVolume;
			if( bFirst || dVolume > dMaxVolume )	dMaxVolume	=	dVolume;
			adwPrice.Add( DWORD(dPrice * 1000) );
			adwVolume.Add( DWORD(dVolume) );
			dTotalVolume	+=	dVolume;
			bFirst	=	FALSE;
		}
	}

	// Return
	// Min Max
	dMinVolume	-=	fabs(dMinVolume)*0.01;
	dMaxVolume	+=	fabs(dMaxVolume)*0.01;
	if( dMaxVolume - dMinVolume < 3 )
		dMaxVolume	=	dMinVolume + 3;
	if( pdMinVolume )	*pdMinVolume	=	dMinVolume;
	if( pdMaxVolume )	*pdMaxVolume	=	dMaxVolume;
	if( pdTotalVolume )	*pdTotalVolume	=	dTotalVolume;

	// VolPercent
	double dVolPercent = 1.0;
	double	dShareCurrency = 0;
	if( (!info.GetShareCurrency( &dShareCurrency ) || dShareCurrency < 1e+6) && nEnd-nStart+1 > 0 )
		dShareCurrency	=	dTotalVolume * 100 / (nEnd-nStart+1);
	if( dShareCurrency > 1e-4 )
		dVolPercent	=	dTotalVolume / (dShareCurrency*m_dChangeHand);
	if( dVolPercent > 1.0 )		dVolPercent	=	1.0;
	if( dVolPercent < 0.0 )		dVolPercent	=	0.0;
	if( pdVolPercent )	*pdVolPercent	=	dVolPercent;

	return adwPrice.GetSize() > 0;
}

/***
	筹码分布图计算,计算最近nDays天内的筹码分布
*/
BOOL CCW::CalculateRecentCW(int nEnd, int nDays, CStockInfo & info, double dStep,
						CSPDWordArray & adwPrice, CSPDWordArray & adwVolume,
						double * pdMinVolume, double * pdMaxVolume, double * pdTotalVolume, double * pdVolPercent )
{
	// Prepare
	if( !m_pKData || m_pKData->GetSize() <= 0 )
		return FALSE;
	if( nEnd < 0 || nEnd >= m_pKData->GetSize() )
		nEnd	=	m_pKData->GetSize()-1;
	int	nStart = nEnd - nDays + 1;
	if( nStart < 0 || nStart >= m_pKData->GetSize() )
		return FALSE;

	return CalculateCW( nStart, nEnd, info, dStep, adwPrice, adwVolume, pdMinVolume, pdMaxVolume, pdTotalVolume, pdVolPercent );
}

/***
	筹码分布图计算,计算nDays天前内的筹码分布
*/
BOOL CCW::CalculatePastCW(int nEnd, int nDays, CStockInfo & info, double dStep,
						CSPDWordArray & adwPrice, CSPDWordArray & adwVolume,
						double * pdMinVolume, double * pdMaxVolume, double * pdTotalVolume, double * pdVolPercent )
{
	// Prepare
	if( !m_pKData || m_pKData->GetSize() <= 0 )
		return FALSE;
	if( nEnd < 0 || nEnd >= m_pKData->GetSize() )
		nEnd	=	m_pKData->GetSize()-1;
	int	nStart = nEnd - nDays;
	if( nStart < 0 || nStart >= m_pKData->GetSize() )
		return FALSE;

	nEnd = nStart;
	if( !GetRange( nStart, nEnd, info ) )
		return FALSE;

	BOOL bOK = CalculateCW( nStart, nEnd, info, dStep, adwPrice, adwVolume, pdMinVolume, pdMaxVolume, pdTotalVolume, pdVolPercent );

	// TotalVolumeRecent
	double dTotalVolumeRecent = 0;
	for( int k=nEnd+1; k<=nEnd+nDays && k<m_pKData->GetSize(); k ++ )
		dTotalVolumeRecent	+=	m_pKData->ElementAt(k).m_fVolume;

	// VolPercent
	double dVolPercent = 1.0;
	double	dShareCurrency = 0;
	if( (!info.GetShareCurrency( &dShareCurrency ) || dShareCurrency < 1e+6) && nDays > 0 )
		dShareCurrency	=	dTotalVolumeRecent * 100 / nDays;
	if( dShareCurrency > 1e-4 )
		dVolPercent	=	dTotalVolumeRecent / (dShareCurrency*m_dChangeHand);
	dVolPercent	=	1.0 - dVolPercent;
	if( dVolPercent > 1.0 )		dVolPercent	=	1.0;
	if( dVolPercent < 0.0 )		dVolPercent	=	0.0;
	if( pdVolPercent )	*pdVolPercent	=	dVolPercent;

	return bOK;
}

/***
	筹码分布图统计,获利比例统计
*/
BOOL CCW::StatGainPercent( double *pdGainPercent, CSPDWordArray &adwPrice, CSPDWordArray &adwVolume, double dPriceSel )
{
	double dTotalVolume = 0;
	double dGainVolume = 0;
	for( int k=0; k<adwPrice.GetSize() && k<adwVolume.GetSize(); k++ )
	{
		dTotalVolume	+=	adwVolume[k];
		if( adwPrice[k] * 0.001 <= dPriceSel )
			dGainVolume	+=	adwVolume[k];
	}

	double dGainPercent = 0;
	if( dTotalVolume > 1e-4 )
		dGainPercent	=	dGainVolume / dTotalVolume;

	if( pdGainPercent )	*pdGainPercent = dGainPercent;
	return TRUE;
}

/***
	筹码分布图统计,平均成本统计
*/
BOOL CCW::StatCostAverage( double *pdCostAve, CSPDWordArray &adwPrice, CSPDWordArray &adwVolume )
{
	double dTotalVolume = 0;
	double dTotalCost = 0;
	for( int k=0; k<adwPrice.GetSize() && k<adwVolume.GetSize(); k++ )
	{
		dTotalVolume	+=	adwVolume[k];
		dTotalCost		+=	0.001 * adwPrice[k] * adwVolume[k];
	}

	double dCostAve = 0;
	if( dTotalVolume > 1e-4 )
		dCostAve	=	dTotalCost / dTotalVolume;

	if( pdCostAve )	*pdCostAve = dCostAve;
	return TRUE;
}
	
/***
	筹码分布图统计,集中度统计
*/
BOOL CCW::StatMass( double *pdLower, double *pdUpper, double *pdMassPrice, CSPDWordArray &adwPrice, CSPDWordArray &adwVolume, double dMassVol )
{
	if( adwPrice.GetSize() != adwVolume.GetSize() || dMassVol < 0 || dMassVol > 1 )
		return FALSE;

	double dTotalVolume = 0;
	for( int k=0; k<adwPrice.GetSize() && k<adwVolume.GetSize(); k++ )
		dTotalVolume	+=	adwVolume[k];

	if( dTotalVolume > 1e-4 )
	{
		double dUpperVolume = dTotalVolume * (1-dMassVol) * 0.5;
		double dLowerVolume = dUpperVolume;
		int nLower = 0, nUpper = adwPrice.GetSize()-1;

		int k;
		for( k=0; k<adwPrice.GetSize(); k++ )
		{
			dLowerVolume -= (double)adwVolume[k];
			if( dLowerVolume < 0 )
				break;
		}
		nLower	=	k;

		for( k=adwPrice.GetSize()-1; k>=0; k-- )
		{
			dUpperVolume -= (double)adwVolume[k];
			if( dUpperVolume < 0 )
				break;
		}
		nUpper	=	k;
		
		if( nLower < 0 || nLower > nUpper || nUpper >= adwPrice.GetSize() )
			return FALSE;

		double dLower = 0.001 * adwPrice[nLower];
		double dUpper = 0.001 * adwPrice[nUpper];
		if( pdLower )	*pdLower	=	dLower;
		if( pdUpper )	*pdUpper	=	dUpper;
		if( pdMassPrice && adwPrice.GetSize() >= 2 )
		{
			double dPriceRange = 0.001 * ((double)adwPrice[adwPrice.GetSize()-1] - (double)adwPrice[0]);
			if( dPriceRange > 1e-4 )
				*pdMassPrice	=	(dUpper-dLower)/dPriceRange;
			if( *pdMassPrice < 0 )	*pdMassPrice	=	0;
			if( *pdMassPrice > 1 )	*pdMassPrice	=	1;
		}
	}

	return TRUE;
}

⌨️ 快捷键说明

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