📄 kdata.cpp
字号:
// 检查是否是相邻成交日
if( !IsAdjacentDays( nIndex, nDays ) )
return FALSE;
if( ElementAt(nIndex-nDays).m_fAmount < 1e-4 )
return FALSE;
if( pValue )
*pValue = (100. * ElementAt(nIndex).m_fClose) / ElementAt(nIndex-nDays).m_fClose - 100;
return TRUE;
}
BOOL CKData::GetScope( double * pValue, DWORD dateCur, int nDays )
{
SP_ASSERT( pValue && nDays > 0 );
// Find date Current to calculate from
int nIndex = GetIndexByDate( dateCur );
if( -1 == nIndex )
return FALSE;
// data not enough
if( nDays > nIndex )
return FALSE;
// 检查是否是相邻成交日
if( !IsAdjacentDays( nIndex, nDays ) )
return FALSE;
double dMax = 0, dMin = 0;
int nCount = 0;
for( int k=nIndex; k>=0; k-- )
{
if( nIndex == k )
{
dMin = ElementAt(k).m_fLow;
dMax = ElementAt(k).m_fHigh;
}
if( dMin > ElementAt(k).m_fLow ) dMin = ElementAt(k).m_fLow;
if( dMax < ElementAt(k).m_fHigh ) dMax = ElementAt(k).m_fHigh;
nCount ++;
if( nCount == nDays )
break;
}
// data not enough
if( nCount != nDays || nCount <= 0 )
return FALSE;
if( ElementAt(nIndex-nDays).m_fClose <= 0 )
return FALSE;
if( pValue )
*pValue = ( 100. * (dMax-dMin) ) / ElementAt(nIndex-nDays).m_fClose ;
return TRUE;
}
BOOL CKData::GetVolumeSum( double * pValue, DWORD dateCur, int nDays )
{
SP_ASSERT( pValue && nDays > 0 );
// Find date Current to calculate from
int nIndex = GetIndexByDate( dateCur );
if( -1 == nIndex )
return FALSE;
// data not enough
if( nDays > nIndex )
return FALSE;
// 检查是否是相邻成交日
if( !IsAdjacentDays( nIndex, nDays ) )
return FALSE;
// begin calculate
double dAll = 0;
int nCount = 0;
for( int i=nIndex; i>=0; i-- )
{
dAll += ElementAt(i).m_fVolume;
nCount ++;
if( nCount >= nDays )
break;
}
// data not enough
if( nCount != nDays || nCount <= 0 )
return FALSE;
if( pValue )
*pValue = dAll;
return TRUE;
}
BOOL CKData::GetRatioVolume( double * pValue, DWORD dateCur, int nDays )
{
SP_ASSERT( pValue && nDays > 0 );
// Find date Current to calculate from
int nIndex = GetIndexByDate( dateCur );
if( -1 == nIndex )
return FALSE;
// data not enough
if( nDays > nIndex )
return FALSE;
// 检查是否是相邻成交日
if( !IsAdjacentDays( nIndex, nDays ) )
return FALSE;
// begin calculate
double dAll = 0;
int nCount = 0;
for( int i=nIndex-1; i>=0; i-- )
{
dAll += ElementAt(i).m_fVolume;
nCount ++;
if( nCount >= nDays )
break;
}
// data not enough
if( nCount != nDays || nCount <= 0 )
return FALSE;
if( fabs(dAll) < 1 )
return FALSE;
if( pValue )
*pValue = (ElementAt(nIndex).m_fVolume / dAll ) * nCount;
return TRUE;
}
BOOL CKData::GetRS( double * pValue, DWORD dateCur, int nDays )
{
SP_ASSERT( pValue && nDays > 0 );
// Find date Current to calculate from
int nIndex = GetIndexByDate( dateCur );
if( -1 == nIndex )
return FALSE;
// data not enough
if( nDays > nIndex )
return FALSE;
// 检查是否是相邻成交日
if( !IsAdjacentDays( nIndex, nDays ) )
return FALSE;
int nCount = 0;
double dA = 0, dB = 0;
for( int k=nIndex; k>=1; k-- )
{
if( ElementAt(k).m_fClose > ElementAt(k-1).m_fClose )
dA += (ElementAt(k).m_fClose - ElementAt(k-1).m_fClose);
else
dB += (ElementAt(k-1).m_fClose - ElementAt(k).m_fClose);
nCount ++;
if( nCount == nDays )
{
double dResult;
if( fabs(dB) < 1e-4 )
dResult = 100;
else
dResult = dA / dB;
if( pValue )
*pValue = dResult;
return TRUE;
}
}
return FALSE;
}
BOOL CKData::GetMA( double * pValue, int nIndex, int nDays )
{
SP_ASSERT( nIndex >= 0 && nIndex < GetSize() && nDays > 0 );
if( nIndex < 0 || nIndex >=GetSize() || nDays <= 0 )
return FALSE;
int nCount = 0;
if( nDays > nIndex+1 )
return FALSE;
double dResult = 0;
for( int k=nIndex; k>=0; k-- )
{
dResult += MaindataAt(k);
nCount ++;
if( nCount == nDays )
{
if( pValue )
*pValue = dResult / nDays;
return TRUE;
}
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Private Operations
int CKData::ConvertKData( CKData &kdSrc, CKData &kdDest, int multiple )
{
// convert kdSrc k line to kdDest k line accordding to their multiple
SP_ASSERT( multiple > 1 );
if( multiple < 2 ) return 0;
kdDest.SetSize( 0, kdSrc.GetSize() / multiple + 5 );
int nStart = kdSrc.GetSize() % multiple;
int nCount = 0;
KDATA dataDest;
for( int pos=nStart; pos<kdSrc.GetSize(); pos++ )
{
KDATA & dataSrc = kdSrc.ElementAt( pos );
nCount ++;
if( 1 == nCount )
{
memcpy( &dataDest, &dataSrc, sizeof(dataDest) );
}
else
{
dataDest.m_fAmount += dataSrc.m_fAmount;
if( dataDest.m_fHigh < dataSrc.m_fHigh ) dataDest.m_fHigh = dataSrc.m_fHigh;
if( dataDest.m_fLow > dataSrc.m_fLow ) dataDest.m_fLow = dataSrc.m_fLow;
dataDest.m_fVolume += dataSrc.m_fVolume;
dataDest.m_fClose = dataSrc.m_fClose;
}
if( multiple == nCount ) // new dataDest is over
{
nCount = 0;
kdDest.Add( dataDest );
}
}
return kdDest.GetSize();
}
void CKData::CopyData( const CKData &src )
{
if( m_pDataOriginal )
{
delete [] (BYTE*)m_pDataOriginal;
m_pDataOriginal = NULL;
m_nSizeOriginal = m_nMaxSizeOriginal = 0;
}
if( m_pData )
{
delete [] (BYTE*)m_pData;
m_pData = NULL;
m_nSize = m_nMaxSize = m_nGrowBy = 0;
}
if( src.m_nSizeOriginal > 0 )
{
SP_ASSERT( src.m_pDataOriginal );
SP_ASSERT( src.m_nMaxSizeOriginal >= src.m_nSizeOriginal );
m_pDataOriginal = (KDATA*) new BYTE[src.m_nMaxSizeOriginal * sizeof(KDATA)];
if( m_pDataOriginal )
{
memset( m_pDataOriginal, 0, src.m_nMaxSizeOriginal * sizeof(KDATA) ); // zero fill
memcpy( m_pDataOriginal, src.m_pDataOriginal, src.m_nSizeOriginal * sizeof(KDATA) );
m_nSizeOriginal = src.m_nSizeOriginal;
m_nMaxSizeOriginal = src.m_nMaxSizeOriginal;
}
}
if( src.m_nSize > 0 )
{
SP_ASSERT( src.m_pData );
SP_ASSERT( src.m_nMaxSize >= src.m_nSize );
m_pData = (KDATA*) new BYTE[src.m_nMaxSize * sizeof(KDATA)];
if( m_pData )
{
memset( m_pData, 0, src.m_nMaxSize * sizeof(KDATA) ); // zero fill
memcpy( m_pData, src.m_pData, src.m_nSize * sizeof(KDATA) );
m_nSize = src.m_nSize;
m_nMaxSize = src.m_nMaxSize;
}
}
}
void CKData::LoadDataOriginal( )
{
if( m_pDataOriginal )
{
if( m_pData )
delete [] (BYTE*)m_pData;
m_pData = m_pDataOriginal;
m_nSize = m_nSizeOriginal;
m_nMaxSize = m_nMaxSizeOriginal;
m_pDataOriginal = NULL;
m_nSizeOriginal = m_nMaxSizeOriginal = 0;
}
}
void CKData::StoreDataOriginal( )
{
if( NULL == m_pDataOriginal )
{
m_pDataOriginal = m_pData;
m_nSizeOriginal = m_nSize;
m_nMaxSizeOriginal = m_nMaxSize;
m_pData = NULL;
m_nSize = m_nMaxSize = 0;
}
}
float CKData::GetRatio( float fLastClose, DRDATA & dr )
{
if( fLastClose < 1e-4 )
return 1.0000;
float fRatio = 1.0000;
if( dr.m_fProfit > 1e-4 )
{
fRatio = fRatio * ( 1 - dr.m_fProfit/fLastClose );
}
if( dr.m_fGive > 1e-4 )
{
fRatio = (float)( fRatio * 1./(1.+dr.m_fGive) );
}
if( dr.m_fPei > 1e-4 )
{
float priceNow = (float)( (dr.m_fPeiPrice * dr.m_fPei + fLastClose)/(1.+dr.m_fPei) );
fRatio = fRatio * priceNow / fLastClose;
}
return fRatio;
}
void CKData::ConvertXDR( BOOL bUP, DWORD dateAutoDRBegin, double dAutoDRLimit )
{
CDRData drtemp;
drtemp = m_drdata;
drtemp.Sort( );
if( m_pData )
{
delete [] (BYTE*)m_pData;
m_nSize = m_nMaxSize = 0;
m_pData = NULL;
}
if( NULL == m_pDataOriginal || 0 == m_nSizeOriginal )
return;
/* if( drtemp.GetSize() == 0 )
{
SetSize( m_nSizeOriginal );
if( m_pData )
memcpy( m_pData, m_pDataOriginal, sizeof(KDATA)*m_nSize );
return;
}
*/
dAutoDRLimit = dAutoDRLimit / 100;
if( bUP )
{
SetSize( 0, m_nSizeOriginal );
int drPos = 0;
float fRatio = 1.000000;
for( int i=0; i<m_nSizeOriginal; i++ )
{
KDATA & kd = m_pDataOriginal[i];
KDATA newkd = kd;
if( drPos < drtemp.GetSize() && ToDayDate(kd.m_date) >= drtemp.ElementAt(drPos).m_date )
{
if( i > 0 )
{
KDATA kdLast = m_pDataOriginal[i-1];
fRatio = fRatio * GetRatio( kdLast.m_fClose, drtemp.ElementAt(drPos) );
}
drPos ++;
}
else if( ToDayDate(kd.m_date) >= dateAutoDRBegin && i > 0 ) // Auto XDR
{
KDATA kdLast = m_pDataOriginal[i-1];
if( kdLast.m_fClose > 1e-4 && kd.m_fOpen < kdLast.m_fClose
&& fabs(kd.m_fOpen/kdLast.m_fClose-1) > dAutoDRLimit )
fRatio = fRatio * kd.m_fOpen / kdLast.m_fClose;
}
newkd.m_fOpen = (kd.m_fOpen / fRatio);
newkd.m_fHigh = (kd.m_fHigh / fRatio);
newkd.m_fLow = (kd.m_fLow / fRatio);
newkd.m_fClose = (kd.m_fClose / fRatio);
newkd.m_fVolume = (kd.m_fVolume * fRatio);
Add( newkd );
}
}
else
{
SetSize( m_nSizeOriginal );
int drPos = drtemp.GetSize()-1;
float fRatio = 1.000000;
for( int i=m_nSizeOriginal-1; i>=0; i-- )
{
KDATA & kd = m_pDataOriginal[i];
KDATA newkd = kd;
if( drPos >= 0 && ToDayDate(kd.m_date) < drtemp.ElementAt(drPos).m_date )
{
if( i < m_nSizeOriginal-1 )
fRatio = fRatio * GetRatio( kd.m_fClose, drtemp.ElementAt(drPos) );
drPos --;
}
else if( ToDayDate(kd.m_date) >= dateAutoDRBegin && i+1 < m_nSizeOriginal ) // Auto XDR
{
KDATA kdNext = m_pDataOriginal[i+1];
if( kdNext.m_fOpen > 1e-4 && kdNext.m_fOpen < kd.m_fClose
&& fabs(kdNext.m_fOpen/kd.m_fClose-1) > dAutoDRLimit )
fRatio = fRatio * kdNext.m_fOpen / kd.m_fClose;
}
newkd.m_fOpen = (kd.m_fOpen * fRatio);
newkd.m_fHigh = (kd.m_fHigh * fRatio);
newkd.m_fLow = (kd.m_fLow * fRatio);
newkd.m_fClose = (kd.m_fClose * fRatio);
newkd.m_fVolume = (kd.m_fVolume / fRatio);
SetAt( i, newkd );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -