/* * 功能: 计算指标值 * nID: 指标标识,介于 0 <= nID < GetTechUserCount() * pInfo: 计算数据,参数,并返回计算结果信息 * 返回值:TRUE成功,FALSE失败 */ TECHUSER_API BOOL WINAPI Calculate( UINT nID, PCALCULATE_INFO pInfo ) { CKData * pKData = pInfo->m_pKData; int nIndex = pInfo->m_nIndex; switch( nID ) { case 0: { // 10日OSC指标 double dCt = pKData->ElementAt(nIndex).m_fClose; double dMA = 0; int nCount = 0; for( int k=nIndex; k>=0; k-- ) { dMA += pKData->ElementAt(k).m_fClose; nCount ++; if( nCount == 10 ) { dMA = dMA / 10; if( dMA < 1e-4 ) return FALSE; pInfo->m_dValue1 = (dCt/dMA); return TRUE; } } return FALSE; } default:; } return FALSE; }
LRESULT CDownloadDlg::OnStkReceiverData(WPARAM wParam, LPARAM lParam) { PCOMMPACKET pCommPacket = (PCOMMPACKET)lParam; switch( wParam ) { case CStock::dataReport: if( pCommPacket && CStock::dataReport == pCommPacket->m_dwDataType && pCommPacket->m_dwCount > 0 ) { m_nReportCount += pCommPacket->m_dwCount; for( DWORD i=0; i<pCommPacket->m_dwCount; i++ ) { CKData kdata; kdata.SetKType( CKData::ktypeDay ); KDATA kd; if( UpdateKDATAByREPORT( kd, &(pCommPacket->m_pReport[i]) ) ) { kdata.Add( kd ); AfxGetDB().InstallKData( kdata, FALSE ); } } CStockContainer & container = AfxGetStockContainer(); if( m_nReportRequestSent - m_nReportCount < 64 && m_nReportRequestSent < (UINT)container.GetSize() ) { container.Lock(); m_nReportRequestSent += AfxGetStkReceiver().RequestStockData( CStock::dataReport, container.GetData()+m_nReportRequestSent, min(160,container.GetSize()-m_nReportRequestSent), 0, 0 ); container.UnLock(); } if( !m_bReportFinished && m_nReportCount > 0.95 * m_nReportTotal ) { m_bReportFinished = TRUE; ::SendMessage( GetSafeHwnd(), WM_USER_DOWNLOAD_PROGRESS, STKLIB_MAX_PROGRESS, NULL ); AfxBeginThread( DownloadMain, (LPVOID)m_pDownloadInfo,THREAD_PRIORITY_NORMAL); } else if( !m_bReportFinished && m_nReportTotal > 0 ) { DWORD dwProgress = STKLIB_MAX_PROGRESS * m_nReportCount / m_nReportTotal; ::SendMessage( GetSafeHwnd(), WM_USER_DOWNLOAD_PROGRESS, dwProgress, NULL ); } } break; } return 0L; }
BOOL CStockInfo::GetRatioChangeHand( CKData &kdata, double * pValue, DWORD dateCur, int nDays ) { double dVolume = 0; if( !kdata.GetVolumeSum( &dVolume, dateCur, nDays ) ) return FALSE; return GetRatioChangeHand( pValue, dVolume ); }
int CStock::MergeKData( CStock &stock, int period ) { CKData * pkdata = NULL; CKData * pkdata2 = NULL; switch( period ) { case CKData::ktypeMonth: pkdata = &(GetKDataMonth()); pkdata2 = &(stock.GetKDataMonth()); break; case CKData::ktypeWeek: pkdata = &(GetKDataWeek()); pkdata2 = &(stock.GetKDataWeek()); break; case CKData::ktypeDay: pkdata = &(GetKDataDay()); pkdata2 = &(stock.GetKDataDay()); break; case CKData::ktypeMin60: pkdata = &(GetKDataMin60()); pkdata2 = &(stock.GetKDataMin60()); break; case CKData::ktypeMin30: pkdata = &(GetKDataMin30()); pkdata2 = &(stock.GetKDataMin30()); break; case CKData::ktypeMin15: pkdata = &(GetKDataMin15()); pkdata2 = &(stock.GetKDataMin15()); break; case CKData::ktypeMin5: pkdata = &(GetKDataMin5()); pkdata2 = &(stock.GetKDataMin5()); break; case CKData::ktypeMin1: pkdata = &(GetKDataMin1()); pkdata2 = &(stock.GetKDataMin1()); break; default: SP_ASSERT( FALSE ); return 0; } return pkdata->MergeKData( pkdata2 ); }
BOOL UpdateStockContainerByKData( CStockContainer &container, LPCTSTR lpszCode, CKData & kdata ) { container.Lock(); int id = 0; if( CKData::ktypeDay == kdata.GetKType() && container.GetStockInfo( lpszCode, NULL, &id ) ) { CStockInfo & info = container.ElementAt(id); if( kdata.GetSize() > (int)AfxGetProfile().GetCacheDays() ) { // 只使用AfxGetProfile().GetCacheDays()天的数据 CKData temp( kdata.GetKType() ); for( int i=kdata.GetSize()-AfxGetProfile().GetCacheDays(); i<kdata.GetSize(); i++ ) temp.Add( kdata.ElementAt(i) ); info.m_kdata.MergeKData( &temp ); } else info.m_kdata.MergeKData( &kdata ); // 指数涨跌家数 int nSize = info.m_kdata.GetSize(); if( nSize > 0 ) { info.m_dwAdvance = info.m_kdata.ElementAt(nSize-1).m_dwAdvance; info.m_dwDecline = info.m_kdata.ElementAt(nSize-1).m_dwDecline; } } container.UnLock(); return TRUE; }
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; }
///////////////////////////////////////////////////////////////////////////// // 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(); }
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; }
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(); }
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::Min5ToMin60( CKData &kdm5, CKData &kdm60 ) { SP_ASSERT( ktypeMin5 == kdm5.GetKType() ); SP_ASSERT( ktypeMin60 == kdm60.GetKType() ); return ConvertKData( kdm5, kdm60, 12 ); }
int CKData::Min5ToMin30( CKData &kdm5, CKData &kdm30 ) { SP_ASSERT( ktypeMin5 == kdm5.GetKType() ); SP_ASSERT( ktypeMin30 == kdm30.GetKType() ); return ConvertKData( kdm5, kdm30, 6 ); }
int CKData::Min5ToMin15( CKData &kdm5, CKData &kdm15 ) { SP_ASSERT( ktypeMin5 == kdm5.GetKType() ); SP_ASSERT( ktypeMin15 == kdm15.GetKType() ); return ConvertKData( kdm5, kdm15, 3 ); }