?? strategy.cpp
字號:
// 操作記錄數組,加入記錄
int COpRecordContainer::AddRecord(long lOpType, CSPTime tm, const char *szCode,
DWORD dwShare, double dSharePrice, double dRateCost )
{
SP_ASSERT( NULL != szCode && strlen(szCode) > 0 );
if( NULL == szCode || strlen(szCode) <= 0 )
return -1;
OPRECORD record;
memset( &record, 0, sizeof(record) );
record.lOpType = lOpType;
record.time = tm.GetTime();
strncpy( record.szCode, szCode, min(sizeof(record.szCode)-1,strlen(szCode)) );
record.dwShare = dwShare;
record.dSharePrice = dSharePrice;
record.dRateCost = dRateCost;
record.dwMarket = CStock::marketUnknown;
return Add( record );
}
// 操作記錄數組,加入記錄,記錄中如果已經有該股票的記錄,更改為現在的信息
int COpRecordContainer::AddRecordUniqueStock(long lOpType, CSPTime tm, const char *szCode,
DWORD dwShare, double dSharePrice, double dRateCost )
{
SP_ASSERT( NULL != szCode && strlen(szCode) > 0 );
if( NULL == szCode || strlen(szCode) <= 0 )
return -1;
OPRECORD record;
memset( &record, 0, sizeof(record) );
for( int i=0; i<GetSize(); i++ )
{
if( 0 == strncmp( ElementAt(i).szCode, szCode, sizeof(record.szCode) ) )
{
ElementAt(i).lOpType = lOpType;
ElementAt(i).time = tm.GetTime();
strncpy( ElementAt(i).szCode, szCode, min(sizeof(ElementAt(i).szCode)-1,strlen(szCode)) );
ElementAt(i).dwShare = dwShare;
ElementAt(i).dSharePrice = dSharePrice;
ElementAt(i).dRateCost = dRateCost;
ElementAt(i).dwMarket = CStock::marketUnknown;
return i;
}
}
record.lOpType = lOpType;
record.time = tm.GetTime();
strncpy( record.szCode, szCode, min(sizeof(record.szCode)-1,strlen(szCode)) );
record.dwShare = dwShare;
record.dSharePrice = dSharePrice;
record.dRateCost = dRateCost;
record.dwMarket = CStock::marketUnknown;
return Add( record );
}
// 操作記錄數組,得到買入記錄數
int COpRecordContainer::GetBuyRecordCount()
{
int nCount = 0;
for( int i=0; i<GetSize(); i++ )
{
OPRECORD & record = ElementAt(i);
if( STRATEGY_OPTYPE_BUY == record.lOpType )
nCount ++;
}
return nCount;
}
// 操作記錄數組,是否有szCode股票的買入記錄
BOOL COpRecordContainer::HasBuyStock( const char * szCode )
{
if( NULL == szCode || strlen(szCode) < 0 )
return FALSE;
for( int i=0; i<GetSize(); i++ )
{
OPRECORD & record = ElementAt(i);
if( STRATEGY_OPTYPE_BUY == record.lOpType )
{
if( 0 == strncmp( record.szCode, szCode, min(sizeof(record.szCode),strlen(szCode)) ) )
return TRUE;
}
}
return FALSE;
}
// 操作記錄數組,統計結果:操作次數,成功次數,最大收益,最低收益
BOOL COpRecordContainer::StatResults( int *pnTimes, int *pnVictoryTimes, double *pdYieldMax, double *pdYieldMin )
{
int nTimes = 0, nVictoryTimes = 0;
double dYieldMax = 0, dYieldMin = 0;
for( int i=0; i<GetSize(); i++ )
{
OPRECORD & record = ElementAt(i);
if( STRATEGY_OPTYPE_BUY != record.lOpType )
continue;
// 查找當前買入操作的對應賣出操作
for( int j=i+1; j<GetSize(); j++ )
{
OPRECORD & record2 = ElementAt(j);
if( STRATEGY_OPTYPE_SELL == record2.lOpType && 0 == strncmp(record.szCode,record2.szCode,sizeof(record.szCode)) )
{ // 如果是賣出操作,根據買入價格和賣出價格計算收益率
if( record.dwShare > 0 && record2.dwShare > 0 )
{
double dBuy = record.dSharePrice + record.dRateCost/record.dwShare;
double dSell = record2.dSharePrice - record2.dRateCost/record2.dwShare;
if( dBuy > 1e-4 )
{
double dYield = (dSell - dBuy)/dBuy;
nTimes ++;
if( dYield > 0 ) nVictoryTimes ++;
if( 1 == nTimes ) dYieldMax = dYieldMin = dYield;
if( dYieldMax < dYield ) dYieldMax = dYield;
if( dYieldMin > dYield ) dYieldMin = dYield;
}
}
break;
}
}
}
if( pnTimes ) *pnTimes = nTimes;
if( pnVictoryTimes ) *pnVictoryTimes = nVictoryTimes;
if( pdYieldMax ) *pdYieldMax = dYieldMax;
if( pdYieldMin ) *pdYieldMin = dYieldMin;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CAssetSerialContainer
// 資產序列數組,按時間排序插入
BOOL CAssetSerialContainer::SortInsert( ASSETSERIAL serial )
{
BOOL bAdded = FALSE;
for( int i=GetSize()-1; i>=0; i-- )
{
ASSETSERIAL & se = ElementAt(i);
if( se.time == serial.time )
{
se.dAsset = serial.dAsset;
se.dCash = serial.dCash;
bAdded = TRUE;
break;
}
else if( se.time < serial.time )
{
InsertAt( i+1, serial );
bAdded = TRUE;
break;
}
}
if( !bAdded )
InsertAt( 0, serial );
return TRUE;
}
// 資產序列數組,獲得資產序列標準差
BOOL CAssetSerialContainer::GetStdDev( double *pdStdDev, double *pdXiapu )
{
if( GetSize() <= 0 )
return FALSE;
double dInit = ElementAt(0).dAsset;
if( dInit < 1e-4 )
return FALSE;
double dSum = 0., dSquareSum = 0.;
for( int k = 0; k<GetSize(); k++ )
{
double dNow = (ElementAt(k).dAsset - dInit) / dInit;
dSum += dNow;
dSquareSum += dNow*dNow;
}
double dAverage = dSum / GetSize();
if( dAverage < 1e-4 )
return FALSE;
double dStdDev = dSquareSum / GetSize() - ( dAverage*dAverage );
if( dStdDev > 0 )
dStdDev = sqrt( dStdDev );
if( pdStdDev ) *pdStdDev = dStdDev;
if( pdXiapu ) *pdXiapu = (dStdDev / dAverage);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CTechStock
CTechStock::CTechStock( )
{
m_bAutoDelete = TRUE;
m_kdata.SetKType(CKData::ktypeDay);
m_kdataLong.SetKType(CKData::ktypeDay);
}
CTechStock::CTechStock( const CTechStock & src )
{
*this = src;
}
CTechStock & CTechStock::operator = ( const CTechStock &src )
{
m_bAutoDelete = FALSE;
m_info = src.m_info;
m_kdata = src.m_kdata;
m_kdataLong = src.m_kdataLong;
m_techs.Copy( src.m_techs );
m_techsLong.Copy( src.m_techsLong );
return *this;
}
void CTechStock::SetAutoDelete( BOOL bAutoDelete )
{
m_bAutoDelete = bAutoDelete;
}
CTechStock::~CTechStock( )
{
Clear( );
}
// 清除內存
void CTechStock::Clear( )
{
if( m_bAutoDelete )
{
int i=0;
for( i=0; i<m_techs.GetSize(); i++ )
{
CTechnique * pTech = (CTechnique *)m_techs.ElementAt(i);
if( pTech )
delete pTech;
}
for( i=0; i<m_techsLong.GetSize(); i++ )
{
CTechnique * pTech = (CTechnique *)m_techsLong.ElementAt(i);
if( pTech )
delete pTech;
}
}
m_techs.RemoveAll();
m_techsLong.RemoveAll();
}
// 指定日期,指定操作,指定委托價格,得到股票的成交價格
BOOL CTechStock::GetPriceOK( long lOpType, CSPTime tmCur, DWORD dwShare, double dSharePrice, double *pdPriceOK )
{
double dPriceOK = dSharePrice;
CSPTime sptimeCur(tmCur.GetTime());
DWORD dwDate = sptimeCur.ToStockTimeDay();
int nIndex = m_kdata.GetIndexByDate( dwDate );
if( -1 == nIndex )
return FALSE;
KDATA & kd = m_kdata.ElementAt(nIndex);
if( STRATEGY_OPTYPE_BUY == lOpType )
{
if( dSharePrice < kd.m_fLow )
return FALSE;
if( dSharePrice > kd.m_fOpen )
dPriceOK = kd.m_fOpen;
else
dPriceOK = dSharePrice;
}
else if( STRATEGY_OPTYPE_SELL == lOpType )
{
if( dSharePrice > kd.m_fHigh )
return FALSE;
if( dSharePrice < kd.m_fOpen )
dPriceOK = kd.m_fOpen;
else
dPriceOK = dSharePrice;
}
else
return FALSE;
if( pdPriceOK ) *pdPriceOK = dPriceOK;
return TRUE;
}
// 指定日期是否停牌
BOOL CTechStock::IsStopTrading( CSPTime tmCur )
{
CSPTime sptimeCur(tmCur.GetTime());
DWORD dwDate = sptimeCur.ToStockTimeDay();
int nIndex = m_kdata.GetIndexByDate( dwDate );
if( -1 == nIndex )
{
if( -1 != m_kdata.GetAboutIndexByDate( dwDate ) )
return TRUE;
return FALSE;
}
KDATA & kd = m_kdata.ElementAt(nIndex);
float fLastClose = kd.m_fOpen;
if( nIndex > 0 )
fLastClose = m_kdata.ElementAt(nIndex-1).m_fClose;
if( fabs(kd.m_fOpen-kd.m_fClose) < 1e-4 && fabs(kd.m_fOpen-kd.m_fHigh) < 1e-4
&& fabs(kd.m_fOpen-kd.m_fLow) < 1e-4 && fabs(kd.m_fOpen-fLastClose) < 1e-4 )
return TRUE;
return FALSE;
}
// 得到股票的收盤價
BOOL CTechStock::GetClosePrice( CSPTime tmCur, double *pdPrice )
{
CSPTime sptimeCur(tmCur.GetTime());
DWORD dwDate = sptimeCur.ToStockTimeDay();
int nIndex = m_kdata.GetAboutIndexByDate( dwDate );
if( -1 == nIndex )
{
SP_ASSERT( FALSE );
return FALSE;
}
KDATA & kd = m_kdata.ElementAt(nIndex);
if( pdPrice ) *pdPrice = kd.m_fClose;
return TRUE;
}
// 得到股票的收盤價漲幅%
BOOL CTechStock::GetCloseDiffPercent( CSPTime tmCur, double *pdDiffPercent )
{
if( pdDiffPercent ) *pdDiffPercent = 0;
CSPTime sptimeCur(tmCur.GetTime());
DWORD dwDate = sptimeCur.ToStockTimeDay();
int nIndex = m_kdata.GetIndexByDate( dwDate );
if( -1 == nIndex || nIndex <= 0 )
{
return FALSE;
}
KDATA & kd = m_kdata.ElementAt(nIndex);
KDATA & kdLast = m_kdata.ElementAt(nIndex-1);
if( pdDiffPercent && kdLast.m_fClose > 1e-4 )
{
*pdDiffPercent = 100. * (kd.m_fClose-kdLast.m_fClose)/kdLast.m_fClose;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CTechStockContainer
CTechStockContainer::~CTechStockContainer( )
{
Clear( );
}
void CTechStockContainer::Clear( )
{
m_infoIndex.Clear();
m_kdataIndex.Clear();
m_kdataIndex.SetKType(CKData::ktypeDay);
int i=0;
for( i=0; i<m_techsIndex.GetSize(); i++ )
{
CTechnique * pTech = (CTechnique *)m_techsIndex.ElementAt(i);
if( pTech )
delete pTech;
}
m_techsIndex.RemoveAll();
for( i=0; i<GetSize(); i++ )
{
CTechStock & stock = ElementAt(i);
stock.Clear( );
}
RemoveAll();
}
// 給定CTechStock,日期tmCur,資金dCash,交易費率rate,操作條件opparam,
// 現在擁有股票數量nOwnedStockCount,計算需要買入的股票數量和委托價格及委托時間,
// 如果不需要買入,返回FALSE
BOOL CTechStockContainer::GetShouldBuyShare( CTechStock & techstock, CSPTime tmCur, double dCash, CRateParam &rate, COpParam &opparam, int nOwnedStockCount,
CSPTime *ptmOp, DWORD *pdwShare, double *pdSharePrice )
{
CSPTime tmOp = tmCur;
DWORD dwShare = 0;
double dSharePrice = 0;
CSPTime sptimeCur(tmCur.GetTime());
DWORD dwDate = sptimeCur.ToStockTimeDay();
int nIndex = techstock.m_kdata.GetIndexByDate( dwDate ); // 得到nIndex,指向techstock.m_kdata數組的當前日期位置
if( -1 == nIndex )
return FALSE;
double dPriceNow = techstock.m_kdata.ElementAt(nIndex).m_fClose; // 當前價
// 買入判斷
BOOL bBuy = TRUE;
if( COpParam::logicOr == opparam.m_nBuyLogic ) // 全部條件還是任一條件
bBuy = FALSE;
for( int i=0; i<techstock.m_techs.GetSize(); i++ ) // 每一個設定指標,分別判斷
{
CTechnique * pTech = (CTechnique *)techstock.m_techs.ElementAt(i); // 技術指標
SP_ASSERT( NULL != pTech );
if( NULL == pTech )
continue;
int nIntensity = pTech->GetSignal( nIndex ); // 當前買賣信號
if( COpParam::logicOr == opparam.m_nBuyLogic )
{
if( nIntensity >= opparam.m_nBuyLimit ) // 買賣信號是否達到所需條件
bBuy = TRUE;
}
else
{
if( nIntensity < opparam.m_nBuyLimit )
bBuy = FALSE;
}
}
// Long and Index Trend
if( bBuy )
{
// 如果技術指標判斷為買入,判斷是否滿足長周期趨勢和指數趨勢
if( opparam.m_bLongTrend ) // 長周期趨勢
{
int nIndexLong = techstock.m_kdataLong.GetAboutIndexByDate( dwDate );
if( opparam.m_nKTypeLong > opparam.m_nKType )
nIndexLong --;
if( nIndexLong >= 0 )
{
for( int i=0; i<techstock.m_techsLong.GetSize(); i++ )
{
CTechnique * pTech = (CTechnique *)techstock.m_techsLong.ElementAt(i);
SP_ASSERT( NULL != pTech );
if( NULL == pTech )
continue;
pTech->ClearLastIntensity();
int nIntensity = pTech->GetIntensity( nIndexLong ); // 得到當前趨勢
if( !ITS_ISBUY(nIntensity) )
bBuy = FALSE;
}
}
}
if( opparam.m_bIndexTrend ) // 指數趨勢
{
int nIndexIndex = m_kdataIndex.GetAboutIndexByDate( dwDate );
if( opparam.m_nKTypeIndex > opparam.m_nKType )
nIndexIndex --;
if( nIndexIndex >= 0 )
{
for( int i=0; i<m_techsIndex.GetSize(); i++ )
{
CTechnique * pTech = (CTechnique *)m_techsIndex.ElementAt(i);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -