代码拉取完成,页面将自动刷新
#include "MACD.h"
#include <math.h>
#include "Tech.h"
#include "../FacilityBaseLib/KData.h"
//////////////////////////////////////////////////////////////////////
// CMACD
CMACD::CMACD( )
{
SetDefaultParameters( );
}
CMACD::CMACD( KdataContainer * pKData )
: TechnicalIndicator( 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::attach( 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( )
{
TechnicalIndicator::clear( );
}
int CMACD::signal( size_t nIndex, uint32_t * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
prepare_cache( 0, -1, false );
int nMaxDays = max( max(m_nEMA1Days,m_nEMA2Days) , m_nDIFDays );
double dLiminalLow = 0, dLiminalHigh = 0;
if( !intensity_prepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.309, 0.682 ) )
return ITS_NOTHING;
double dEMA1, dEMA2, dDIF, dDEA;
if( !calc( &dEMA1, &dEMA2, &dDIF, &dDEA, nIndex, false ) )
return ITS_NOTHING;
if( is_deviate_on_bottom( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 底背离
if( pnCode ) *pnCode = ITSC_DEVIATEONBOTTOM;
return m_itsDeviateOnBottom;
}
if( is_deviate_on_top( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 顶背离
if( pnCode ) *pnCode = ITSC_DEVIATEONTOP;
return m_itsDeviateOnTop;
}
if( dDIF < dLiminalLow && dDEA < dLiminalLow && is_golden_fork( nIndex, m_pdCache3, m_pdCache4 ) )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dDIF > dLiminalHigh && dDEA > dLiminalHigh && is_dead_fork( 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::min_max_info(size_t nStart, size_t nEnd, double *pdMin, double *pdMax )
{
STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
double dMin = 0, dMax = 0;
//前一日的数据设为0
double dEMA1 = 0, dEMA2 = 0, dDIF = 0, dDEA = 0;
bool bFirst = true;
for( int k=nStart; k<=nEnd; k++ )
{
if( calc( &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::calc( double *pdEMA1, double *pdEMA2, double *pdDIF, double *pdDEA,
size_t 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( load_from_cache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA ) )
return true;
// Calculate EMA1, EMA2, DIF, DEA
//EMA1的参数为12日,EMA2的参数为26日
//12日收盘价的EMA的计算公式为:
//EMA(12)=前一日EMA(12)*(12-1)/(12+1)+今日收盘价*2/(12+1)
//26日EMA的算式为
//EMA(26)=前一日EMA(26)×25/27+今日收盘价×2/27
//计算离差值(DIF)
//DIF=今日EMA(12)-今日EMA(26)
//计算MACD
//今日DEA(MACD)=前一日DEA×8/10+今日DIF×2/10
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;
store_to_cache( nIndex, pdEMA1, pdEMA2, pdDIF, pdDEA );
return true;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。