📄 strategy.cpp.svn-base
字号:
/*
Cross Platform Core Code.
Copyright(R) 2001-2002 Balang Software.
All rights reserved.
Using:
class CRateParam;
class COpParam;
class CStockOwnContainer;
class COpRecordContainer;
class CAssetSerialContainer;
class CTechStock;
class CTechStockContainer;
class CStrategy;
*/
#include "stdafx.h"
#include "../Include/Strategy.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRateParam
CRateParam::CRateParam( )
{
SetDefault( );
}
// 交易费用参数是否合法
BOOL CRateParam::IsValid( )
{
return (m_dShaa >= 0 && m_dShaa < 0.1
&& m_dShab >= 0 && m_dShab < 0.1
&& m_dShafund >= 0 && m_dShafund < 0.1
&& m_dSzna >= 0 && m_dSzna < 0.1
&& m_dSznb >= 0 && m_dSznb < 0.1
&& m_dSznfund >= 0 && m_dSznfund < 0.1 );
}
// 缺省交易费用
void CRateParam::SetDefault( )
{
m_dShaa = 0.003;
m_dShab = 0.003;
m_dShafund = 0.001;
m_dSzna = 0.003;
m_dSznb = 0.003;
m_dSznfund = 0.001;
}
// 保存交易费用至文件
void CRateParam::Serialize( CSPArchive &ar )
{
if( ar.IsStoring( ) )
{
ar << m_dShaa;
ar << m_dShab;
ar << m_dShafund;
ar << m_dSzna;
ar << m_dSznb;
ar << m_dSznfund;
}
else
{
ar >> m_dShaa;
ar >> m_dShab;
ar >> m_dShafund;
ar >> m_dSzna;
ar >> m_dSznb;
ar >> m_dSznfund;
}
}
// 根据股票选择交易费率
double CRateParam::GetRate( CStockInfo & info )
{
LONG stocktype = info.GetType();
if( CStock::typeshA == stocktype || CStock::typeshIndex == stocktype )
return m_dShaa;
else if( CStock::typeshB == stocktype )
return m_dShab;
else if( info.IsShangHai() && info.IsFund() )
return m_dShafund;
else if( CStock::typeszA == stocktype || CStock::typeszIndex == stocktype )
return m_dSzna;
else if( CStock::typeszB == stocktype )
return m_dSznb;
else if( info.IsShenZhen() && info.IsFund() )
return m_dSznfund;
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// COpParam
// 逻辑字符串,全部指标 任一指标
CSPString AfxGetLogicString( int nLogic )
{
switch( nLogic )
{
case COpParam::logicAnd: return strategy_logicand;
case COpParam::logicOr: return strategy_logicor;
default:
SP_ASSERT( FALSE );
}
return "";
}
// 仓位字符串
CSPString AfxGetStoreDivString( int nStoreDiv )
{
switch( nStoreDiv )
{
case COpParam::storedivOnce: return strategy_sdonce;
case COpParam::storedivTwice: return strategy_sdtwice;
case COpParam::storedivThird: return strategy_sdthird;
case COpParam::storedivForth: return strategy_sdforth;
case COpParam::storedivFifth: return strategy_sdfifth;
case COpParam::storedivSixth: return strategy_sdsixth;
case COpParam::storedivSeventh: return strategy_sdseventh;
case COpParam::storedivEighth: return strategy_sdeighth;
case COpParam::storedivNinth: return strategy_sdninth;
case COpParam::storedivTenth: return strategy_sdtenth;
default:
SP_ASSERT( FALSE );
}
return "";
}
COpParam::COpParam( )
{
SetDefault( );
}
// 操作条件是否合法
BOOL COpParam::IsValid( )
{
if( CKData::ktypeDay != m_nKType && CKData::ktypeWeek != m_nKType && CKData::ktypeMonth != m_nKType )
return FALSE;
if( m_nMaindataType < CKData::mdtypeMin || m_nMaindataType > CKData::mdtypeMax )
return FALSE;
if( m_nBuyLogic < logicMin || m_nBuyLogic > logicMax )
return FALSE;
if( m_nBuyLimit < ITS_MIN || m_nBuyLimit > ITS_MAX )
return FALSE;
if( m_dBuyMulti <= 0.89 || m_dBuyMulti > 1.11 )
return FALSE;
if( m_nSellLogic < logicMin || m_nSellLogic > logicMax )
return FALSE;
if( m_nSellLimit < ITS_MIN || m_nSellLimit > ITS_MAX )
return FALSE;
if( m_dSellMulti <= 0.89 || m_dSellMulti > 1.11 )
return FALSE;
if( m_atmBegin.GetSize() <= 0 || m_atmEnd.GetSize() <= 0
|| m_atmBegin.GetSize() != m_atmEnd.GetSize() )
return FALSE;
// TIMEZONES
if( m_nStartAmount < 1000 || m_nStartAmount > 2000000000 )
return FALSE;
if( m_nStoreDiv < storedivMin || m_nStoreDiv > COpParam::storedivMax )
return FALSE;
if( m_bStopLosing && ( m_dStopLosing <= 0 || m_dStopLosing >= 100 ) )
return FALSE;
if( m_bStopProfit && m_dStopProfit <= 0 )
return FALSE;
if( m_bLongTrend && CKData::ktypeDay != m_nKTypeLong && CKData::ktypeWeek != m_nKTypeLong && CKData::ktypeMonth != m_nKTypeLong )
return FALSE;
if( m_bIndexTrend && CKData::ktypeDay != m_nKTypeIndex && CKData::ktypeWeek != m_nKTypeIndex && CKData::ktypeMonth != m_nKTypeIndex )
return FALSE;
return TRUE;
}
// 缺省操作条件
void COpParam::SetDefault( )
{
m_nKType = CKData::ktypeDay;
m_nMaindataType = CKData::mdtypeClose;
m_nBuyLogic = logicAnd;
m_nBuyLimit = ITS_BUY;
m_dBuyMulti = 1.0;
m_nSellLogic = logicOr;
m_nSellLimit = ITS_SELL;
m_dSellMulti = 0.98;
CSPTime tmCurrent = CSPTime::GetCurrentTime();
m_atmBegin.RemoveAll();
m_atmEnd.RemoveAll();
m_atmBegin.Add( tmCurrent - CSPTimeSpan( 365 * 3, 0, 0, 0 ) );
m_atmEnd.Add( tmCurrent );
m_nStartAmount = 1000000;
m_nStoreDiv = storedivThird;
m_bStopLosing = FALSE;
m_bStopProfit = FALSE;
m_dStopLosing = 0.1;
m_dStopProfit = 0.3;
m_bLongTrend = FALSE;
m_bIndexTrend = FALSE;
m_nKTypeLong = CKData::ktypeWeek;
m_nKTypeIndex = CKData::ktypeWeek;
}
// 设定不合法的操作条件为缺省值
void COpParam::SetDefaultOfInvalidMember( )
{
if( CKData::ktypeDay != m_nKType && CKData::ktypeWeek != m_nKType && CKData::ktypeMonth != m_nKType )
m_nKType = CKData::ktypeDay;
if( m_nMaindataType < CKData::mdtypeMin || m_nMaindataType > CKData::mdtypeMax )
m_nMaindataType = CKData::mdtypeClose;
if( m_nBuyLogic < logicMin || m_nBuyLogic > logicMax )
m_nBuyLogic = logicAnd;
if( m_nBuyLimit < ITS_MIN || m_nBuyLimit > ITS_MAX )
m_nBuyLimit = ITS_BUY;
if( m_dBuyMulti <= 0.89 || m_dBuyMulti > 1.11 )
m_dBuyMulti = 1.0;
if( m_nSellLogic < logicMin || m_nSellLogic > logicMax )
m_nSellLogic = logicOr;
if( m_nSellLimit < ITS_MIN || m_nSellLimit > ITS_MAX )
m_nSellLimit = ITS_SELL;
if( m_dSellMulti <= 0.89 || m_dSellMulti > 1.11 )
m_dSellMulti = 0.98;
if( m_atmBegin.GetSize() <= 0 || m_atmEnd.GetSize() <= 0
|| m_atmBegin.GetSize() != m_atmEnd.GetSize() )
{
m_atmBegin.RemoveAll();
m_atmEnd.RemoveAll();
CSPTime tmCurrent = CSPTime::GetCurrentTime();
m_atmBegin.Add( tmCurrent - CSPTimeSpan( 365 * 3, 0, 0, 0 ) );
m_atmEnd.Add( tmCurrent );
}
// TIMEZONES
if( m_nStartAmount < 1000 || m_nStartAmount > 2000000000 )
m_nStartAmount = 1000000;
if( m_nStoreDiv < storedivMin || m_nStoreDiv > storedivMax )
m_nStoreDiv = storedivThird;
if( m_bStopLosing && ( m_dStopLosing <= 0 || m_dStopLosing >= 100 ) )
m_dStopLosing = 0.1;
if( m_bStopProfit && m_dStopProfit <= 0 )
m_dStopProfit = 0.3;
if( m_bLongTrend && CKData::ktypeDay != m_nKTypeLong && CKData::ktypeWeek != m_nKTypeLong && CKData::ktypeMonth != m_nKTypeLong )
m_nKTypeLong = CKData::ktypeWeek;
if( m_bIndexTrend && CKData::ktypeDay != m_nKTypeIndex && CKData::ktypeWeek != m_nKTypeIndex && CKData::ktypeMonth != m_nKTypeIndex )
m_nKTypeIndex = CKData::ktypeWeek;
}
// 保存或者读取硬盘文件
void COpParam::Serialize( CSPArchive &ar )
{
if( ar.IsStoring( ) )
{
ar << m_nKType;
ar << m_nMaindataType;
ar << m_nBuyLogic;
ar << m_nBuyLimit;
ar << m_dBuyMulti;
ar << m_nSellLogic;
ar << m_nSellLimit;
ar << m_dSellMulti;
m_atmBegin.Serialize( ar );
m_atmEnd.Serialize( ar );
ar << m_nStartAmount;
ar << m_nStoreDiv;
ar << m_bStopLosing;
ar << m_bStopProfit;
ar << m_dStopLosing;
ar << m_dStopProfit;
ar << m_bLongTrend;
ar << m_bIndexTrend;
ar << m_nKTypeLong;
ar << m_nKTypeIndex;
}
else
{
ar >> m_nKType;
ar >> m_nMaindataType;
ar >> m_nBuyLogic;
ar >> m_nBuyLimit;
ar >> m_dBuyMulti;
ar >> m_nSellLogic;
ar >> m_nSellLimit;
ar >> m_dSellMulti;
m_atmBegin.Serialize( ar );
m_atmEnd.Serialize( ar );
ar >> m_nStartAmount;
ar >> m_nStoreDiv;
ar >> m_bStopLosing;
ar >> m_bStopProfit;
ar >> m_dStopLosing;
ar >> m_dStopProfit;
ar >> m_bLongTrend;
ar >> m_bIndexTrend;
ar >> m_nKTypeLong;
ar >> m_nKTypeIndex;
}
}
// 给定时间是不是在模拟时间内
BOOL COpParam::IsInTimeZones( CSPTime tm )
{
for( int i=0; i<m_atmBegin.GetSize() && i<m_atmEnd.GetSize(); i++ )
{
if( tm >= m_atmBegin.ElementAt(i) && tm <= m_atmEnd.ElementAt(i) )
return TRUE;
}
return FALSE;
}
// 获取模拟开始时间
CSPTime COpParam::GetBeginTime( )
{
if( m_atmBegin.GetSize() > 0 )
return m_atmBegin.ElementAt(0);
return CSPTime::GetCurrentTime();
}
// 获取模拟结束时间
CSPTime COpParam::GetEndTime( )
{
if( m_atmEnd.GetSize() > 0 )
return m_atmEnd.ElementAt(m_atmEnd.GetSize()-1);
return CSPTime::GetCurrentTime();
}
// 获取下一个交易时间
BOOL COpParam::GetNextTradeTime( CSPTime tmNow, CSPTime &tmNext )
{
CSPTime sptime( tmNow.GetTime() );
DWORD dwDate = sptime.ToStockTime( CKData::IsDayOrMin(m_nKType) );
DWORD dwDateNext = CSPTime::GetStockTimeNext( dwDate, m_nKType );
if( sptime.FromStockTime( dwDateNext, CKData::IsDayOrMin(m_nKType) ) )
{
tmNext = sptime.GetTime();
return TRUE;
}
return FALSE;
}
// 获取当前模拟进度
DWORD COpParam::GetProgress( CSPTime tmNow, DWORD dwProgressMax )
{
// TIMEZONES
if( !IsInTimeZones( tmNow ) )
return 0;
CSPTime tmBegin = GetBeginTime( );
CSPTime tmEnd = GetEndTime( );
double dBeginNow = ( tmNow.GetTime() - tmBegin.GetTime() );
double dBeginEnd = ( tmEnd.GetTime() - tmBegin.GetTime() );
double dProgress = 0;
if( fabs(dBeginEnd) > 1e-4 )
{
dProgress = ( dBeginNow / dBeginEnd ) * dwProgressMax;
}
return (DWORD)dProgress;
}
/////////////////////////////////////////////////////////////////////////////
// CStockOwnContainer
// 拥有股票数组,加入股票
BOOL CStockOwnContainer::AddStock( CStockInfo & info, DWORD dwShare, double dBuyPrice )
{
if( dwShare <= 0 )
return FALSE;
// 如果已经有了,改变数量
for( int i=0; i<GetSize(); i++ )
{
STOCKOWN & own = ElementAt(i);
if( info.IsEqualTo( own.dwMarket, own.szCode ) )
{
if( dBuyPrice > 0.005 && own.dwShare + dwShare > 0 )
{
own.dBuyPrice = (own.dBuyPrice * own.dwShare + dBuyPrice * dwShare) / (own.dwShare + dwShare);
}
own.dwShare += dwShare;
return TRUE;
}
}
// 加入新的
STOCKOWN ownnew;
memset( &ownnew, 0, sizeof(ownnew) );
strncpy( ownnew.szCode, info.GetStockCode(), min(sizeof(ownnew.szCode)-1,strlen(info.GetStockCode())) );
ownnew.dwShare = dwShare;
ownnew.dBuyPrice = dBuyPrice;
ownnew.dwMarket = info.GetMarket();
return ( Add(ownnew) >= 0 );
}
// 拥有股票数组,移除股票
BOOL CStockOwnContainer::RemoveStock( CStockInfo & info, DWORD dwShare )
{
for( int i=0; i<GetSize(); i++ )
{
STOCKOWN & own = ElementAt(i);
if( info.IsEqualTo( own.dwMarket, own.szCode ) )
{
if( own.dwShare < dwShare )
return FALSE;
own.dwShare -= dwShare;
if( 0 == own.dwShare )
RemoveAt(i);
return TRUE;
}
}
return FALSE;
}
// 拥有股票数组,是否有这个股票,如果有,返回至lpOwn
BOOL CStockOwnContainer::HasThisStock( CStockInfo & info, LPSTOCKOWN lpOwn )
{
for( int i=0; i<GetSize(); i++ )
{
STOCKOWN & own = ElementAt(i);
if( info.IsEqualTo( own.dwMarket, own.szCode ) )
{
if( lpOwn )
memcpy( lpOwn, &own, sizeof(own) );
return ( own.dwShare > 0 );
}
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// COpRecordContainer
// 操作描述
CSPString AfxGetStrategyOpTypeString( long lOpType )
{
CSPString strOp;
if( STRATEGY_OPTYPE_BUY == lOpType )
return strategy_optype_buy;
else if( STRATEGY_OPTYPE_SELL == lOpType )
return strategy_optype_sell;
else if( STRATEGY_OPTYPE_ADDSTOCK == lOpType )
return strategy_optype_addstock;
else if( STRATEGY_OPTYPE_REMOVESTOCK == lOpType )
return strategy_optype_removestock;
else if( STRATEGY_OPTYPE_ADDCASH == lOpType )
return strategy_optype_addcash;
else if( STRATEGY_OPTYPE_REMOVECASH == lOpType )
return strategy_optype_removecash;
return strOp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -