?? strategy.cpp
字號:
AfxGetDB().GetTimeLocalRange( &tmLatest, NULL, NULL );
m_RealBeginTime = tmLatest;
m_RealCurrentTime = tmLatest;
m_RealCurrentCash = m_opparam.m_nStartAmount;
m_RealOpRecord.RemoveAll();
m_RealNextOp.RemoveAll();
m_RealStockOwn.RemoveAll();
m_RealAssetSerial.RemoveAll();
SP_ASSERT( m_opparam.IsValid() );
}
// 策略實戰:下一個交易時間
BOOL CStrategy::RealGotoNextTime( )
{
CSPTime tmNext;
if( m_techstocks.GetNextExistTradeTime( RealGetCurrentTime(), tmNext ) )
{
m_RealCurrentTime = tmNext;
return TRUE;
}
return FALSE;
}
// 策略實戰:開始時間
CSPTime CStrategy::RealGetBeginTime( )
{
return m_RealBeginTime;
}
// 策略實戰:當前時間
CSPTime CStrategy::RealGetCurrentTime( )
{
return m_RealCurrentTime;
}
// 策略實戰:當前資金
double CStrategy::RealGetCurrentCash( )
{
return m_RealCurrentCash;
}
// 策略實戰:執行一個操作
BOOL CStrategy::RealOperate( OPRECORD record, BOOL bTimeStrict )
{
if( bTimeStrict && m_RealOpRecord.GetSize() > 0 && record.time < m_RealOpRecord.ElementAt(m_RealOpRecord.GetSize()-1).time )
return FALSE;
CStockInfo info;
if( strlen(record.szCode)>0
&& ( !AfxGetStockContainer().GetStockInfo( record.szCode, &info )
|| !info.IsValidStock() ) )
return FALSE;
double dAmount = record.dwShare * record.dSharePrice;
double dRateCost = record.dRateCost;
if( STRATEGY_OPTYPE_BUY == record.lOpType ) // 買入
{
if( m_RealCurrentCash < dAmount+dRateCost )
return FALSE;
if( !m_RealStockOwn.AddStock( info, record.dwShare, record.dSharePrice ) )
return FALSE;
m_RealCurrentCash -= (dAmount+dRateCost);
}
else if( STRATEGY_OPTYPE_SELL == record.lOpType ) // 賣出
{
if( !m_RealStockOwn.RemoveStock( info, record.dwShare ) )
return FALSE;
m_RealCurrentCash += (dAmount-dRateCost);
}
else if( STRATEGY_OPTYPE_ADDSTOCK == record.lOpType ) // 添加股票
{
if( !m_RealStockOwn.AddStock( info, record.dwShare, record.dSharePrice ) )
return FALSE;
}
else if( STRATEGY_OPTYPE_REMOVESTOCK == record.lOpType ) // 移除股票
{
if( !m_RealStockOwn.RemoveStock( info, record.dwShare ) )
return FALSE;
}
else if( STRATEGY_OPTYPE_ADDCASH == record.lOpType ) // 加入資金
{
m_RealCurrentCash += record.dSharePrice;
}
else if( STRATEGY_OPTYPE_REMOVECASH == record.lOpType ) // 移除資金
{
if( m_RealCurrentCash < record.dSharePrice )
return FALSE;
m_RealCurrentCash -= record.dSharePrice;
}
else
return FALSE;
// Record
m_RealOpRecord.Add( record );
return TRUE;
}
// 策略實戰:操作記錄
COpRecordContainer & CStrategy::RealGetOpRecord( )
{
return m_RealOpRecord;
}
// 策略實戰:下一步操作計劃
COpRecordContainer & CStrategy::RealGetNextOp( )
{
return m_RealNextOp;
}
// 策略實戰:當前擁有股票
CStockOwnContainer & CStrategy::RealGetStockOwn( )
{
return m_RealStockOwn;
}
// 策略實戰:總資產序列
CAssetSerialContainer & CStrategy::RealGetAssetSerial( )
{
return m_RealAssetSerial;
}
// 策略實戰:得到指定日期的總資產
double CStrategy::RealGetAsset( CSPTime tmCur )
{
double dAsset = 0;
if( m_techstocks.GetSumAsset( tmCur, m_RealStockOwn, &dAsset ) )
{
dAsset += m_RealCurrentCash;
ASSETSERIAL serial;
memset( &serial, 0, sizeof(serial) );
serial.time = tmCur.GetTime();
serial.dAsset = dAsset;
serial.dCash = m_RealCurrentCash;
m_RealAssetSerial.SortInsert( serial );
return dAsset;
}
else
{
for( int i=m_RealAssetSerial.GetSize()-1; i>=0; i-- )
{
ASSETSERIAL & serial = m_RealAssetSerial.ElementAt(i);
if( serial.time <= tmCur.GetTime() )
return serial.dAsset;
}
}
return m_opparam.m_nStartAmount;
}
// 策略實戰:當前收益
double CStrategy::RealGetCurrentYield( )
{
if( m_opparam.m_nStartAmount > 0 )
return STRATEGY_BASEF_YIELD * RealGetAsset(RealGetCurrentTime()) / m_opparam.m_nStartAmount;
return STRATEGY_BASEF_YIELD;
}
// 策略實戰:當前指數上漲百分比
double CStrategy::RealGetCurrentYieldIndexPercent( )
{
CSPTime sptmBegin( RealGetBeginTime().GetTime() );
CSPTime sptmNow( RealGetCurrentTime().GetTime() );
DWORD dateBegin = sptmBegin.ToStockTimeDay();
DWORD dateNow = sptmNow.ToStockTimeDay();
CKData & kdata = AfxGetStockMain().GetKData(m_opparam.m_nKType);
int nIndexBegin = kdata.GetAboutIndexByDate( dateBegin );
int nIndexNow = kdata.GetAboutIndexByDate( dateNow );
if( -1 == nIndexBegin || -1 == nIndexNow )
return 0;
if( kdata.ElementAt(nIndexBegin).m_fClose < 1e-4 )
return 0;
double dYield = ((double)kdata.ElementAt(nIndexNow).m_fClose) - kdata.ElementAt(nIndexBegin).m_fClose;
dYield = dYield / kdata.ElementAt(nIndexBegin).m_fClose;
return dYield;
}
// 策略實戰:當前收益百分比
double CStrategy::RealGetCurrentYieldPercent( )
{
return ( RealGetCurrentYield() - STRATEGY_BASEF_YIELD ) / STRATEGY_BASEF_YIELD;
}
// 策略實戰:執行操作計劃
BOOL CStrategy::RealOperateNextop( CSPTime tmCur, COpRecordContainer & nextop, CTechStock & techstock )
{
for( int j=0; j<nextop.GetSize(); j++ ) // 依次執行每一個計劃
{
OPRECORD & record = nextop.ElementAt(j);
if( STRATEGY_OPTYPE_BUY != record.lOpType && STRATEGY_OPTYPE_SELL != record.lOpType )
continue;
if( tmCur.GetTime() >= record.time
&& techstock.m_info.IsEqualTo( CStock::marketUnknown, record.szCode ) )
{
if( !record.bViewed ) // Not Viewed
{
nextop.RemoveAt(j);
j --;
continue;
}
if( techstock.IsStopTrading(tmCur) ) // 停牌,轉入下一個交易日的計劃中
{
CSPTime tmNext;
if( m_opparam.GetNextTradeTime(tmCur, tmNext) )
record.time = tmNext.GetTime();
continue;
}
double dPriceOK = record.dSharePrice;
if( techstock.GetPriceOK( record.lOpType, tmCur, record.dwShare, record.dSharePrice, &dPriceOK ) ) // 成交價格
{
record.time = tmCur.GetTime();
record.dSharePrice = dPriceOK;
record.dRateCost = record.dwShare * record.dSharePrice * m_rate.GetRate(techstock.m_info);
RealOperate( record );
}
else if( STRATEGY_OPTYPE_SELL == record.lOpType ) // 如果是賣出不成功,轉入下一個交易日,直至賣出成功
{
CSPTime tmNext;
if( m_opparam.GetNextTradeTime(tmCur, tmNext) )
record.time = tmNext.GetTime();
if( techstock.GetClosePrice(tmCur,&dPriceOK) )
record.dSharePrice = dPriceOK * m_opparam.m_dSellMulti;
continue;
}
nextop.RemoveAt(j);
j --;
}
}
return TRUE;
}
// 策略實戰:執行
BOOL CStrategy::RealRun( SIMULATION_CALLBACK fnCallback, void * cookie )
{
// TIMEZONES
// 準備數據
if( !PrepareData( fnCallback, cookie ) )
return FALSE;
ClearLastIntensity( );
DWORD dwShare = 0; // Temp Data
double dSharePrice = 0; // Temp Data
CSPTime tmOp; // Temp Data
do {
CSPTime tmCur = RealGetCurrentTime(); // 當前日期
// Process
for( int i=0; i<m_techstocks.GetSize(); i++ ) // 每只股票依次判斷
{
CTechStock & techstock = m_techstocks.ElementAt(i);
// Operate
RealOperateNextop( tmCur, m_RealNextOp, techstock ); // 執行今日操作計劃
// Judge Whether to operate, if yes, save to nextop
STOCKOWN own;
memset( &own, 0, sizeof(own) );
if( m_RealStockOwn.HasThisStock( techstock.m_info, &own ) ) // 如果有這支股票,判斷是否賣出
{
if( m_techstocks.GetShouldSellShare( techstock, tmCur, own, m_opparam, &tmOp, &dwShare, &dSharePrice ) )
{ // 如果賣出,加入操作計劃中
m_RealNextOp.AddRecordUniqueStock( STRATEGY_OPTYPE_SELL, tmOp, techstock.m_info.GetStockCode(), dwShare, dSharePrice, dwShare*dSharePrice*m_rate.GetRate(techstock.m_info) );
}
}
else // 判斷是否買入
{
if( m_techstocks.GetShouldBuyShare( techstock, tmCur, m_RealCurrentCash, m_rate , m_opparam, m_RealStockOwn.GetSize(), &tmOp, &dwShare, &dSharePrice )
&& ( m_RealStockOwn.GetSize() + m_RealNextOp.GetBuyRecordCount() < m_opparam.m_nStoreDiv || m_RealNextOp.HasBuyStock(techstock.m_info.GetStockCode()) ) )
{ // 如果買入,加入操作計劃中
m_RealNextOp.AddRecordUniqueStock( STRATEGY_OPTYPE_BUY, tmOp, techstock.m_info.GetStockCode(), dwShare, dSharePrice, dwShare*dSharePrice*m_rate.GetRate(techstock.m_info) );
}
}
// 進度顯示
DWORD dwProgress = (DWORD)((i+1)*STRATEGY_MAX_PROGRESS/m_techstocks.GetSize());
if( fnCallback && !fnCallback( SIMULATION_PROGRESS, dwProgress, NULL, cookie ) )
return FALSE;
}
RealGetAsset( RealGetCurrentTime() );
} while( RealGotoNextTime() ); // 下一個交易日
if( fnCallback )
fnCallback( SIMULATION_PROGRESS, STRATEGY_MAX_PROGRESS, NULL, cookie );
return TRUE;
}
// 策略實戰:加入操作記錄,如果成功,同時要刪除加入日后的所有操作
BOOL CStrategy::RealAddOpRecordStrict( OPRECORD record )
{
COpRecordContainer recordbk;
recordbk.Copy( m_RealOpRecord );
// 重新執行操作記錄,到加入新操作日為止
BOOL bOK = TRUE;
m_RealCurrentCash = m_opparam.m_nStartAmount;
m_RealOpRecord.RemoveAll();
m_RealNextOp.RemoveAll();
m_RealStockOwn.RemoveAll();
for( int i=0; i<recordbk.GetSize(); i++ )
{
OPRECORD rec = recordbk.ElementAt(i);
if( bOK && rec.time < record.time )
bOK &= RealOperate( rec );
}
if( bOK && RealOperate( record ) )
{ // 加入成功,重新計算總資產序列
for( int i=m_RealAssetSerial.GetSize()-1; i>=0; i-- )
{
ASSETSERIAL serial = m_RealAssetSerial.ElementAt(i);
if( serial.time >= record.time )
m_RealAssetSerial.RemoveAt(i);
}
RealGetAsset( record.time );
return TRUE;
}
else
{
// 加入失敗,全部重來,恢復原樣
m_RealCurrentCash = m_opparam.m_nStartAmount;
m_RealOpRecord.RemoveAll();
m_RealNextOp.RemoveAll();
m_RealStockOwn.RemoveAll();
for( int i=0; i<recordbk.GetSize(); i++ )
{
OPRECORD rec = recordbk.ElementAt(i);
RealOperate( rec );
}
return FALSE;
}
}
// 策略實戰:刪除操作記錄,如果成功,同時要刪除日后的所有操作
BOOL CStrategy::RealDeleteOpRecordStrict( int nRecord )
{
if( nRecord < 0 || nRecord >= m_RealOpRecord.GetSize() )
{
SP_ASSERT( FALSE );
return FALSE;
}
OPRECORD record = m_RealOpRecord.ElementAt(nRecord);
COpRecordContainer recordbk;
recordbk.Copy( m_RealOpRecord );
// 重新執行操作記錄,到刪除日為止
BOOL bOK = TRUE;
m_RealCurrentCash = m_opparam.m_nStartAmount;
m_RealOpRecord.RemoveAll();
m_RealNextOp.RemoveAll();
m_RealStockOwn.RemoveAll();
for( int i=0; i<recordbk.GetSize(); i++ )
{
OPRECORD rec = recordbk.ElementAt(i);
if( bOK && rec.time < record.time )
bOK &= RealOperate( rec );
}
if( bOK )
{ // 成功刪除,重新計算總資產序列
for( int i=m_RealAssetSerial.GetSize()-1; i>=0; i-- )
{
ASSETSERIAL serial = m_RealAssetSerial.ElementAt(i);
if( serial.time >= record.time )
m_RealAssetSerial.RemoveAt(i);
}
RealGetAsset( record.time );
return TRUE;
}
else
{
// 刪除失敗,恢復原樣
m_RealCurrentCash = m_opparam.m_nStartAmount;
m_RealOpRecord.RemoveAll();
m_RealNextOp.RemoveAll();
m_RealStockOwn.RemoveAll();
for( int i=0; i<recordbk.GetSize(); i++ )
{
OPRECORD rec = recordbk.ElementAt(i);
RealOperate( rec );
}
return FALSE;
}
}
/*
BOOL CStrategy::RealUnOperate( OPRECORD record )
{
CStockInfo info;
if( strlen(record.szCode)>0
&& ( !AfxGetStockContainer().GetStockInfo( record.szCode, &info )
|| !info.IsValidStock() ) )
return FALSE;
double dAmount = record.dwShare * record.dSharePrice;
double dRateCost = record.dRateCost;
if( STRATEGY_OPTYPE_BUY == record.lOpType )
{
if( !m_RealStockOwn.RemoveStock( info, record.dwShare ) )
return FALSE;
m_RealCurrentCash += (dAmount+dRateCost);
}
else if( STRATEGY_OPTYPE_SELL == record.lOpType )
{
if( m_RealCurrentCash < dAmount-dRateCost )
return FALSE;
if( !m_RealStockOwn.AddStock( info, record.dwShare ) )
return FALSE;
m_RealCurrentCash -= (dAmount-dRateCost);
}
else if( STRATEGY_OPTYPE_ADDSTOCK == record.lOpType )
{
if( !m_RealStockOwn.RemoveStock( info, record.dwShare ) )
return FALSE;
}
else if( STRATEGY_OPTYPE_REMOVESTOCK == record.lOpType )
{
if( !m_RealStockOwn.AddStock( info, record.dwShare ) )
return FALSE;
}
else if( STRATEGY_OPTYPE_ADDCASH == record.lOpType )
{
if( m_RealCurrentCash < record.dSharePrice )
return FALSE;
m_RealCurrentCash -= record.dSharePrice;
}
else if( STRATEGY_OPTYPE_REMOVECASH == record.lOpType )
{
m_RealCurrentCash += record.dSharePrice;
}
else
return FALSE;
return TRUE;
}
BOOL CStrategy::RealAddOpRecordStrict( OPRECORD record )
{
COpRecordContainer recordbk;
recordbk.Copy( m_RealOpRecord );
BOOL bOK = TRUE;
for( int i=m_RealOpRecord.GetSize()-1; i>=0; i-- )
{
OPRECORD rec = m_RealOpRecord.ElementAt(i);
if( bOK && rec.time > record.time )
{
bOK &= RealUnOperate( rec );
if( bOK )
m_RealOpRecord.RemoveAt(i);
}
}
if( bOK && RealOperate( record ) )
{
for( i=m_RealAssetSerial.GetSize()-1; i>=0; i-- )
{
ASSETSERI
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -