📄 techswing.cpp
字号:
*pValue = (dTP - dMATP) / (m_dQuotiety * dD);
StoreToCache( nIndex, pValue );
return TRUE;
}
/***
CCI 及其 移动平均值
*/
BOOL CCCI::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
//////////////////////////////////////////////////////////////////////
// CCV
CCV::CCV( )
{
SetDefaultParameters( );
}
CCV::CCV( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CCV::~CCV()
{
Clear( );
}
void CCV::SetDefaultParameters( )
{
m_nMAHLDays = 10;
m_nCVDays = 10;
m_itsSold = ITS_BUY;
m_itsBought = ITS_SELL;
}
void CCV::AttachParameters( CCV & src )
{
m_nMAHLDays = src.m_nMAHLDays;
m_nCVDays = src.m_nCVDays;
m_itsSold = src.m_itsSold;
m_itsBought = src.m_itsBought;
}
BOOL CCV::IsValidParameters( )
{
return ( VALID_DAYS(m_nMAHLDays) && VALID_DAYS(m_nCVDays)
&& VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
}
void CCV::Clear( )
{
CTechnique::Clear( );
}
int CCV::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
if( nIndex <= 1 )
return ITS_NOTHING;
double dNow, dLast, dLastLast;
if( !Calculate( &dLastLast, nIndex-2, FALSE )
|| !Calculate( &dLast, nIndex-1, FALSE )
|| !Calculate( &dNow, nIndex, FALSE ) )
return ITS_NOTHING;
if( dLastLast < 0 && dLast < 0 && dNow < 0 && dLast <= dLastLast && dNow > dLast )
{ // 超卖
if( pnCode ) *pnCode = ITSC_OVERSOLD;
return m_itsSold;
}
if( dLastLast > 0 && dLast > 0 && dNow > 0 && dLast >= dLastLast && dNow < dLast )
{ // 超买
if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
return m_itsBought;
}
return ITS_NOTHING;
}
BOOL CCV::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
}
/***
A = 最高价 - 最低价
MAHL = A的m_nMAHLDays日平均值
MAHLLast= m_nCVDays日前的MAHL
CCI = 100 * (MAHL - MAHLLast) / MAHLLast;
*/
BOOL CCV::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nMAHLDays+m_nCVDays > nIndex+2 )
return FALSE;
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dMAHLNow = 0, dMAHLLast = 0;
int nCount = 0, k=0;
for( k=nIndex; k>=0; k-- )
{
KDATA kd = m_pKData->ElementAt(k);
dMAHLNow += (kd.m_fHigh-kd.m_fLow);
nCount ++;
if( nCount == m_nMAHLDays )
break;
}
nCount = 0;
for( k=nIndex-m_nCVDays+1; k>=0; k-- )
{
KDATA kd = m_pKData->ElementAt(k);
dMAHLLast += (((double)kd.m_fHigh)-kd.m_fLow);
nCount ++;
if( nCount == m_nMAHLDays )
break;
}
dMAHLNow = dMAHLNow / m_nMAHLDays;
dMAHLLast = dMAHLLast / m_nMAHLDays;
if( fabs(dMAHLLast) < 1e-4 )
return FALSE;
if( pValue )
*pValue = (dMAHLNow - dMAHLLast) * 100 / dMAHLLast;
StoreToCache( nIndex, pValue );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CARBR
CARBR::CARBR( )
{
SetDefaultParameters( );
}
CARBR::CARBR( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CARBR::~CARBR()
{
Clear( );
}
void CARBR::SetDefaultParameters( )
{
m_nDays = 26;
m_itsGoldenFork = ITS_BUYINTENSE;
m_itsDeadFork = ITS_SELLINTENSE;
m_itsSold = ITS_BUY;
m_itsBought = ITS_SELL;
}
void CARBR::AttachParameters( CARBR & src )
{
m_nDays = src.m_nDays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
m_itsSold = src.m_itsSold;
m_itsBought = src.m_itsBought;
}
BOOL CARBR::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays)
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork)
&& VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
}
void CARBR::Clear( )
{
CTechnique::Clear( );
}
int CARBR::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
double dAR, dBR;
if( !Calculate( &dAR, &dBR, nIndex, FALSE ) )
return ITS_NOTHING;
int nForkSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( (dAR < 50 || dBR < 50 ) && nForkSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( (dAR > 180 || dBR > 300) && nForkSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
if( dAR < 50 )
{ // 超卖
if( pnCode ) *pnCode = ITSC_OVERSOLD;
return m_itsSold;
}
if( dAR > 200 )
{ // 超买
if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
return m_itsBought;
}
return ITS_NOTHING;
}
BOOL CARBR::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
(H-O)n天之和
AR = ———————— × 100
(O-L)n天之和
(H-C)n天之和
BR = ———————— × 100
(C-L)n天之和
H:最高价 L:最低价 O:开盘价 C:收盘价
*/
BOOL CARBR::Calculate( double * pAR, double *pBR, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nDays > nIndex )
return FALSE;
if( LoadFromCache( nIndex, pAR, pBR ) )
return TRUE;
double dUP = 0, dDG = 0, dBS = 0, dSS = 0;
int nCount = 0;
for( int k=nIndex; k>=1; k-- )
{
KDATA kd = m_pKData->ElementAt(k);
KDATA kdLast = m_pKData->ElementAt(k-1);
dUP += (((double)kd.m_fHigh)-kd.m_fOpen);
dDG += (((double)kd.m_fOpen)-kd.m_fLow);
dBS += max( 0, ((double)kd.m_fHigh) - kdLast.m_fClose );
dSS += max( 0, ((double)kdLast.m_fClose) - kd.m_fLow );
nCount ++;
if( nCount == m_nDays )
break;
}
if( dDG < 1e-4 || dSS < 1e-4 )
return FALSE;
if( pAR )
*pAR = dUP * 100 / dDG;
if( pBR )
*pBR = dBS * 100 / dSS;
StoreToCache( nIndex, pAR, pBR );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CCR
CCR::CCR( )
{
SetDefaultParameters( );
}
CCR::CCR( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CCR::~CCR()
{
Clear( );
}
void CCR::SetDefaultParameters( )
{
m_nDays = 26;
m_nMADaysA = 10;
m_nMADaysB = 20;
m_nMADaysC = 40;
m_nMADaysD = 62;
m_itsSold = ITS_BUY;
m_itsBought = ITS_SELL;
}
void CCR::AttachParameters( CCR & src )
{
m_nDays = src.m_nDays;
m_nMADaysA = src.m_nMADaysA;
m_nMADaysB = src.m_nMADaysB;
m_nMADaysC = src.m_nMADaysC;
m_nMADaysD = src.m_nMADaysD;
m_itsSold = src.m_itsSold;
m_itsBought = src.m_itsBought;
}
BOOL CCR::IsValidParameters( )
{
return ( VALID_DAYS( m_nDays ) && VALID_DAYS( m_nMADaysA ) && VALID_DAYS( m_nMADaysB )
&& VALID_DAYS( m_nMADaysC ) && VALID_DAYS( m_nMADaysD )
&& VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
}
void CCR::Clear( )
{
CTechnique::Clear( );
}
int CCR::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
double dCR;
if( !Calculate( &dCR, nIndex, FALSE ) )
return ITS_NOTHING;
if( dCR < 40 )
{ // 超卖
if( pnCode ) *pnCode = ITSC_OVERSOLD;
return m_itsSold;
}
if( dCR > 300 )
{ // 超买
if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
return m_itsBought;
}
return ITS_NOTHING;
}
BOOL CCR::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo5( nStart, nEnd, pdMin, pdMax, this );
}
/***
MID = (开盘价 + 收盘价 + 最高价 + 最低价)÷ 2
上升值 = 今最高 - 昨日MID (负值记为0)
下跌值 = 昨MID - 今最低
n天上升值之和
CR = ———————— × 100
n天下跌值之和
*/
BOOL CCR::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nDays > nIndex )
return FALSE;
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dBS = 0, dSS = 0, dCR = 0;
int nCount = 0;
for( int k=nIndex; k>=1; k-- )
{
KDATA kd = m_pKData->ElementAt(k);
KDATA kdLast = m_pKData->ElementAt(k-1);
double dTP = (kdLast.m_fHigh+kdLast.m_fLow+kdLast.m_fOpen+kdLast.m_fClose)/4;
dBS += max( 0, kd.m_fHigh - dTP );
dSS += max( 0, dTP - kd.m_fLow );
nCount ++;
if( nCount == m_nDays )
break;
}
if( dSS < 1e-4 )
return FALSE;
dCR = dBS * 100 / dSS;
if( pValue )
*pValue = dCR;
StoreToCache( nIndex, pValue );
return TRUE;
}
/***
A, B, C, D 分别是CR的N日平均值
N分别为m_nMADaysA,m_nMADaysB,m_nMADaysC,m_nMADaysD
*/
BOOL CCR::Calculate( double * pValue, double * pA, double * pB, double * pC, double * pD, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
int nMaxMADays = max( max(m_nMADaysA,m_nMADaysB), max(m_nMADaysC,m_nMADaysD) );
if( m_nDays+nMaxMADays > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pValue, pA, pB, pC, pD ) )
return TRUE;
double dCR = 0, dA = 0, dB = 0, dC = 0, dD = 0;
int nCount = 0;
for( int k=nIndex; k>=m_nDays; k-- )
{
double dTemp;
if( Calculate( &dTemp, k, FALSE ) )
{
if( nIndex == k )
dCR = dTemp;
nCount ++;
if( nCount <= m_nMADaysA )
dA += dTemp;
if( nCount <= m_nMADaysB )
dB += dTemp;
if( nCount <= m_nMADaysC )
dC += dTemp;
if( nCount <= m_nMADaysD )
dD += dTemp;
if( nCount > nMaxMADays )
{
if( pValue ) *pValue = dCR;
if( pA ) *pA = dA / m_nMADaysA;
if( pB ) *pB = dB / m_nMADaysB;
if( pC ) *pC = dC / m_nMADaysC;
if( pD ) *pD = dD / m_nMADaysD;
StoreToCache( nIndex, pValue, pA, pB, pC, pD );
return TRUE;
}
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// COSC
COSC::COSC( )
{
SetDefaultParameters( );
}
COSC::COSC( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
COSC::~COSC()
{
Clear( );
}
void COSC::SetDefaultParameters( )
{
m_nDays = 10;
m_nMADays = 6;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void COSC::AttachParameters( COSC & src )
{
m_nDays = src.m_nDays;
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL COSC::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays) && VALID_DAYS(m_nMADays)
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void COSC::Clear( )
{
CTechnique::Clear( );
}
int COSC::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = m_nDays+m_nMADays;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.3, 0.6 ) )
return ITS_NOTHING;
double dOSC;
if( !Calculate( &dOSC, nIndex, FALSE ) )
return ITS_NOTHING;
int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( dOSC < dLiminalLow && nSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dOSC > dLiminalHigh && nSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
BOOL COSC::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
OSC = 今日收盘价/N日收盘价平均值
*/
BOOL COSC::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nDays > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dCt = m_pKData->MaindataAt(nIndex);
double dMA = 0;
int nCount = 0;
for( int k=nIndex; k>=0; k-- )
{
dMA += m_pKData->MaindataAt(k);
nCount ++;
if( nCount == m_nDays )
{
dMA = dMA / m_nDays;
if( dMA < 1e-4 )
return FALSE;
if( pValue )
*pValue = (dCt/dMA);
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
/***
计算OSC及其移动平均值
*/
BOOL COSC::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
//////////////////////////////////////////////////////////////////////
// CUOS
CUOS::CUOS( )
{
SetDefaultParameters( );
}
CUOS::CUOS( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CUOS::~CUOS()
{
Clear( );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -