📄 strategy.cpp.svn-base
字号:
SP_ASSERT( NULL != pTech );
if( NULL == pTech )
continue;
pTech->ClearLastIntensity();
int nIntensity = pTech->GetIntensity( nIndexIndex );
if( !ITS_ISBUY(nIntensity) )
bBuy = FALSE;
}
}
}
}
if( bBuy ) // 确定买入了
{
if( !opparam.GetNextTradeTime(tmCur, tmOp) ) // 操作日期,下一个交易日
return FALSE;
if( opparam.m_nStoreDiv-nOwnedStockCount <= 0 ) // 股票已经够多了,不能再买入新的了
return FALSE;
double dUseCash = dCash / (opparam.m_nStoreDiv-nOwnedStockCount); // 需使用资金
if( dCash < dUseCash )
dUseCash = dCash; // 资金不够,则有多少用多少
dSharePrice = opparam.m_dBuyMulti * dPriceNow;
double dTemp = dSharePrice * ( 1 + rate.GetRate( techstock.m_info ) );
if( fabs(dTemp) < 1e-4 || dUseCash < 1e-4 )
return FALSE;
dwShare = (DWORD)( dUseCash / dTemp ); // 买入股数
dwShare = ( dwShare / 100 ) * 100; // 取整
if( 0 == dwShare )
return FALSE;
if( ptmOp ) *ptmOp = tmOp;
if( pdwShare ) *pdwShare = dwShare;
if( pdSharePrice ) *pdSharePrice = dSharePrice;
return TRUE;
}
return FALSE;
}
// 给定CTechStock,日期tmCur,资金dCash,拥有股票own(含有买入时价格),操作条件opparam,
// 现在拥有股票数量nOwnedStockCount,计算需要卖出的股票数量和委托价格及委托时间,
// 如果不需要卖出,返回FALSE
BOOL CTechStockContainer::GetShouldSellShare( CTechStock & techstock, CSPTime tmCur, STOCKOWN & own, COpParam &opparam,
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 bSell = FALSE;
if( COpParam::logicAnd == opparam.m_nSellLogic ) // 全部条件还是任一条件
bSell = TRUE;
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::logicAnd == opparam.m_nSellLogic )
{
if( nIntensity > opparam.m_nSellLimit ) // 买卖信号是否达到所需条件
bSell = FALSE;
}
else
{
if( nIntensity <= opparam.m_nSellLimit )
bSell = TRUE;
}
}
// StopLosing and StopProfit 止损和止赢
if( opparam.m_bStopLosing && dPriceNow < own.dBuyPrice * (1-opparam.m_dStopLosing) ) // 止损
bSell = TRUE;
if( opparam.m_bStopProfit && dPriceNow > own.dBuyPrice * (1+opparam.m_dStopProfit) ) // 止赢
bSell = TRUE;
if( bSell ) // 确定卖出了
{
if( !opparam.GetNextTradeTime(tmCur, tmOp) ) // 操作日期,下一个交易日
return FALSE;
dwShare = own.dwShare;
dSharePrice = opparam.m_dSellMulti * dPriceNow;
if( ptmOp ) *ptmOp = tmOp;
if( pdwShare ) *pdwShare = dwShare;
if( pdSharePrice ) *pdSharePrice = dSharePrice;
return TRUE;
}
return FALSE;
}
// 得到某只股票szCode在日期tmCur的收盘价
BOOL CTechStockContainer::GetClosePrice( const char * szCode, CSPTime tmCur, double * pdPrice )
{
if( NULL == szCode || strlen(szCode) <= 0 || GetSize() <= 0 )
return FALSE;
for( int j=0; j<GetSize(); j++ )
{
CTechStock & techstock = ElementAt(j);
if( techstock.m_info.IsEqualTo( CStock::marketUnknown, szCode ) )
{
return techstock.GetClosePrice( tmCur, pdPrice );
}
}
return FALSE;
}
// 得到某日的总资产
BOOL CTechStockContainer::GetSumAsset( CSPTime tmCur, CStockOwnContainer &container, double * pdAsset )
{
if( GetSize() <= 0 )
return FALSE;
double dAsset = 0;
for( int i=0; i<container.GetSize(); i++ )
{
STOCKOWN & own = container.ElementAt(i);
double dPrice = 0;
if( !GetClosePrice( own.szCode, tmCur, &dPrice ) )
return FALSE;
dAsset += dPrice * own.dwShare;
}
if( pdAsset ) *pdAsset = dAsset;
return TRUE;
}
// 得到下一个有成交量的交易日
BOOL CTechStockContainer::GetNextExistTradeTime( CSPTime tmCur, CSPTime & tmNext )
{
CSPTime sptime(tmCur.GetTime());
DWORD dateCur = sptime.ToStockTimeDay( );
DWORD dateNext = -1;
for( int i=0; i<GetSize(); i++ )
{
CTechStock & techstock = ElementAt(i);
int nIndex = techstock.m_kdata.GetAboutIndexByDate( dateCur );
if( -1 != nIndex && nIndex+1 < techstock.m_kdata.GetSize() )
{
if( -1 == dateNext )
dateNext = techstock.m_kdata.ElementAt(nIndex+1).m_date;
else if( dateNext > techstock.m_kdata.ElementAt(nIndex+1).m_date )
dateNext = techstock.m_kdata.ElementAt(nIndex+1).m_date;
}
}
if( -1 != dateNext && sptime.FromStockTimeDay( dateNext ) )
{
tmNext = sptime.GetTime();
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CStrategy
// 给定策略文件,得到策略名称
CSPString CStrategy::GetName( LPCTSTR lpszPath )
{
if( NULL == lpszPath || strlen(lpszPath) <= 0 )
return "";
CSPString strName;
CStrategy doc;
CSPFile file;
if( file.Open( lpszPath, CSPFile::modeRead) )
{
CSPArchive ar(&file, CSPArchive::load | CSPArchive::bNoFlushOnDelete);
if( file.GetLength() > 0 )
doc.Serialize( ar, NULL, 0 );
ar.Close();
file.Close();
strName = doc.m_strName;
}
if( strName.IsEmpty() )
strName = lpszPath;
return strName;
}
/////////////////////////////////////////////////////////////////////////////
// CStrategy construction/destruction
char szCELFileMagic[] = "BALANG CEL FILE.";
DWORD dwCELFileVersion = 0x20000000;
CStrategy::CStrategy()
{
SimuReset( );
RealReset( );
}
CStrategy::~CStrategy()
{
ClearCache( );
}
// 打开策略文件
BOOL CStrategy::OpenStrategyFile( LPCTSTR lpszPathName, LPSTR lpErr, UINT nMaxSize )
{
CSPFile file;
if( NULL != lpszPathName && file.Open( lpszPathName, CSPFile::modeRead) )
{
if( 0 == file.GetLength() )
{
SetPathName(lpszPathName);
return TRUE;
}
CSPArchive ar(&file, CSPArchive::load | CSPArchive::bNoFlushOnDelete);
BOOL bSuccess = Serialize( ar, lpErr, nMaxSize );
ar.Close();
file.Close();
if( bSuccess )
SetPathName(lpszPathName);
return bSuccess;
}
SetPathName( NULL );
return FALSE;
}
BOOL CStrategy::SaveStrategyFile( LPCTSTR lpszPathName )
{
CSPString newName;
if( lpszPathName )
newName = lpszPathName;
if (newName.IsEmpty())
newName = m_strPathName;
CSPFile file;
if( file.Open( newName, CSPFile::modeCreate | CSPFile::modeWrite) )
{
CSPArchive ar(&file, CSPArchive::store);
Serialize( ar, NULL, 0 );
ar.Close();
file.Close();
SetPathName(newName);
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CStrategy serialization
// 文件保存和读取
BOOL CStrategy::Serialize(CSPArchive& ar, LPSTR lpErr, UINT nMaxSize )
{
if( lpErr && nMaxSize>0 )
memset(lpErr,0,nMaxSize);
if (ar.IsStoring())
{
ar.Write( szCELFileMagic, sizeof(szCELFileMagic) );
ar << dwCELFileVersion;
ar << m_strName;
ar << m_strDescript;
m_stocks.Serialize( ar );
m_rate.Serialize( ar );
m_paramBuy.Serialize( ar );
m_paramSell.Serialize( ar );
m_paramLongTrend.Serialize( ar );
m_paramIndexTrend.Serialize( ar );
m_anTechsBuy.Serialize( ar );
m_anTechsSell.Serialize( ar );
m_anTechsLongTrend.Serialize( ar );
m_anTechsIndexTrend.Serialize( ar );
m_opparam.Serialize( ar );
// Simulation
ar << m_SimuCurrentStatus;
ar << m_SimuCurrentTime;
ar << m_SimuCurrentCash;
m_SimuStockOwn.Serialize( ar );
m_SimuOpRecord.Serialize( ar );
m_SimuNextOp.Serialize( ar );
m_SimuAssetSerial.Serialize( ar );
// Real Operation
ar << m_RealBeginTime;
ar << m_RealCurrentTime;
ar << m_RealCurrentCash;
m_RealStockOwn.Serialize( ar );
m_RealOpRecord.Serialize( ar );
m_RealNextOp.Serialize( ar );
m_RealAssetSerial.Serialize( ar );
}
else
{
char buffer[sizeof(szCELFileMagic)+1];
if( sizeof(szCELFileMagic) != ar.Read( buffer, sizeof(szCELFileMagic) )
|| 0 != strncmp( buffer, szCELFileMagic, sizeof(szCELFileMagic) ) )
{
if( lpErr )
strncpy(lpErr,strategy_errfile,min(nMaxSize-1,strlen(strategy_errfile)) );
return FALSE;
}
ar >> m_dwFileVersion;
if( m_dwFileVersion > dwCELFileVersion )
{
if( lpErr )
strncpy(lpErr,strategy_errfilever,min(nMaxSize-1,strlen(strategy_errfilever)) );
return FALSE;
}
ar >> m_strName;
ar >> m_strDescript;
m_stocks.Serialize( ar );
m_rate.Serialize( ar );
m_paramBuy.Serialize( ar );
m_paramSell.Serialize( ar );
m_paramLongTrend.Serialize( ar );
m_paramIndexTrend.Serialize( ar );
m_anTechsBuy.Serialize( ar );
m_anTechsSell.Serialize( ar );
m_anTechsLongTrend.Serialize( ar );
m_anTechsIndexTrend.Serialize( ar );
m_opparam.Serialize( ar );
// Simulation
ar >> m_SimuCurrentStatus;
ar >> m_SimuCurrentTime;
ar >> m_SimuCurrentCash;
m_SimuStockOwn.Serialize( ar );
m_SimuOpRecord.Serialize( ar );
m_SimuNextOp.Serialize( ar );
m_SimuAssetSerial.Serialize( ar );
// Real Operation
ar >> m_RealBeginTime;
ar >> m_RealCurrentTime;
ar >> m_RealCurrentCash;
m_RealStockOwn.Serialize( ar );
m_RealOpRecord.Serialize( ar );
m_RealNextOp.Serialize( ar );
m_RealAssetSerial.Serialize( ar );
}
return TRUE;
}
BOOL CStrategy::DoFileSave( )
{
return SaveStrategyFile( GetPathName() );
}
BOOL CStrategy::OnClose( )
{
ClearCache( );
return TRUE;
}
void CStrategy::OnRealOpViewed( )
{
for( int i=0; i<m_RealNextOp.GetSize(); i++ )
m_RealNextOp.ElementAt(i).bViewed = TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CStrategy commands
void CStrategy::SetPathName( LPCTSTR lpszPathName )
{
m_strPathName = lpszPathName;
}
CSPString CStrategy::GetPathName( )
{
return m_strPathName;
}
// 设定策略名称
void CStrategy::SetName( LPCTSTR lpszName )
{
m_strName = lpszName;
}
// 得到策略名称
CSPString CStrategy::GetName( )
{
if( m_strName.IsEmpty() )
return GetPathName();
return m_strName;
}
// 设定策略描述
void CStrategy::SetDescript( LPCTSTR lpszDescript )
{
m_strDescript = lpszDescript;
}
// 得到策略描述
CSPString CStrategy::GetDescript( )
{
return m_strDescript;
}
// 得到策略被选股票
CSPStringArray & CStrategy::GetStocks( )
{
return m_stocks;
}
// 设定策略备选股票
void CStrategy::SetStocks( CSPStringArray & astr )
{
m_stocks.Copy( astr );
}
// 加入策略备选股票
void CStrategy::AddStock( LPCTSTR lpszCode )
{
m_stocks.AddStock( lpszCode );
}
// 移除策略备选股票
void CStrategy::RemoveStock( LPCTSTR lpszCode )
{
m_stocks.RemoveStock( lpszCode );
}
// 得到策略的一般性描述文字
CSPString CStrategy::GetStockTechString( )
{
int nStockShowCount = 3, nTechShowCount = 10;
CSPString strStock;
for( int i=0; i<m_stocks.GetSize() && i<nStockShowCount; i++ )
{
if( strStock.GetLength() > 0 )
strStock += ",";
CStockInfo info;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -