📄 techswing.cpp
字号:
void CUOS::SetDefaultParameters( )
{
m_nDays1 = 7;
m_nDays2 = 14;
m_nDays3 = 28;
m_nMADays = 6;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CUOS::AttachParameters( CUOS & src )
{
m_nDays1 = src.m_nDays1;
m_nDays2 = src.m_nDays2;
m_nDays3 = src.m_nDays3;
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CUOS::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays1) && VALID_DAYS(m_nDays2) && VALID_DAYS(m_nDays3) && VALID_DAYS(m_nMADays)
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CUOS::Clear( )
{
CTechnique::Clear( );
}
int CUOS::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = max( max(m_nDays1,m_nDays2),m_nDays3) +m_nMADays;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.4, 0.6 ) )
return ITS_NOTHING;
double dUOS;
if( !Calculate( &dUOS, nIndex, FALSE ) )
return ITS_NOTHING;
int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( dUOS < dLiminalLow && nSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dUOS > dLiminalHigh && nSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
BOOL CUOS::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
OSC1 = m_nDays1日OSC
OSC2 = m_nDays2日OSC
OSC3 = m_nDays3日OSC
UOS = (OSC1+OSC2+OSC3)/3
*/
BOOL CUOS::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dOSC1 = 0, dOSC2 = 0, dOSC3 = 0;
COSC osc1(m_pKData), osc2(m_pKData), osc3(m_pKData);
osc1.m_nDays = m_nDays1;
osc2.m_nDays = m_nDays2;
osc3.m_nDays = m_nDays3;
if( osc1.Calculate( &dOSC1, nIndex, FALSE )
&& osc2.Calculate( &dOSC2, nIndex, FALSE )
&& osc3.Calculate( &dOSC3, nIndex, FALSE ) )
{
if( pValue )
*pValue = (dOSC1+dOSC2+dOSC3)/3;
StoreToCache( nIndex, pValue );
return TRUE;
}
return FALSE;
}
/***
计算UOS及其移动平均值
*/
BOOL CUOS::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
//////////////////////////////////////////////////////////////////////
// CMAOSC
CMAOSC::CMAOSC( )
{
SetDefaultParameters( );
}
CMAOSC::CMAOSC( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CMAOSC::~CMAOSC()
{
Clear( );
}
void CMAOSC::SetDefaultParameters( )
{
m_nDays1 = 6;
m_nDays2 = 12;
m_nMADays = 6;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CMAOSC::AttachParameters( CMAOSC & src )
{
m_nDays1 = src.m_nDays1;
m_nDays2 = src.m_nDays2;
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CMAOSC::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays1) && VALID_DAYS(m_nDays2) && VALID_DAYS(m_nMADays)
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CMAOSC::Clear( )
{
CTechnique::Clear( );
}
int CMAOSC::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = m_nMADays + max(m_nDays1,m_nDays2);
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.4, 0.5 ) )
return ITS_NOTHING;
double dMAOSC;
if( !Calculate( &dMAOSC, nIndex, FALSE ) )
return ITS_NOTHING;
int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( dMAOSC < dLiminalLow && nSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dMAOSC > dLiminalHigh && nSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
BOOL CMAOSC::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
MAOSC = m_nDays1日收盘价移动平均值 - m_nDays2日收盘价移动平均值
*/
BOOL CMAOSC::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dMA1 = 0, dMA2 = 0;
int nCount = 0;
for( int k=nIndex; k>=0; k-- )
{
if( nCount < m_nDays1 )
dMA1 += m_pKData->MaindataAt(k);
if( nCount < m_nDays2 )
dMA2 += m_pKData->MaindataAt(k);
nCount ++;
if( nCount >= m_nDays1 && nCount >= m_nDays2 )
{
if( pValue )
*pValue = (dMA1/m_nDays1 - dMA2/m_nDays2);
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
/***
计算MAOSC及其移动平均值
*/
BOOL CMAOSC::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
//////////////////////////////////////////////////////////////////////
// C36BIAS
C36BIAS::C36BIAS( )
{
SetDefaultParameters( );
}
C36BIAS::C36BIAS( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
C36BIAS::~C36BIAS()
{
Clear( );
}
void C36BIAS::SetDefaultParameters( )
{
m_itsSold = ITS_BUY;
m_itsBought = ITS_SELL;
}
void C36BIAS::AttachParameters( C36BIAS & src )
{
m_itsSold = src.m_itsSold;
m_itsBought = src.m_itsBought;
}
BOOL C36BIAS::IsValidParameters( )
{
return ( VALID_ITS(m_itsSold) && VALID_ITS(m_itsBought) );
}
void C36BIAS::Clear( )
{
CTechnique::Clear( );
}
int C36BIAS::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = 6;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, 40, &dLiminalLow, &dLiminalHigh, 0.02, 0.98 ) )
return ITS_NOTHING;
double d36BIAS;
if( !Calculate( &d36BIAS, nIndex, FALSE ) )
return ITS_NOTHING;
if( d36BIAS < dLiminalLow )
{ // 超卖
if( pnCode ) *pnCode = ITSC_OVERSOLD;
return m_itsSold;
}
if( d36BIAS > dLiminalHigh )
{ // 超买
if( pnCode ) *pnCode = ITSC_OVERBOUGHT;
return m_itsBought;
}
return ITS_NOTHING;
}
BOOL C36BIAS::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
}
/***
3-6BIAS = 3日收盘价移动平均值 - 6日收盘价移动平均值
*/
BOOL C36BIAS::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dMA1 = 0, dMA2 = 0;
int nCount = 0;
for( int k=nIndex; k>=0; k-- )
{
if( nCount < 3 )
dMA1 += m_pKData->MaindataAt(k);
if( nCount < 6 )
dMA2 += m_pKData->MaindataAt(k);
nCount ++;
if( nCount >= 3 && nCount >= 6 )
{
if( pValue )
*pValue = (dMA1/3 - dMA2/6);
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CDPO
CDPO::CDPO( )
{
SetDefaultParameters( );
}
CDPO::CDPO( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CDPO::~CDPO()
{
Clear( );
}
void CDPO::SetDefaultParameters( )
{
m_nDays = 10;
m_nMADays = 6;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CDPO::AttachParameters( CDPO & src )
{
m_nDays = src.m_nDays;
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CDPO::IsValidParameters( )
{
return ( VALID_DAYS( m_nDays ) && VALID_DAYS( m_nMADays )
&& VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CDPO::Clear( )
{
CTechnique::Clear( );
}
int CDPO::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = 3*m_nDays + m_nMADays;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.2, 0.7 ) )
return ITS_NOTHING;
double dDPO;
if( !Calculate( &dDPO, nIndex, FALSE ) )
return FALSE;
int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( dDPO < dLiminalLow && nSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dDPO > dLiminalHigh && nSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
BOOL CDPO::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
DPO = 今日收盘价 - N日前的(N+N)日平均收盘价
*/
BOOL CDPO::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
if( 3*m_nDays-2 > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dCt = 0, dMA = 0;
double nCount = 0;
for( int k=nIndex-m_nDays+1; k>=0; k-- )
{
dMA += m_pKData->MaindataAt(k);
nCount ++;
if( nCount == m_nDays+m_nDays )
{
dCt = m_pKData->MaindataAt(nIndex);
dMA = dMA / (m_nDays+m_nDays);
if( pValue )
*pValue = (dCt-dMA);
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
/***
计算DPO及其移动平均值
*/
BOOL CDPO::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
//////////////////////////////////////////////////////////////////////
// CKST
CKST::CKST( )
{
SetDefaultParameters( );
}
CKST::CKST( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CKST::~CKST()
{
Clear( );
}
void CKST::SetDefaultParameters( )
{
m_adwROCDays.RemoveAll();
m_adwROCDays.Add( 9 );
m_adwROCDays.Add( 12 );
m_adwROCDays.Add( 18 );
m_adwROCDays.Add( 24 );
m_nMADays = 6;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CKST::AttachParameters( CKST & src )
{
m_adwROCDays.Copy( src.m_adwROCDays );
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CKST::IsValidParameters( )
{
STT_VALID_DAYSARRAY( m_adwROCDays );
return ( VALID_DAYS(m_nMADays) && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CKST::Clear( )
{
CTechnique::Clear( );
}
int CKST::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
int nMaxDays = AfxGetMaxDays( m_adwROCDays )+m_nMADays;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.2, 0.6 ) )
return ITS_NOTHING;
if( nIndex <= 1 )
return ITS_NOTHING;
double dKST;
if( !Calculate( &dKST, nIndex, FALSE ) )
return ITS_NOTHING;
int nSignal = GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
if( dKST < dLiminalLow && nSignal == m_itsGoldenFork )
{ // 低位金叉
if( pnCode ) *pnCode = ITSC_GOLDENFORK;
return m_itsGoldenFork;
}
if( dKST > dLiminalHigh && nSignal == m_itsDeadFork )
{ // 高位死叉
if( pnCode ) *pnCode = ITSC_DEADFORK;
return m_itsDeadFork;
}
return ITS_NOTHING;
}
BOOL CKST::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
9日ROC + 12日ROC×2 + 18日ROC×3 + 24日ROC×4
KST = ------------------------------------------------
10
*/
BOOL CKST::Calculate( double * pValue, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
UINT nMaxDays = AfxGetMaxDays( m_adwROCDays );
if( (int)nMaxDays > nIndex )
return FALSE;
if( LoadFromCache( nIndex, pValue ) )
return TRUE;
double dKST = 0;
int nCount = 0;
for( int m=0; m<m_adwROCDays.GetSize(); m++ )
{
CROC roc(m_pKData);
roc.m_nDays = m_adwROCDays[m];
double dROC = 0;
if( !roc.Calculate( &dROC, nIndex, FALSE ) )
return FALSE;
dKST += dROC*(m+1);
nCount += (m+1);
}
if( nCount <= 0 )
return FALSE;
dKST = dKST / nCount;
if( pValue )
*pValue = dKST;
StoreToCache( nIndex, pValue );
return TRUE;
}
/***
计算KST及其移动平均值
*/
BOOL CKST::Calculate( double * pValue, double * pMA, int nIndex, BOOL bUseLast )
{
return CTechnique::CalculateMA( pValue, pMA, nIndex, bUseLast, m_nMADays );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -