📄 kdata.cpp
字号:
m_nKType = ktypeWeek;
else if( elapse < 4320000 )
m_nKType = ktypeWeek;
}
}
int CKData::GetKType( ) { return m_nKType; }
int CKData::GetCurFormat( ) { return m_nCurFormat; }
void CKData::SetMaindataType( int type ) { m_nCurMaindataType = type; }
int CKData::GetMaindataType( ) { return m_nCurMaindataType; }
void CKData::SetDRData( CDRData &drdata ) { m_drdata = drdata; }
CDRData &CKData::GetDRData( ) { return m_drdata; }
void CKData::ChangeCurFormat( int format, DWORD dateAutoDRBegin, double dAutoDRLimit )
{
SP_ASSERT( GetKType() != ktypeMonth && GetKType() != ktypeWeek );
if( m_nCurFormat == format )
return;
switch( format )
{
case formatOriginal:
LoadDataOriginal( );
m_nCurFormat = format;
break;
case formatXDRup:
StoreDataOriginal( );
ConvertXDR( TRUE, dateAutoDRBegin, dAutoDRLimit );
m_nCurFormat = format;
break;
case formatXDRdown:
StoreDataOriginal( );
ConvertXDR( FALSE, dateAutoDRBegin, dAutoDRLimit );
m_nCurFormat = format;
break;
default:
SP_ASSERT( FALSE );
}
}
void CKData::Clear( )
{
if( m_pDataOriginal )
{
delete [] (BYTE*)m_pDataOriginal;
m_pDataOriginal = NULL;
}
if( m_pData )
{
delete [] (BYTE*)m_pData;
m_pData = NULL;
}
m_nKType = ktypeDay;
m_nCurFormat= formatOriginal;
m_nCurMaindataType = mdtypeClose;
m_pDataOriginal = NULL;
m_nSizeOriginal = m_nMaxSizeOriginal = 0;
m_pData = NULL;
m_nSize = m_nMaxSize = m_nGrowBy = 0;
}
int CKData::CompareLatestDate( CKData &kd )
{
// compare this kdata with kd's latest time
int nYearThis, nMonthThis, nDayThis, nHourThis, nMinuteThis;
int nYear, nMonth, nDay, nHour, nMinute;
LatestDate( nYearThis, nMonthThis, nDayThis, nHourThis, nMinuteThis );
kd.LatestDate( nYear, nMonth, nDay, nHour, nMinute );
if( nYearThis > nYear || nMonthThis > nMonth || nDayThis > nDay
|| nHourThis > nHour || nMinuteThis > nMinute )
return 1;
if( nYearThis < nYear || nMonthThis < nMonth || nDayThis < nDay
|| nHourThis < nHour || nMinuteThis < nMinute )
return -1;
return 0;
}
int CKData::Min5ToMin15( CKData &kdm5, CKData &kdm15 )
{
SP_ASSERT( ktypeMin5 == kdm5.GetKType() );
SP_ASSERT( ktypeMin15 == kdm15.GetKType() );
return ConvertKData( kdm5, kdm15, 3 );
}
int CKData::Min5ToMin30( CKData &kdm5, CKData &kdm30 )
{
SP_ASSERT( ktypeMin5 == kdm5.GetKType() );
SP_ASSERT( ktypeMin30 == kdm30.GetKType() );
return ConvertKData( kdm5, kdm30, 6 );
}
int CKData::Min5ToMin60( CKData &kdm5, CKData &kdm60 )
{
SP_ASSERT( ktypeMin5 == kdm5.GetKType() );
SP_ASSERT( ktypeMin60 == kdm60.GetKType() );
return ConvertKData( kdm5, kdm60, 12 );
}
int CKData::DayToMonth( CKData &kdday, CKData &kdmonth )
{
// convert day k line to month k line
SP_ASSERT( ktypeDay == kdday.GetKType() );
SP_ASSERT( ktypeMonth == kdmonth.GetKType() );
kdmonth.SetSize( 0, kdday.GetSize() / 20 + 5 );
int nStart = kdday.GetSize() % 3;
int nCount = 0;
KDATA dataDest;
memset( &dataDest, 0, sizeof(dataDest) );
int nYearCur = 0, nMonthCur = 0 ;
for( int pos=nStart; pos<kdday.GetSize(); pos++ )
{
KDATA & dataSrc = kdday.ElementAt( pos );
CSPTime tm;
if( !tm.FromStockTimeDay(dataSrc.m_date) )
continue;
int nYear = tm.GetYear();
int nMonth = tm.GetMonth();
if( nYear != nYearCur || nMonth != nMonthCur ) // a new month
{
if( 0 != pos )
kdmonth.Add( dataDest ); // add a month
memcpy( &dataDest, &dataSrc, sizeof(dataDest) ); // begin a new month
nYearCur = nYear;
nMonthCur = nMonth;
}
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( pos == kdday.GetSize()-1 ) // the latest one
kdmonth.Add( dataDest );
}
return kdmonth.GetSize();
}
int CKData::DayToWeek( CKData &kdday, CKData &kdweek )
{
// convert day k line to week k line
SP_ASSERT( ktypeDay == kdday.GetKType() );
SP_ASSERT( ktypeWeek == kdweek.GetKType() );
kdweek.SetSize( 0, kdday.GetSize() / 5 + 5 );
int nStart = kdday.GetSize() % 3;
int nCount = 0;
KDATA dataDest;
memset( &dataDest, 0, sizeof(dataDest) );
for( int pos=nStart; pos<kdday.GetSize(); pos++ )
{
KDATA & dataSrc = kdday.ElementAt( pos );
CSPTime tm;
if( !tm.FromStockTimeDay(dataSrc.m_date) )
continue;
if( tm.GetDayOfWeek() == 2 ) // a new week
{
if( 0 != pos )
kdweek.Add( dataDest ); // add a week
memcpy( &dataDest, &dataSrc, sizeof(dataDest) ); // begin a new week
}
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( pos == kdday.GetSize()-1 ) // the latest one
kdweek.Add( dataDest );
}
return kdweek.GetSize();
}
DWORD CKData::ToDayDate( DWORD date )
{
switch( GetKType() )
{
case ktypeMin60:
case ktypeMin30:
case ktypeMin15:
case ktypeMin5:
return (date / 10000 + 1990 * 10000);
default:
return date;
}
}
int CKData::MergeKData( CKData * pother )
{
if( !pother || pother->GetSize() == 0 )
return 0;
if( GetKType() != pother->GetKType() )
return 0;
if( GetSize() == 0 )
{
CopyData( *pother );
return GetSize();
}
int nCount = 0;
SetSize( GetSize(), pother->GetSize()+1 );
for( int i=0; i<pother->GetSize(); i++ )
{
KDATA kdnew = pother->ElementAt(i);
if( kdnew.m_fClose < 1e-4 || kdnew.m_fOpen < 1e-4 || kdnew.m_fHigh < 1e-4 || kdnew.m_fLow < 1e-4 )
continue;
int j;
for( j=0; j<GetSize(); j++ )
{
if( kdnew.m_date == ElementAt(j).m_date )
{
SetAt(j,kdnew);
break;
}
if( kdnew.m_date < ElementAt(j).m_date )
{
InsertAt(j,kdnew);
break;
}
}
if( GetSize() == j )
Add( kdnew );
nCount ++;
}
return nCount;
/* The Old Version
if( !pother || pother->GetSize() == 0 )
return GetSize();
if( GetKType() != pother->GetKType() )
return GetSize();
if( GetSize() == 0 )
{
CopyData( *pother );
return GetSize();
}
int nLen = GetSize();
int nLenOther = pother->GetSize();
SP_ASSERT( 0 != nLen && 0 != nLenOther );
if( ElementAt(nLen-1).m_date < pother->ElementAt(0).m_date )
CopyData( *pother );
// else if( ElementAt(0).m_date > pother->ElementAt(nLenOther-1).m_date )
// ;
// else if( ElementAt(0).m_date <= pother->ElementAt(0).m_date
// && ElementAt(nLen-1).m_date >= pother->ElementAt(nLenOther-1).m_date )
// ;
else if( ElementAt(0).m_date > pother->ElementAt(0).m_date
&& ElementAt(nLen-1).m_date < pother->ElementAt(nLenOther-1).m_date )
CopyData( *pother );
else if( ElementAt(0).m_date <= pother->ElementAt(0).m_date
&& ElementAt(nLen-1).m_date < pother->ElementAt(nLenOther-1).m_date )
{
// append from pother
DWORD date = ElementAt(nLen-1).m_date;
SetSize( GetSize(), pother->GetSize() );
for( int i=0; i<pother->GetSize(); i++ )
{
KDATA & kd = pother->ElementAt(i);
if( kd.m_date > m_data )
Add( kd );
}
}
else if( ElementAt(0).m_date >= pother->ElementAt(0).m_date
&& ElementAt(nLen-1).m_date > pother->ElementAt(nLenOther-1).m_date )
{
// insert from pother
CKData temp = (*pother);
DWORD date = pother->ElementAt(nLenOther-1).m_date;
temp.SetSize( temp.GetSize(), GetSize()+5 );
for( int i=0; i<GetSize(); i++ )
{
KDATA & kd = ElementAt(i);
if( kd.m_date > date )
temp.Add( kd );
}
CopyData( temp );
}
return GetSize();
*/
}
int CKData::FullFillKData( CKData & kdataMain, BOOL bFillToEnd )
{
SP_ASSERT( GetKType() == kdataMain.GetKType() );
if( GetKType() != kdataMain.GetKType() )
return 0;
if( GetSize() == 0 || kdataMain.GetSize() == 0 )
return 0;
DWORD dateBegin = ElementAt(0).m_date;
DWORD dateMainEnd5 = (kdataMain.GetSize() >= 5 ? kdataMain.ElementAt(kdataMain.GetSize()-5).m_date : 0);
DWORD dateEnd5 = (GetSize() >= 5 ? ElementAt(GetSize()-5).m_date : 0);
int iMain = 0, iSelf = 0;
for( iMain=0; iMain<kdataMain.GetSize(); iMain ++ )
{
if( dateBegin == kdataMain.ElementAt(iMain).m_date )
break;
}
SetSize( GetSize(), kdataMain.GetSize()-iMain-GetSize() > 0 ? kdataMain.GetSize()-iMain-GetSize() : -1 );
int nCount = 0;
for( ; iMain <= kdataMain.GetSize() && iSelf <= GetSize(); iMain++, iSelf++ )
{
if( !bFillToEnd && iSelf == GetSize() && ElementAt(iSelf-1).m_date < dateMainEnd5 )
break;
if( !bFillToEnd && iMain == kdataMain.GetSize() && kdataMain.ElementAt(iMain-1).m_date < dateEnd5 )
break;
while( iMain > 0 && iMain <= kdataMain.GetSize() && iSelf < GetSize()
&& ( iMain == kdataMain.GetSize() || kdataMain.ElementAt(iMain).m_date > ElementAt(iSelf).m_date ) )
{
// KDATA kd;
// memset( &kd, 0, sizeof(kd) );
// kd.m_date = ElementAt(iSelf).m_date;
// kd.open = kd.high = kd.low = kd.close = kdataMain.ElementAt(iMain-1).close;
// kdataMain.InsertAt( iMain, kd );
// iMain ++;
iSelf ++;
// nCount ++;
}
while( iMain < kdataMain.GetSize() && iSelf <= GetSize() && iSelf > 0
&& ( iSelf == GetSize() || kdataMain.ElementAt(iMain).m_date < ElementAt(iSelf).m_date ) )
{
KDATA kd;
memset( &kd, 0, sizeof(kd) );
kd.m_date = kdataMain.ElementAt(iMain).m_date;
kd.m_fOpen = kd.m_fHigh = kd.m_fLow = kd.m_fClose = ElementAt(iSelf-1).m_fClose;
InsertAt( iSelf, kd );
iMain ++;
iSelf ++;
nCount ++;
}
}
return nCount;
}
BOOL CKData::IsAdjacentDays( int nIndex, int nDays )
{
// check parameters
SP_ASSERT( nIndex >= 0 && nIndex < GetSize() && nDays >= 1 );
if( nIndex < 0 || nIndex >= GetSize() || nDays < 1 )
return FALSE;
// data not enougy
if( nDays > nIndex )
return FALSE;
CSPTime sptime1, sptime2;
sptime1.FromStockTime( ElementAt(nIndex-nDays).m_date, CKData::IsDayOrMin(m_nKType) );
sptime1.FromStockTime( ElementAt(nIndex).m_date, CKData::IsDayOrMin(m_nKType) );
if( CKData::ktypeMonth == m_nKType )
{
if( sptime2 - sptime1 >= CSPTimeSpan(nDays+63,0,0,0) )
return FALSE;
}
else if( CKData::ktypeWeek == m_nKType )
{
if( sptime2 - sptime1 >= CSPTimeSpan(nDays+15,0,0,0) )
return FALSE;
}
else
{
if( sptime2 - sptime1 >= CSPTimeSpan(nDays+8,0,0,0) )
return FALSE;
}
return TRUE;
}
BOOL CKData::GetDiff( 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;
if( ElementAt(nIndex-nDays).m_fClose < 1e-4 )
return FALSE;
if( pValue )
*pValue = ElementAt(nIndex).m_fClose - ElementAt(nIndex-nDays).m_fClose;
return TRUE;
}
BOOL CKData::GetDiffPercent( 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -