DWORD AfxGetMaxDays( CSPDWordArray & adw ) { DWORD dwMax = 0; for( int i=0; i<adw.GetSize(); i++ ) { if( adw.ElementAt(i) > dwMax ) dwMax = adw.ElementAt(i); } return dwMax; }
/*** 筹码分布图计算,计算筹码分布 */ 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 CStockContainer::GetTechDateArray( CSPDWordArray & dwArray ) { CStockInfo info; if( GetStockInfo( STKLIB_CODE_MAIN, &info ) ) { dwArray.SetSize( 0, info.m_kdata.GetSize()+10 ); for( int i=0; i<info.m_kdata.GetSize(); i++ ) dwArray.Add( info.m_kdata.ElementAt(i).m_date ); return TRUE; } return FALSE; }
/*** 筹码分布图统计,集中度统计 */ 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; 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; }
////////////////////////////////////////////////////////////////// // GetMinMaxInfo // 一些反复使用的代码,用函数代替,得到技术指标在指定范围内的最大最小值 // 技术指标有不同日期作为参数 BOOL AfxGetMinMaxInfo( int nStart, int nEnd, double *pdMin, double *pdMax, CTechnique * pTech, CSPDWordArray & adwDays ) { SP_ASSERT( pTech ); if( nStart < 0 || nEnd < 0 || nStart > nEnd || !pTech ) return FALSE; double dMin = 0, dMax = 0; double dValue = 0; BOOL bFirst = TRUE; for( int i=0; i<adwDays.GetSize(); i++ ) { for( int k=nStart; k<=nEnd; k++ ) { if( pTech->Calculate( &dValue, k, adwDays[i], !bFirst ) ) { if( bFirst || dValue < dMin ) dMin = dValue; if( bFirst || dValue > dMax ) dMax = dValue; bFirst = FALSE; } } } dMin -= fabs(dMin - dMax)*0.2; dMax += fabs(dMax - dMin)*0.2; if( dMax - dMin < 0.03 ) dMax = dMin + 0.05; if( pdMin ) *pdMin = dMin; if( pdMax ) *pdMax = dMax; return !bFirst; }
/*** 筹码分布图统计,平均成本统计 */ 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::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 CDateComboBox::InitDates( ) { ResetContent( ); // Add Date ComboBox Members CSPDWordArray dwArray; AfxGetStockContainer().GetTechDateArray( dwArray ); InitStorage( dwArray.GetSize()+2, 32 ); CString strMore; strMore.LoadString( IDS_DATECOMBOBOX_MORE ); int nIndex = AddString( strMore ); SetItemData( nIndex, -2 ); /*int nMaxDaysCalculate = AfxGetProfile().GetMaxDaysCalculate( );*/ // for( int nCount=dwArray.GetSize()-1; nCount >= 0/*nCount > nMaxDaysCalculate*/; nCount -- ) for( int nCount=0; nCount < dwArray.GetSize(); nCount ++ ) { CSPTime sptime; if( sptime.FromStockTimeDay( dwArray[nCount] ) ) { CSPTime time( sptime.GetTime() ); CString strItem = AfxGetTimeString( time.GetTime(), szDateComboBoxTimeFormat, TRUE ); if( strItem.GetLength() > 0 ) { int nIndex = AddString( strItem ); SetItemData( nIndex, dwArray[nCount] ); } } } CString strNow; strNow.LoadString( IDS_DATECOMBOBOX_NOW ); nIndex = AddString( strNow ); SetItemData( nIndex, -1 ); SetCurSel( nIndex ); return TRUE; }
// 得到趋势信号 int CTechnique::GetTrendIntensity(int nIndex, CSPDWordArray & adwDays, UINT itsLong, UINT itsShort, UINT * pnCode ) { if( pnCode ) *pnCode = ITSC_NOTHING; if( nIndex <= 0 ) return ITS_NOTHING; int nRet = ITS_NOTHING; for( int k=1; k<adwDays.GetSize(); k++ ) { double dMALast1, dMALast2, dMANow1, dMANow2; if( !Calculate( &dMALast1, nIndex-1, min(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMALast2, nIndex-1, max(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMANow1, nIndex, min(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMANow2, nIndex, max(adwDays[k-1],adwDays[k]), FALSE ) ) return ITS_NOTHING; if( dMANow1 >= dMALast1 && dMANow2 >= dMALast2 && dMANow1 > dMANow2 && (dMANow1-dMANow2)>=(dMALast1-dMALast2) && (ITS_ISBUY(nRet) || 1==k) ) { if( pnCode ) *pnCode = ITSC_LONG; nRet = itsLong; } else if( dMANow1 <= dMALast1 && dMANow2 <= dMALast2 && dMANow1 < dMANow2 && (dMANow1-dMANow2)<=(dMALast1-dMALast2) && (ITS_ISSELL(nRet) || 1==k) ) { if( pnCode ) *pnCode = ITSC_SHORT; nRet = itsShort; } else { if( pnCode ) *pnCode = ITSC_NOTHING; return ITS_NOTHING; } } return nRet; }
BOOL CStockContainer::GetMultiSortIDArray( CSPDWordArray & adwSortID, LONG lStockType, UINT nSLH, BOOL bAsc, int nCount ) { CSPMutex::Scoped l(m_mutex); SP_ASSERT( nCount > 0 && nSLH >= SLH_MIN && nSLH <= SLH_MAX ); if( nCount <= 0 || nSLH < SLH_MIN || nSLH > SLH_MAX ) return FALSE; adwSortID.RemoveAll(); for( int n=0; n<nCount; n++ ) { int nMinMaxIndex = -1; double dMinMaxValue = 0; BOOL bInited = FALSE; for( int i=0; i<GetSize(); i++ ) { CStockInfo & info = ElementAt(i); // 股票类型 if( info.GetType() != lStockType ) continue; // 如果加过,则继续寻找下一个 for( int k=0; k<adwSortID.GetSize(); k++ ) { if( adwSortID[k] == (DWORD)i ) break; } if( k != adwSortID.GetSize() ) continue; // 判断大小 double dValue = 0; if( AfxGetVariantValue( nSLH, info, &dValue, NULL ) ) { if( !bInited ) { nMinMaxIndex = i; dMinMaxValue = dValue; bInited = TRUE; } if( bAsc && dValue < dMinMaxValue ) { nMinMaxIndex = i; dMinMaxValue = dValue; } if( !bAsc && dValue > dMinMaxValue ) { nMinMaxIndex = (DWORD)i; dMinMaxValue = dValue; } } } if( -1 == nMinMaxIndex ) break; adwSortID.Add( nMinMaxIndex ); } return TRUE; }
void CSetColumnDlg::SetListColumnItems( CSPDWordArray & anShow, BOOL bSetDefault ) { m_listColumn.DeleteAllItems( ); CSPDWordArray & anOrder = AfxGetProfile().GetSListColumnsOrder( ); CIndexContainer & acol = AfxGetProfile().GetSListColumnsUser( ); CString strDay; strDay.LoadString( IDS_SLHHDR_DAY ); int nCount = 0; for( int i=0; i<anOrder.GetSize(); i++ ) { // Set Item Text CString strName, strDes; int nItem = -1; UINT nID = anOrder[i]; strName = AfxGetVariantName( nID, FALSE ); if( strName.IsEmpty() ) continue; if( nID >= SLH_USERDEFINE_BEGIN ) strDes.LoadString( IDS_SETCOLUMN_USERDEFINE ); else strDes = (LPCTSTR)AfxGetSLHDescript( nID ); nItem = m_listColumn.InsertItem( nCount, strName, -1 ); m_listColumn.SetItemText( nItem, 1, strDes ); m_listColumn.SetItemData( nItem, nID ); nCount ++; // SetCheck for( int j=0; j<anShow.GetSize(); j++ ) { if( anShow[j] == nID ) { m_listColumn.SetCheck( nItem ); break; } } // Set Column Combo Text CStringArray astr; if( SLH_DIFF == nID || SLH_DIFFPERCENT == nID || SLH_SCOPE == nID || SLH_RATIO_CHANGEHAND == nID || SLH_RATIO_VOLUME == nID || SLH_RS == nID ) { for( int nDays=1; nDays<=STKLIB_DAYS_CALCULATE; nDays ++ ) { CString strTemp; strTemp.Format( "%d%s", nDays, strDay ); astr.Add( strTemp ); } } else if( SLH_ANNGAINS_AVERAGE == nID ) { CString strTemp; strTemp.Format( "%d%s", 20, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 40, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 60, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 120, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", STKLIB_DAYS_INONEYEAR, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 2*STKLIB_DAYS_INONEYEAR, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 3*STKLIB_DAYS_INONEYEAR, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 6*STKLIB_DAYS_INONEYEAR, strDay ); astr.Add( strTemp ); strTemp.Format( "%d%s", 10*STKLIB_DAYS_INONEYEAR, strDay ); astr.Add( strTemp ); } if( astr.GetSize() > 0 ) m_listColumn.SetItemStrings( nItem, astr ); // Set Current Parameter CString strParam; if( SLH_DIFF == nID ) { if( bSetDefault ) AfxGetProfile().SetDiffDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetDiffDays(), strDay ); } else if( SLH_DIFFPERCENT == nID ) { if( bSetDefault ) AfxGetProfile().SetDiffPercentDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetDiffPercentDays(), strDay ); } else if( SLH_SCOPE == nID ) { if( bSetDefault ) AfxGetProfile().SetScopeDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetScopeDays(), strDay ); } else if( SLH_RATIO_CHANGEHAND == nID ) { if( bSetDefault ) AfxGetProfile().SetRatioChangeHandDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetRatioChangeHandDays(), strDay ); } else if( SLH_RATIO_VOLUME == nID ) { if( bSetDefault ) AfxGetProfile().SetRatioVolumeDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetRatioVolumeDays( ), strDay ); } else if( SLH_RS == nID ) { if( bSetDefault ) AfxGetProfile().SetRSDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetRSDays( ), strDay ); } else if( SLH_ANNGAINS_AVERAGE == nID ) { if( bSetDefault ) AfxGetProfile().SetYieldAverageDays( -1 ); strParam.Format( "%d%s", AfxGetProfile().GetYieldAverageDays( ), strDay ); } else if( SLH_ANNGAINS_STDDEV == nID || SLH_BETA == nID || SLH_SHARP == nID ) { strParam.LoadString( IDS_SETCOLUMN_SAMEASYIELDAVERAGE ); } if( strParam.GetLength() > 0 ) m_listColumn.SetItemText( nItem, 2, strParam ); } m_listColumn.SetComboBoxColumn( 2 ); m_listColumn.SetItemState( 0, LVIS_SELECTED, LVIS_SELECTED ); }
void CMultiSort::DrawMultiSort( CDC * pDC, CSPDWordArray &adwSortID, CRect rect, UINT nSLH, int nSelectPos ) { DECLARE_COLOR_DEFINATION int x = rect.left+8; int x2 = (int)( rect.left+0.56*rect.Width() ); int x3 = rect.right-8; int y = rect.top+20; int yStep = (rect.Height()-23) / 6 ; if( yStep <= 0 ) return; CFont * pOldFont = AfxSelectDCFont( pDC, 14 ); pDC->SetBkColor( clrBK ); for( int i=0; i<adwSortID.GetSize(); i++ ) { if( (int)adwSortID[i] < 0 || (int)adwSortID[i] >= AfxGetStockContainer().GetSize() ) continue; CStockInfo & info = AfxGetStockContainer().ElementAt(adwSortID[i]); pDC->SetTextColor( clrText ); //#ifdef CLKLAN_ENGLISH_US // pDC->TextOut( x, y, info.GetStockCode() ); //#else pDC->TextOut( x, y, info.GetStockName() ); //#endif UINT nOldAlign = pDC->SetTextAlign( TA_RIGHT | TA_TOP ); pDC->SetTextColor( AfxGetVariantColor(SLH_CLOSE,info) ); pDC->TextOut( x2, y, (LPCTSTR)AfxGetVariantDispString(SLH_CLOSE,info,NULL) ); pDC->SetTextColor( AfxGetVariantColor(nSLH,info) ); if( SLH_RATIO_VOLUME == nSLH ) { double dVolRatio = 1; CSPTime tTrade; if( AfxGetVariantValue(nSLH,info,&dVolRatio,NULL) && tTrade.FromStockTimeDay( info.m_datetech ) ) dVolRatio = dVolRatio / CSPTime::GetTimeTradeRatioOfOneDay( tTrade, CSPTime::GetCurrentTime() ); CString strTemp; strTemp.Format( "%.2f", dVolRatio ); pDC->TextOut( x3, y, strTemp ); } else { pDC->TextOut( x3, y, (LPCTSTR)AfxGetVariantDispString(nSLH,info,NULL) ); } y += yStep; pDC->SetTextAlign( nOldAlign ); // 选中股票 if( nSelectPos == i ) { int ySel = y-yStep+16; if( ySel > rect.top && ySel < rect.bottom ) DrawLine( pDC, 2, clrBorder, rect.left+5, ySel, rect.right-5, ySel ); } } // 补足股票排名 for( i=adwSortID.GetSize(); i<6; i++ ) { pDC->SetTextColor( clrText ); pDC->TextOut( x, y, "-" ); UINT nOldAlign = pDC->SetTextAlign( TA_RIGHT | TA_TOP ); pDC->TextOut( x2, y, "-" ); pDC->TextOut( x3, y, "-" ); y += yStep; pDC->SetTextAlign( nOldAlign ); } pDC->SelectObject( pOldFont ); }
// 得到金叉或者死叉信号 int CTechnique::GetForkSignal(int nIndex, CSPDWordArray & adwDays, UINT itsGoldenFork, UINT itsDeadFork, UINT * pnCode ) { if( pnCode ) *pnCode = ITSC_NOTHING; if( nIndex <= 0 ) return ITS_NOTHING; for( int k=1; k<adwDays.GetSize(); k++ ) { double dMANow1, dMANow2, dMALast1, dMALast2; if( !Calculate( &dMANow1, nIndex, min(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMANow2, nIndex, max(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMALast1, nIndex-1, min(adwDays[k-1],adwDays[k]), FALSE ) || !Calculate( &dMALast2, nIndex-1, max(adwDays[k-1],adwDays[k]), FALSE ) ) return ITS_NOTHING; if( dMALast1 <= dMALast2 && dMANow1 > dMANow2 && dMANow1 >= dMALast1 && dMANow2 >= dMALast2 ) { if( adwDays.GetSize()-1 == k ) { if( pnCode ) *pnCode = ITSC_GOLDENFORK; return itsGoldenFork; } for( int l=k+1; l<adwDays.GetSize(); l++ ) { double dMANow3, dMALast3; if( !Calculate( &dMANow3, nIndex, adwDays[l], FALSE ) || !Calculate( &dMALast3, nIndex-1, adwDays[l], FALSE ) ) return ITS_NOTHING; if( dMANow3 >= dMALast3 ) { if( pnCode ) *pnCode = ITSC_GOLDENFORK; return itsGoldenFork; } } } if( dMALast1 >= dMALast2 && dMANow1 < dMANow2 && dMANow1 <= dMALast1 && dMANow2 <= dMALast2 ) { if( adwDays.GetSize()-1 == k ) { if( pnCode ) *pnCode = ITSC_DEADFORK; return itsDeadFork; } for( int l=k+1; l<adwDays.GetSize(); l++ ) { double dMANow3, dMALast3; if( !Calculate( &dMANow3, nIndex, adwDays[l], FALSE ) || !Calculate( &dMALast3, nIndex-1, adwDays[l], FALSE ) ) return ITS_NOTHING; if( dMANow3 <= dMALast3 ) { if( pnCode ) *pnCode = ITSC_DEADFORK; return itsDeadFork; } } } } return ITS_NOTHING; }