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; }
BOOL CVOLUME::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax ) { STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd ); double dMin = 0; double dMax = 1; for( int k=nStart; k<=nEnd; k++ ) { KDATA & kd = m_pKData->ElementAt(k); if( dMax < kd.m_fVolume ) dMax = (double)kd.m_fVolume; } dMax = dMax + 1; if( dMax - dMin < 3 ) dMax = dMin + 3; if( pdMin ) *pdMin = dMin; if( pdMax ) *pdMax = dMax; return TRUE; }
/*** 得到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; }