?? techtrend.cpp
字號:
/*
Cross Platform Core Code.
Copyright(R) 2001-2002 Balang Software.
All rights reserved.
*/
#include "StdAfx.h"
#include "Stock.h"
#include "Technique.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CMACD
CMACD::CMACD( )
{
SetDefaultParameters( );
}
CMACD::CMACD( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CMACD::~CMACD()
{
Clear( );
}
void CMACD::SetDefaultParameters( )
{
m_nEMA1Days = 12;
m_nEMA2Days = 26;
m_nDIFDays = 9;
m_itsDeviateOnBottom = ITS_BUYINTENSE;
m_itsDeviateOnTop = ITS_SELLINTENSE;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CMACD::AttachParameters( CMACD & src )
{
m_nEMA1Days = src.m_nEMA1Days;
m_nEMA2Days = src.m_nEMA2Days;
m_nDIFDays = src.m_nDIFDays;
m_itsDeviateOnBottom = src.m_itsDeviateOnBottom;
m_itsDeviateOnTop = src.m_itsDeviateOnTop;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CMACD::IsValidParameters( )
{
return ( VALID_DAYS(m_nEMA1Days) && VALID_DAYS(m_nEMA2Days) && VALID_DAYS(m_nDIFDays)
&& VALID_ITS(m_itsDeviateOnBottom) && VALID_ITS(m_itsDeviateOnTop)
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CMACD::Clear( )
{
CTechnique::Clear( );
}
int CMACD::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
PrepareCache( 0, -1, FALSE );
int nMaxDays = max( max(m_nEMA1Days,m_nEMA2Days) , m_nDIFDays );
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.309, 0.682 ) )
return ITS_NOTHING;
double dEMA1, dEMA2, dDIF, dDEA;
if( !Calculate( &dEMA1, &dEMA2, &dDIF, &dDEA, nIndex, FALSE ) )
return ITS_NOTHING;
if( IsDeviateOnBottom( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 底背離
if( pnCode ) *pnCode = ITSC_DEVIATEONBOTTOM;
return m_itsDeviateOnBottom;
}
if( IsDeviateOnTop( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 頂背離
if( pnCode ) *pnCode = ITSC_DEVIATEONTOP;
return m_itsDeviateOnTop;
}
if( dDIF < dLiminalLow && dDEA < dLiminalLow && IsGoldenFork( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dDIF > dLiminalHigh && dDEA > dLiminalHigh && IsDeadFork( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
if( dDIF < dLiminalLow && dDEA < dLiminalLow )
{ // 低位
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dDIF > dLiminalHigh && dDEA > dLiminalHigh )
{ // 高位
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
/***
EMA = 短期移動均值
EMA2 = 長期移動均值
DIF = 短期移動均值 - 長期移動均值
DEA = DIF的移動平滑值
柱狀線值 = DIF - DEA
*/
BOOL CMACD::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
double dMin = 0, dMax = 0;
double dEMA1 = 0, dEMA2 = 0, dDIF = 0, dDEA = 0;
BOOL bFirst = TRUE;
for( int k=nStart; k<=nEnd; k++ )
{
if( Calculate( &dEMA1, &dEMA2, &dDIF, &dDEA, k, !bFirst ) )
{
if( bFirst ) { dMin = dDIF; dMax = dDIF; }
if( dDIF < dMin ) dMin = dDIF;
if( dDEA < dMin ) dMin = dDEA;
if( 2*(dDIF-dDEA) < dMin ) dMin = 2*(dDIF-dDEA); // WARNING: different
if( dDIF > dMax ) dMax = dDIF;
if( dDEA > dMax ) dMax = dDEA;
if( 2*(dDIF-dDEA) > dMax ) dMax = 2*(dDIF-dDEA); // WARNING: different
bFirst = FALSE;
}
}
dMin -= fabs(dMin)*0.02;
dMax += fabs(dMax)*0.02;
if( fabs(dMin) < 1e-4 )
dMin = -0.01;
if( fabs(dMax) < 1e-4 )
dMax = 0.01;
if( dMax - dMin < 0.03 )
dMax = dMin + 0.05;
if( pdMin ) *pdMin = dMin;
if( pdMax ) *pdMax = dMax;
return TRUE;
}
BOOL CMACD::Calculate( double *pdEMA1, double *pdEMA2, double *pdDIF, double *pdDEA,
int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nEMA1Days > nIndex+1 || m_nEMA2Days > nIndex+1 || m_nDIFDays > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA ) )
return TRUE;
// Calculate EMA1, EMA2, DIF, DEA
double dEMA1New = 0, dEMA2New = 0, dDIFNew = 0, dDEANew = 0;
if( bUseLast && pdEMA1 && pdEMA2 && pdDEA )
{
dEMA1New = (*pdEMA1)*(m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->MaindataAt(nIndex) /(m_nEMA1Days+1);
dEMA2New = (*pdEMA2)*(m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->MaindataAt(nIndex) /(m_nEMA2Days+1);
dDIFNew = dEMA1New-dEMA2New;
dDEANew = (*pdDEA)*(m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew/(m_nDIFDays+1);
}
else
{
double factor1 = 1, factor2 = 1;
int k;
for( k=nIndex; k > 0; k-- )
{
factor1 *= ((double)(m_nEMA1Days-1))/(m_nEMA1Days+1);
factor2 *= ((double)(m_nEMA2Days-1))/(m_nEMA2Days+1);
if( factor1 < 0.001 && factor2 < 0.001 )
break;
}
dEMA1New = m_pKData->MaindataAt(k);
dEMA2New = m_pKData->MaindataAt(k);
dDIFNew = dEMA1New - dEMA2New;
dDEANew = dDIFNew;
for( ; k<=nIndex; k++ )
{
dEMA1New = dEMA1New * (m_nEMA1Days-1)/(m_nEMA1Days+1) + 2 * m_pKData->MaindataAt(k) /(m_nEMA1Days+1);
dEMA2New = dEMA2New * (m_nEMA2Days-1)/(m_nEMA2Days+1) + 2 * m_pKData->MaindataAt(k) /(m_nEMA2Days+1);
dDIFNew = dEMA1New - dEMA2New;
dDEANew = dDEANew * (m_nDIFDays-1)/(m_nDIFDays+1) + 2 * dDIFNew / (m_nDIFDays+1);
}
}
if( pdEMA1 ) *pdEMA1 = dEMA1New;
if( pdEMA2 ) *pdEMA2 = dEMA2New;
if( pdDIF ) *pdDIF = dDIFNew;
if( pdDEA ) *pdDEA = dDEANew;
StoreToCache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CMIKE
CMIKE::CMIKE( )
{
SetDefaultParameters( );
}
CMIKE::CMIKE( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CMIKE::~CMIKE()
{
Clear( );
}
void CMIKE::SetDefaultParameters( )
{
m_nDays = 12;
}
void CMIKE::AttachParameters( CMIKE & src )
{
m_nDays = src.m_nDays;
}
BOOL CMIKE::IsValidParameters( )
{
return VALID_DAYS( m_nDays );
}
void CMIKE::Clear( )
{
CTechnique::Clear( );
}
/***
H:最高價 L:最低價 C:收盤價
TP = (H+L+C)÷3
第一條窄通道的上下限計算如下:
弱阻力WR=TP+(TP-L) 弱支撐WS=TP-(H-TP)
第二條通道的上下限計算如下:
中阻力MR=TP+(H-L) 中支撐MS=TP-(H-L)
第三條闊通道的上下限計算如下:
強阻力SR=H+(H-L) 強支撐SS=L-(H-L)
*/
BOOL CMIKE::CalculateMIKE( double *pWR, double *pMR, double *pSR,
double *pWS, double *pMS, double *pSS, int nIndex )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nDays * 2 > nIndex + 1 )
return FALSE;
double TP = (m_pKData->ElementAt(nIndex).m_fHigh + m_pKData->ElementAt(nIndex).m_fLow + m_pKData->ElementAt(nIndex).m_fClose)/3.0;
double minN = 0, min2N = 0, maxN = 0, max2N = 0;
for( int k=nIndex; k>=0; k -- )
{
KDATA kd = m_pKData->ElementAt(k);
if( nIndex-k < m_nDays )
{
if( nIndex == k ) { minN = kd.m_fLow; maxN = kd.m_fHigh; }
if( kd.m_fLow < minN ) minN = kd.m_fLow;
if( kd.m_fHigh > maxN ) maxN = kd.m_fHigh;
}
if( nIndex-k < m_nDays*2 )
{
if( nIndex == k ) { min2N = kd.m_fLow; max2N = kd.m_fHigh; }
if( kd.m_fLow < min2N ) min2N = kd.m_fLow;
if( kd.m_fHigh > max2N ) max2N = kd.m_fHigh;
}
else
{
break;
}
}
if( pWR ) *pWR = ( TP + (TP - minN) ) ;
if( pMR ) *pMR = ( TP + (maxN - minN) ) ;
if( pSR ) *pSR = ( TP + (max2N - minN) ) ;
if( pWS ) *pWS = ( TP - (maxN - TP) ) ;
if( pMS ) *pMS = ( TP - (maxN - minN) ) ;
if( pSS ) *pSS = ( TP - (maxN - min2N) ) ;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CPSY
CPSY::CPSY( )
{
SetDefaultParameters( );
}
CPSY::CPSY( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CPSY::~CPSY()
{
Clear( );
}
void CPSY::SetDefaultParameters( )
{
m_nDays = 12;
m_itsSold = ITS_BUY;
m_itsBought = ITS_SELL;
}
void CPSY::AttachParameters( CPSY & src )
{
m_nDays = src.m_nDays;
m_itsSold = src.m_itsSold;
m_itsBought = src.m_itsBought;
}
BOOL CPSY::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays) && VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
}
void CPSY::Clear( )
{
CTechnique::Clear( );
}
int CPSY::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
if( nIndex <= 0 )
return ITS_NOTHING;
double dPSY = 0, dPSYLast;
if( !Calculate( &dPSYLast, nIndex-1, FALSE )
|| !Calculate( &dPSY, nIndex, FALSE ) )
return ITS_NOTHING;
if( dPSY < 30 && dPSY >= dPSYLast )
{ // 超賣
if( pnCode ) *pnCode = ITSC_OVERSOLD;
return m_itsSold;
}
if( dPSY > 70 && dPSY <= dPSYLast )
{ // 超買
if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
return m_itsBought;
}
return ITS_NOTHING;
}
BOOL CPSY::GetMinMaxInfo(int nStart, int nEnd,
double *pdMin, double *pdMax )
{
if( pdMin ) *pdMin = 0;
if( pdMax ) *pdMax = 100;
return TRUE;
}
/***
N日內上漲的天數
PSY = —————————— × 100
N
*/
BOOL CPSY::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 UD = 0;
int nCount = 0;
for( int k=nIndex; k>=1; k-- )
{
if( m_pKData->MaindataAt(k) > m_pKData->MaindataAt(k-1) )
UD += 1;
nCount ++;
if( nCount == m_nDays )
{
if( pValue ) *pValue = UD * 100 / m_nDays;
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -