Fetch the repository succeeded.
#include "SAR.h"
#include "Tech.h"
#include "../FacilityBaseLib/KData.h"
//////////////////////////////////////////////////////////////////////
// CSAR
CSAR::CSAR( )
{
SetDefaultParameters( );
}
CSAR::CSAR( KdataContainer * pKData )
: TechnicalIndicator( pKData )
{
SetDefaultParameters( );
m_bCurUp = m_bFirstUp;
m_bTurn = false;
m_dCurAF = m_dAFStep;
m_dCurHigh = -1;
m_dCurLow = -1;
}
CSAR::~CSAR()
{
clear( );
}
void CSAR::SetDefaultParameters( )
{
m_nInitDays = 4;
m_bFirstUp = true;
m_dAFStep = 0.02;
m_dAFMax = 0.2;
m_itsBuy = ITS_BUY;
m_itsSell = ITS_SELL;
}
void CSAR::attach( CSAR & src )
{
m_nInitDays = src.m_nInitDays;
m_bFirstUp = src.m_bFirstUp;
m_dAFStep = src.m_dAFStep;
m_dAFMax = src.m_dAFMax;
m_itsBuy = src.m_itsBuy;
m_itsSell = src.m_itsSell;
}
bool CSAR::IsValidParameters( )
{
return ( VALID_DAYS(m_nInitDays) && m_bFirstUp >= 0 && m_dAFStep > 0 && m_dAFMax > 0
&& VALID_ITS(m_itsBuy) && VALID_ITS(m_itsSell) );
}
void CSAR::clear( )
{
TechnicalIndicator::clear( );
}
bool CSAR::CalculateSAR( double * pValue, size_t nIndex, bool bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( m_nInitDays > nIndex + 1 )
return false;
double dResult = 0;
if( bUseLast && pValue && nIndex > 0 && !m_bTurn )
{
KDATA kd = m_pKData->at(nIndex-1);
if( m_bCurUp )
{
dResult = (*pValue) + m_dCurAF * (kd.HighestPrice - (*pValue) );
if( kd.HighestPrice > m_dCurHigh )
{
m_dCurHigh = kd.HighestPrice;
m_dCurAF = m_dCurAF + m_dAFStep;
if( m_dCurAF > m_dAFMax )
m_dCurAF = m_dAFMax;
}
if( m_pKData->at(nIndex).LowestPrice < dResult )
m_bTurn = true;
}
else
{
dResult = (*pValue) - m_dCurAF * ((*pValue) - kd.LowestPrice );
if( kd.LowestPrice < m_dCurLow )
{
m_dCurLow = kd.LowestPrice;
m_dCurAF = m_dCurAF + m_dAFStep;
if( m_dCurAF > m_dAFMax )
m_dCurAF = m_dAFMax;
}
if( m_pKData->at(nIndex).HighestPrice > dResult )
m_bTurn = true;
}
}
else
{
for( int k=nIndex; k>=nIndex-m_nInitDays+1; k-- )
{
KDATA kd = m_pKData->at(k);
if( nIndex == k )
{
m_dCurHigh = kd.HighestPrice;
m_dCurLow = kd.LowestPrice;
}
else if( kd.HighestPrice > m_dCurHigh )
m_dCurHigh = kd.HighestPrice;
else if( kd.LowestPrice < m_dCurLow )
m_dCurLow = kd.LowestPrice;
}
if( m_bTurn )
m_bCurUp = ! m_bCurUp;
else
m_bCurUp = m_bFirstUp;
m_bTurn = false;
m_dCurAF = m_dAFStep;
if( m_bCurUp )
dResult = m_dCurLow;
else
dResult = m_dCurHigh;
}
if( pValue )
*pValue = dResult;
return true;
}
int CSAR::signal(size_t nIndex, uint32_t * pnCode)
{
if( pnCode ) *pnCode = ITSC_NOTHING;
clear( );
double dValue;
if( !calc( &dValue, nIndex, false ) )
return ITS_NOTHING;
if( m_bTurn && !m_bCurUp )
{ // 反转向上
if( pnCode ) *pnCode = ITSC_LONG;
return m_itsBuy;
}
if( m_bTurn && m_bCurUp )
{ // 反转向下
if( pnCode ) *pnCode = ITSC_SHORT;
return m_itsSell;
}
return ITS_NOTHING;
}
bool CSAR::min_max_info(size_t nStart, size_t nEnd,
double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
}
/***
计算SAR值
先选定时间,判断价格是在上涨还是在下跌。
若是看涨,则进场第一天的SAR必须是近期内的最低价,是看跌 则进场第一天的SAR必须是近期内的最高价。
本处为缺省定义为看涨。
进场第二天的SAR则为第一天的最高价(看涨时)或最低价(看跌时)与第一天的SAR的差距乘上调整系数,
再加上第一天的SAR就可求得。
按逐步递推的方法,每日的SAR可归纳如下: SAR(N)= SAR(N-1)+ AF * [ EP(N-1)-SAR(N-1)]
其中SAR(N)为第N日的SAR值,AF是调整系数,EP为极点价
第一个调整系数AF为0.02,若每隔一天的最高价比前一天的最高价还高,则AF递增0.02,若未创新高,
则AF沿用前一天的数值,但调整系数最高不超过0.2。
若是买进期间,计算出某日的SAR比当日或前一日的最低价还高,则应以当日或者前一日的最低价为某日之SAR,
卖出期间也对应服从类似原则。
*/
bool CSAR::calc(double * pValue, size_t nIndex, bool bUseLast)
{
if( load_from_cache( nIndex, pValue ) )
return true;
if( bUseLast && pValue && nIndex > 0 )
{
if( CalculateSAR( pValue, nIndex, bUseLast ) )
{
store_to_cache( nIndex, pValue );
return true;
}
return false;
}
else
{
double dResult;
bool bHasLast = false;
for( size_t k=0; k<=nIndex; k++ )
{
if( CalculateSAR( &dResult, k, bHasLast ) )
{
bHasLast = true;
store_to_cache( k, &dResult );
}
}
if( !bHasLast )
return false;
if( pValue )
*pValue = dResult;
return true;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。