📄 techenergy.cpp.svn-base
字号:
/*
Cross Platform Core Code.
Copyright(R) 2001-2002 Balang Software.
All rights reserved.
*/
#include "StdAfx.h"
#include "../Include/Stock.h"
#include "../Include/Technique.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CVOLUME
CVOLUME::CVOLUME( )
{
SetDefaultParameters( );
}
CVOLUME::CVOLUME( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CVOLUME::~CVOLUME()
{
Clear( );
}
void CVOLUME::SetDefaultParameters( )
{
m_adwMADays.RemoveAll();
m_adwMADays.Add( 5 );
m_adwMADays.Add( 10 );
m_itsDeviateOnBottom = ITS_BUYINTENSE;
m_itsDeviateOnTop = ITS_SELLINTENSE;
m_itsLong = ITS_BUY;
m_itsShort = ITS_SELL;
}
void CVOLUME::AttachParameters( CVOLUME & src )
{
m_adwMADays.Copy( src.m_adwMADays );
m_itsDeviateOnBottom = src.m_itsDeviateOnBottom;
m_itsDeviateOnTop = src.m_itsDeviateOnTop;
m_itsLong = src.m_itsLong;
m_itsShort = src.m_itsShort;
}
BOOL CVOLUME::IsValidParameters( )
{
STT_VALID_DAYSARRAY( m_adwMADays );
return ( VALID_ITS(m_itsDeviateOnBottom) && VALID_ITS(m_itsDeviateOnTop)
&& VALID_ITS(m_itsLong) && VALID_ITS(m_itsShort) );
}
void CVOLUME::Clear( )
{
CTechnique::Clear( );
}
int CVOLUME::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
if( !m_pKData || nIndex < 0 || nIndex >= m_pKData->GetSize() )
return ITS_NOTHING;
int nIntensity = GetTrendIntensity( nIndex, m_adwMADays, m_itsLong, m_itsShort, pnCode );
if( ITS_BUY == nIntensity
&& m_pKData->IsNewValue( nIndex, FALSE, ITS_DAYS_DEVIATE ) )
{ // 底背离,股价创新低并且成交量趋势向上
if( pnCode ) *pnCode = ITSC_DEVIATEONBOTTOM;
return m_itsDeviateOnBottom;
}
if( ITS_SELL == nIntensity
&& m_pKData->IsNewValue( nIndex, TRUE, ITS_DAYS_DEVIATE ) )
{ // 顶背离,股价创新高并且成交量趋势向下
if( pnCode ) *pnCode = ITSC_DEVIATEONTOP;
return m_itsDeviateOnTop;
}
return nIntensity;
}
BOOL CVOLUME::GetMinMaxInfo(int nStart, int nEnd,
double *pdMin, double *pdMax )
{
STT_ASSERT_GETMINMAXINFO( m_pKData, nStart, nEnd );
double dMin = 0;
double dMax = 1;
for( int k=nStart; k<=nEnd; k++ )
{
KDATA & kd = m_pKData->ElementAt(k);
if( dMax < kd.m_fVolume )
dMax = (double)kd.m_fVolume;
}
dMax = dMax + 1;
if( dMax - dMin < 3 )
dMax = dMin + 3;
if( pdMin ) *pdMin = dMin;
if( pdMax ) *pdMax = dMax;
return TRUE;
}
/***
计算nDays的平均成交量
*/
BOOL CVOLUME::Calculate( double * pValue, int nIndex, int nDays, BOOL bUseLast )
{
STT_ASSERT_CALCULATE( m_pKData, nIndex, nDays );
int nCount = 0;
if( nDays > nIndex+1 )
return FALSE;
double dResult = 0;
for( int k=nIndex; k>=0; k-- )
{
dResult += m_pKData->ElementAt(k).m_fVolume;
nCount ++;
if( nCount == nDays )
{
if( pValue )
*pValue = dResult / nDays;
return TRUE;
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CNVI
CNVI::CNVI( )
{
SetDefaultParameters( );
}
CNVI::CNVI( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CNVI::~CNVI()
{
Clear( );
}
void CNVI::SetDefaultParameters( )
{
m_nMADays = 25;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CNVI::AttachParameters( CNVI & src )
{
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CNVI::IsValidParameters( )
{
return ( VALID_DAYS( m_nMADays ) && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CNVI::Clear( )
{
CTechnique::Clear( );
}
int CNVI::GetSignal( int nIndex, UINT * pnCode )
{
PrepareCache( 0, -1, FALSE );
// 金叉死叉
return GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
}
BOOL CNVI::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
NVI初值 = 100
如果今天成交量比昨日小 NVI = 前一日NVI + 100 * 涨跌幅 否则,NVI = 前一天NVI
*/
BOOL CNVI::Calculate( double * pValue, double *pMA, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
// Calculate
if( m_nMADays > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pValue, pMA ) )
return TRUE;
double dValueNew = 0, dMANew = 0;
if( bUseLast && pValue && pMA )
{
if( 0 == nIndex )
dValueNew = 100;
else if( m_pKData->ElementAt(nIndex).m_fVolume < m_pKData->ElementAt(nIndex-1).m_fVolume
&& m_pKData->MaindataAt(nIndex-1) > 1e-4 && m_pKData->MaindataAt(nIndex) > 1e-4 )
dValueNew = (*pValue) * m_pKData->MaindataAt(nIndex) / m_pKData->MaindataAt(nIndex-1);
else
dValueNew = *pValue;
dMANew = (*pMA) * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
StoreToCache( nIndex, &dValueNew, &dMANew );
}
else
{
for( int k=0; k<=nIndex; k++ )
{
if( 0 == k )
dValueNew = 100;
else if( m_pKData->ElementAt(k).m_fVolume < m_pKData->ElementAt(k-1).m_fVolume
&& m_pKData->MaindataAt(k-1) > 1e-4 && m_pKData->MaindataAt(k) > 1e-4 )
dValueNew = dValueNew * m_pKData->MaindataAt(k) / m_pKData->MaindataAt(k-1);
if( 0 == k )
dMANew = dValueNew;
else
dMANew = dMANew * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
StoreToCache( k, &dValueNew, &dMANew );
}
}
if( pValue ) *pValue = dValueNew;
if( pMA ) *pMA = dMANew;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CPVI
CPVI::CPVI( )
{
SetDefaultParameters( );
}
CPVI::CPVI( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CPVI::~CPVI()
{
Clear( );
}
void CPVI::SetDefaultParameters( )
{
m_nMADays = 25;
m_itsGoldenFork = ITS_BUY;
m_itsDeadFork = ITS_SELL;
}
void CPVI::AttachParameters( CPVI & src )
{
m_nMADays = src.m_nMADays;
m_itsGoldenFork = src.m_itsGoldenFork;
m_itsDeadFork = src.m_itsDeadFork;
}
BOOL CPVI::IsValidParameters( )
{
return ( VALID_DAYS( m_nMADays ) && VALID_ITS(m_itsGoldenFork) && VALID_ITS(m_itsDeadFork) );
}
void CPVI::Clear( )
{
CTechnique::Clear( );
}
int CPVI::GetSignal( int nIndex, UINT * pnCode )
{
PrepareCache( 0, -1, FALSE );
// 金叉死叉
return GetForkSignal( nIndex, m_itsGoldenFork, m_itsDeadFork, pnCode );
}
BOOL CPVI::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
PVI初值100
如果今天成交量比昨日大 PVI = 前一日PVI + 100 * 涨跌幅 否则,PVI = 前一日PVI
*/
BOOL CPVI::Calculate( double * pValue, double *pMA, int nIndex, BOOL bUseLast )
{
STT_ASSERT_CALCULATE1( m_pKData, nIndex );
// Calculate
if( m_nMADays > nIndex+1 )
return FALSE;
if( LoadFromCache( nIndex, pValue, pMA ) )
return TRUE;
double dValueNew = 0, dMANew = 0;
if( bUseLast && pValue && pMA )
{
if( 0 == nIndex )
dValueNew = 100;
else if( m_pKData->ElementAt(nIndex).m_fVolume > m_pKData->ElementAt(nIndex-1).m_fVolume
&& m_pKData->MaindataAt(nIndex-1) > 1e-4 && m_pKData->MaindataAt(nIndex) > 1e-4 )
dValueNew = (*pValue) * m_pKData->MaindataAt(nIndex) / m_pKData->MaindataAt(nIndex-1);
else
dValueNew = *pValue;
dMANew = (*pMA) * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
StoreToCache( nIndex, &dValueNew, &dMANew );
}
else
{
for( int k=0; k<=nIndex; k++ )
{
if( 0 == k )
dValueNew = 100;
else if( m_pKData->ElementAt(k).m_fVolume > m_pKData->ElementAt(k-1).m_fVolume
&& m_pKData->MaindataAt(k-1) > 1e-4 && m_pKData->MaindataAt(k) > 1e-4 )
dValueNew = dValueNew * m_pKData->MaindataAt(k) / m_pKData->MaindataAt(k-1);
if( 0 == k )
dMANew = dValueNew;
else
dMANew = dMANew * (m_nMADays-1) / (m_nMADays+1) + dValueNew * 2 / (m_nMADays+1);
StoreToCache( k, &dValueNew, &dMANew );
}
}
if( pValue ) *pValue = dValueNew;
if( pMA ) *pMA = dMANew;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CVR
CVR::CVR( )
{
SetDefaultParameters( );
}
CVR::CVR( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CVR::~CVR()
{
Clear( );
}
void CVR::SetDefaultParameters( )
{
m_nDays = 12;
m_itsLong = ITS_BUY;
m_itsShort = ITS_SELL;
}
void CVR::AttachParameters( CVR & src )
{
m_nDays = src.m_nDays;
m_itsLong = src.m_itsLong;
m_itsShort = src.m_itsShort;
}
BOOL CVR::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays) && VALID_ITS(m_itsLong) && VALID_ITS(m_itsShort) );
}
void CVR::Clear( )
{
CTechnique::Clear( );
}
int CVR::GetSignal( int nIndex, UINT * pnCode )
{
if( pnCode ) *pnCode = ITSC_NOTHING;
if( !m_pKData || nIndex < 0 || nIndex >= m_pKData->GetSize() )
return ITS_NOTHING;
int nMaxDays = m_nDays;
double dLiminalLow = 0, dLiminalHigh = 0;
if( !IntensityPrepare( nIndex, pnCode, nMaxDays, ITS_GETMINMAXDAYRANGE, &dLiminalLow, &dLiminalHigh, 0.309, 0.682 ) )
return ITS_NOTHING;
double dNowClose = m_pKData->ElementAt(nIndex).m_fClose;
double dVRNow;
if( !Calculate( &dVRNow, nIndex, FALSE ) )
return ITS_NOTHING;
int nIntensity = GetTrendIntensity1( nIndex, m_itsLong, m_itsShort, pnCode );
if( dVRNow < dLiminalLow && nIntensity == m_itsLong )
{ // 低位趋势向上
if( pnCode ) *pnCode = ITSC_LONG;
return m_itsLong;
}
if( dVRNow > dLiminalHigh && nIntensity == m_itsShort )
{ // 高位趋势向下
if( pnCode ) *pnCode = ITSC_SHORT;
return m_itsShort;
}
return ITS_NOTHING;
}
BOOL CVR::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo1( nStart, nEnd, pdMin, pdMax, this );
}
/***
n日中上涨日成交量+1/2最近n日总成交量
VR = ————————————---------—- ×100
n日中下跌日成交量+1/2最近n日总成交量
*/
BOOL CVR::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 dINTV = 0, dDETV = 0, dTV = 0;
int nCount = 0;
for( int k=nIndex; k>=1; k-- )
{
double dAmount = m_pKData->ElementAt(k).m_fVolume;
if( m_pKData->MaindataAt(k) > m_pKData->MaindataAt(k-1) )
dINTV += dAmount;
if( m_pKData->MaindataAt(k) < m_pKData->MaindataAt(k-1) )
dDETV += dAmount;
dTV += dAmount;
nCount ++;
if( nCount == m_nDays )
{
if( dDETV + dTV/2 < 1e-4 )
return FALSE;
if( pValue ) *pValue = (dINTV + dTV/2) * 100 /(dDETV + dTV/2);
StoreToCache( nIndex, pValue );
return TRUE;
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CVROC
CVROC::CVROC( )
{
SetDefaultParameters( );
}
CVROC::CVROC( CKData * pKData )
: CTechnique( pKData )
{
SetDefaultParameters( );
}
CVROC::~CVROC()
{
Clear( );
}
void CVROC::SetDefaultParameters( )
{
m_nDays = 10;
m_nMADays = 10;
m_itsDeviateOnBottom = ITS_BUY;
m_itsDeviateOnTop = ITS_SELL;
}
void CVROC::AttachParameters( CVROC & src )
{
m_nDays = src.m_nDays;
m_nMADays = src.m_nMADays;
m_itsDeviateOnBottom = src.m_itsDeviateOnBottom;
m_itsDeviateOnTop = src.m_itsDeviateOnTop;
}
BOOL CVROC::IsValidParameters( )
{
return ( VALID_DAYS(m_nDays) && VALID_DAYS(m_nMADays)
&& VALID_ITS(m_itsDeviateOnBottom) && VALID_ITS(m_itsDeviateOnTop) );
}
void CVROC::Clear( )
{
CTechnique::Clear( );
}
int CVROC::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 ) )
return ITS_NOTHING;
if( IsDeviateOnBottom( nIndex, m_pdCache1, m_pdCache2 ) )
{ // 底背离
if( pnCode ) *pnCode = ITSC_DEVIATEONBOTTOM;
return m_itsDeviateOnBottom;
}
if( IsDeviateOnTop( nIndex, m_pdCache1, m_pdCache2 ) )
{ // 顶背离
if( pnCode ) *pnCode = ITSC_DEVIATEONTOP;
return m_itsDeviateOnTop;
}
return ITS_NOTHING;
}
BOOL CVROC::GetMinMaxInfo(int nStart, int nEnd, double *pdMin, double *pdMax )
{
return AfxGetMinMaxInfo2( nStart, nEnd, pdMin, pdMax, this );
}
/***
今日成交量-n日前成交量
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -