Ejemplo n.º 1
0
void CASCTrendStrategy::Test( entity::Quote* pQuote, CPortfolio* pPortfolio, boost::chrono::steady_clock::time_point& timestamp )
{
	// a mutex to protect from unexpected applying strategy settings concurrently
	boost::mutex::scoped_lock l(m_mut);

	//pQuote->set_last(2466);
	//pQuote->set_update_time("09:15:12");

	CTechAnalyStrategy::Test(pQuote, pPortfolio, timestamp);

	if(!IsRunning())
		return;

	if(!m_marketOpen)
	{
		string symbol = pQuote->symbol();
		string quoteUpdateTime = pQuote->update_time();
		bool isIF = isSymbolIF(symbol);
		string targetBeginTime = isIF ? IF_START_1 : NON_IF_START_1;
		if(quoteUpdateTime.compare(targetBeginTime) >= 0)
		{
			m_marketOpen = true;
		}
		else
		{
			return;
		}
	}

	string symbol = pQuote->symbol();

	COHLCRecordSet* ohlc = GetRecordSet(symbol, m_period, timestamp);
	if(ohlc == NULL)
		return;

	int forceCloseBar = ohlc->GetSize() - m_forceCloseOffset;

	m_willRIndicatorSet->Calculate(ohlc);
	m_williamsR = m_willRIndicatorSet->GetRef(IND_WR, 0);

	m_watrStopIndSet->Calculate(ohlc);
	double trend = m_watrStopIndSet->GetRef(IND_WATR_TREND, 0);
	
	int currentBarIdx = ohlc->GetEndIndex();
	if(ohlc->NbElements() > 1)
	{
		m_donchianHi = ohlc->HighSeries[currentBarIdx - 1];
		m_donchianLo = ohlc->LowSeries[currentBarIdx - 1];
	}
	else
	{
		m_donchianHi = DOUBLE_MAX_PRICE;
		m_donchianLo = DOUBLE_MIN_PRICE;
	}
	

	CPortfolioTrendOrderPlacer* pOrderPlacer = dynamic_cast<CPortfolioTrendOrderPlacer*>(pPortfolio->OrderPlacer());

	if(pOrderPlacer->IsClosing())
	{
		LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Check for modifying closing order") % pPortfolio->InvestorId()));
		pOrderPlacer->OnQuoteReceived(timestamp, pQuote);
		return;
	}

	if (pOrderPlacer->IsOpened())
	{
		bool meetCloseCondition = false;
		bool forceClosing = IsForceClosing();
		if(forceClosing // This close condition check is only effective on the bar after open
			|| currentBarIdx >= forceCloseBar)
		{
			LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Closing position due to Force close")
				% pPortfolio->InvestorId() % pPortfolio->ID()));
			ClosePosition(pPortfolio, pOrderPlacer, pQuote, "手动平仓");
			return;
		}

		// check if the open bar is fake signal on next bar
		if(currentBarIdx == m_lastOpenBarIdx + 1 && !m_isRealSignal)
		{
			double preWR = m_willRIndicatorSet->GetRef(IND_WR, 1);
			m_isRealSignal = IsPreBarOpenCorrect(m_lastPositionOffset, preWR);
			LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Check if pre bar open at fake signal - preWR: %.2f (%s)")
				% pPortfolio->InvestorId() % pPortfolio->ID() % preWR % GetPosiDirectionText(m_lastPositionOffset)));
			if(!m_isRealSignal)
				ClosePosition(pPortfolio, pOrderPlacer, pQuote, "假信号开仓立即平仓");
		}

		unsigned int hour = 0, min = 0, sec = -1;
		if(ParseTimeString(pQuote->update_time(), &hour, &min, &sec))
			//&& currentBarIdx > m_lastOpenBarIdx)
		{
			m_watr = m_watrStopIndSet->GetRef(IND_WATR_VAL, 0);
			m_stopPx = m_watrStopIndSet->GetRef(IND_WATR_STOP, 1);

			LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Test for closing %s position - StopPx: %.2f, Last: %.2f, Ask: %.2f, Bid: %.2f")
				% pPortfolio->InvestorId() % pPortfolio->ID() % GetPosiDirectionText(m_lastPositionOffset) 
				% m_stopPx % pQuote->last() % pQuote->ask() % pQuote->bid()));

			string chnCloseReason = "触发WATR止损(盈)";
			bool meetCloseCondition = false;
			if(currentBarIdx > m_lastOpenBarIdx)
			{
				int barsSinceEntry = currentBarIdx - m_lastOpenBarIdx;
				if(barsSinceEntry == 1 && sec >= 58)	// test when next 2 bars closing
				{
					m_stopPx = GetNearStopLoss(m_lastPositionOffset, ohlc, currentBarIdx - 1);
					meetCloseCondition = TestForClose(m_lastPositionOffset, pQuote, m_stopPx);
					if(meetCloseCondition)
					{
						LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Closing position at next 1st bar. StopPx: %.2f")
						% pPortfolio->InvestorId() % pPortfolio->ID() % m_stopPx));
						chnCloseReason = "开仓后第1根K线突破失败";
					}
				}
				else if(barsSinceEntry == 2 && sec >= 58)
				{
					m_stopPx = GetNearStopLoss(m_lastPositionOffset, ohlc, currentBarIdx - 2);
					meetCloseCondition = TestForClose(m_lastPositionOffset, pQuote, m_stopPx);
					if(meetCloseCondition)
					{
						LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Closing position at next 2nd bar. StopPx: %.2f")
							% pPortfolio->InvestorId() % pPortfolio->ID() % m_stopPx));
						chnCloseReason = "开仓后第2根K线突破失败";
					}
					if(!meetCloseCondition)
					{
						// if the 2nd bar after entry doesn't ever make new high/low, close it
						meetCloseCondition = IfNotBreakoutPreceding(pPortfolio, m_lastPositionOffset, ohlc, currentBarIdx);
						chnCloseReason = "开仓后第2根K线未创新高(低)";
					}
				}
				else
				{
					meetCloseCondition = TestForClose(m_lastPositionOffset, pQuote, m_stopPx);
				}
			}
			else // still the bar opening the position
			{
				double initStopPx = m_stopPx;
				double lastTrend = m_watrStopIndSet->GetRef(IND_WATR_TREND, 1);
				// in case opened position is different than trend of last bar use current bar's stopPx
				if((m_lastPositionOffset == entity::LONG && lastTrend < 0) 
					|| (m_lastPositionOffset == entity::SHORT && lastTrend > 0))
				{
					if(m_initStopPx > 0)	// when m_initStopPx was given proper value
					{
						LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Using init stopPx : %.3f")
							% pPortfolio->InvestorId() % pPortfolio->ID() % m_initStopPx));						
						initStopPx = m_initStopPx;
					}
				}
				
				meetCloseCondition = TestForClose(m_lastPositionOffset, pQuote, initStopPx);
			}

			if(meetCloseCondition)
			{
				LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Closing position due to WATR stop")
					% pPortfolio->InvestorId() % pPortfolio->ID()));
				ClosePosition(pPortfolio, pOrderPlacer, pQuote, chnCloseReason.c_str());
				m_lastCloseBarIdx = currentBarIdx;
				return;
			}
		}		

		return;	// don't need to go to test open trigger any more
	}
	
	// Testing for Open position
	double last = pQuote->last();
	LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Testing for OPEN - Last: %.2f, WR: %.2f, Hi: %.2f, Lo: %.2f")
		% pPortfolio->InvestorId() % pPortfolio->ID() 
		% last % m_williamsR % m_donchianHi % m_donchianLo));

	entity::PosiDirectionType direction = TestForOpen(pQuote, m_williamsR, m_donchianHi, m_donchianLo, trend);
	if(currentBarIdx < forceCloseBar &&
		direction > entity::NET && 
		(currentBarIdx > m_lastCloseBarIdx))		// In general, don't open position at the bar just closing position
		//|| direction != m_lastPositionOffset))	// unless the direction is different
	{
		if(!pOrderPlacer->IsWorking())
		{
			LOG_DEBUG(logger, boost::str(boost::format("[%s] ASC Trend - Portfolio(%s) Opening position at bar %d")
				% pPortfolio->InvestorId() % pPortfolio->ID() % currentBarIdx ));
			OpenPosition(direction, pOrderPlacer, pQuote, timestamp, false, 
				boost::str(boost::format("WR(%.2f)满足条件") % m_williamsR).c_str());
			m_lastOpenBarIdx = currentBarIdx;
			
			// The stopPx at the current bar in this moment will be initial stop price as backup stop price.
			// in case the preceding trend is different than this one, this initial stop price will be effective.
			m_initStopPx = m_watrStopIndSet->GetRef(IND_WATR_STOP, 0);
			return;
		}
	}
}
Ejemplo n.º 2
0
BOOL CMorphaResDlg::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	CMainFrame* pMainFrm=(CMainFrame*)AfxGetMainWnd();
	CMorphaDataRetriveDlg& dlg = *(pMainFrm->m_pWndMorphadlg);
	
	CString strSQLCRMfi("select morpharesult.* into morphafordisplay \
	    from morpharesult,basicinfo,morphaimage,spermchait,morpharesultratio \
		where morpharesult.pdetectno = basicinfo.pdetectno \
		  and morpharesult.pdetectno = morphaimage.pdetectno \
		  and morpharesult.pdetectno = spermchait.pdetectno \
		  and morpharesult.pdetectno = morpharesultratio.pdetectno");

	try
	{
		if(IsTableExist(theConnection, "morphafordisplay") == true)
		{
			theConnection->Execute((LPCTSTR)"drop table morphafordisplay",NULL,adCmdText);
		}
		theConnection->Execute((LPCTSTR)strSQLCRMfi,NULL,adCmdText);

		CString strGetN("select count(*) from morphafordisplay");
		_RecordsetPtr rs=theConnection->Execute((LPCSTR)strGetN,NULL,adCmdText);
		
		dlg.m_dp[0].nCurPage = 1;
		dlg.m_dp[0].nTotalRecord=rs->GetCollect((long)0).iVal;
		dlg.m_dp[0].nPageRecord = NUMPERPAGE;
		dlg.m_dp[0].nTotalPage = dlg.m_dp[0].nTotalRecord / dlg.m_dp[0].nPageRecord +
							 (dlg.m_dp[0].nTotalRecord % dlg.m_dp[0].nPageRecord!=0);
		CString queryinfo;
 		queryinfo.Format("共查询到%d条记录",dlg.m_dp[0].nTotalRecord);
 		dlg.SetDlgItemText(IDC_STATIC_QUERY,queryinfo);
		if(dlg.m_dp[0].nTotalRecord == 0 ) 
		{
			CMainFrame* pMainFrm=(CMainFrame*)AfxGetMainWnd();
			pMainFrm->m_pWndMorphadlg->GetDlgItem(IDC_BTN_FIRSTPAGE)->EnableWindow(FALSE);
			pMainFrm->m_pWndMorphadlg->GetDlgItem(IDC_BTN_PREPAGE)->EnableWindow(FALSE);
			pMainFrm->m_pWndMorphadlg->GetDlgItem(IDC_BTN_NEXTPAGE)->EnableWindow(FALSE);
			pMainFrm->m_pWndMorphadlg->GetDlgItem(IDC_BTN_LASTPAGE)->EnableWindow(FALSE);
			pMainFrm->m_pWndMorphadlg->GetDlgItem(IDC_PAGENUM)->EnableWindow(FALSE);
			return FALSE;
		}
		
		int lowRow, upRow;
		dlg.GetPageBound(1,lowRow,upRow,dlg.m_dp[0]);


		GetRecordSet(rs,lowRow,upRow);
		int n=dlg.m_resdlg.m_wndMorphaDataList.SetData(rs);
		
		queryinfo.Format("第 %d / %d 页",dlg.m_dp[0].nCurPage,dlg.m_dp[0].nTotalPage);
		dlg.SetDlgItemText(IDC_PAGENUM,queryinfo);
		
		dlg.GetDlgItem(IDC_BTN_FIRSTPAGE)->EnableWindow(dlg.m_dp[dlg.IsInqueryState()].nCurPage != 1);
		dlg.GetDlgItem(IDC_BTN_PREPAGE)->EnableWindow(dlg.m_dp[dlg.IsInqueryState()].nCurPage != 1);
		dlg.GetDlgItem(IDC_BTN_NEXTPAGE)->EnableWindow(dlg.m_dp[dlg.IsInqueryState()].nCurPage != dlg.m_dp[dlg.IsInqueryState()].nTotalPage);
		dlg.GetDlgItem(IDC_BTN_LASTPAGE)->EnableWindow(dlg.m_dp[dlg.IsInqueryState()].nCurPage != dlg.m_dp[dlg.IsInqueryState()].nTotalPage );

	}
	catch (_com_error& e)
	{
		MessageBox(e.Description());
		return FALSE;
	}	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
Ejemplo n.º 3
0
void CRangeTrendStrategy::Test( entity::Quote* pQuote, CPortfolio* pPortfolio, boost::chrono::steady_clock::time_point& timestamp )
{
	// a mutex to protect from unexpected applying strategy settings concurrently
	boost::mutex::scoped_lock l(m_mut);

	//pQuote->set_last(2466);
	//pQuote->set_update_time("09:15:12");

	CTechAnalyStrategy::Test(pQuote, pPortfolio, timestamp);

	if(!IsRunning())
		return;

	if(!m_marketOpen)
	{
		string symbol = pQuote->symbol();
		string quoteUpdateTime = pQuote->update_time();
		bool isIF = isSymbolIF(symbol);
		string targetBeginTime = isIF ? IF_START_1 : NON_IF_START_1;
		if(quoteUpdateTime.compare(targetBeginTime) >= 0)
		{
			m_marketOpen = true;
		}
		else
		{
			return;
		}
	}

	string symbol = pQuote->symbol();

	COHLCRecordSet* ohlc = GetRecordSet(symbol, m_timeFrame, timestamp);
	if(ohlc == NULL)
		return;

	int forceCloseBar = ohlc->GetSize() - m_forceCloseOffset;

	int currentBarIdx = ohlc->GetEndIndex();

	if(currentBarIdx <= m_openPeriod)
		return;	// too few bars to test

	m_openDonchianDataSet->Calculate(ohlc);
	if(m_openDonchianDataSet->AvailableElems() > 1)
	{
		m_upperBoundOpen = m_openDonchianDataSet->GetRef(IND_DONCHIAN_Hi, 1);
		m_lowerBoundOpen = m_openDonchianDataSet->GetRef(IND_DONCHIAN_Lo, 1);
	}

	m_closeDonchianDataSet->Calculate(ohlc);
	if(m_closeDonchianDataSet->AvailableElems() > 1)
	{
		m_upperBoundClose = m_closeDonchianDataSet->GetRef(IND_DONCHIAN_Hi, 1);
		m_lowerBoundClose = m_closeDonchianDataSet->GetRef(IND_DONCHIAN_Lo, 1);
	}

	m_atrDataSet->Calculate(ohlc);
	m_NATR = m_atrDataSet->GetRef(IND_ATR, 1);

	if(currentBarIdx > m_lastBarIdx)	// Get into next bar
	{
		m_lastBarIdx = currentBarIdx;

		if(m_pendingOrdCmd.get() != NULL)
		{
			if(m_pendingOrdCmd->IsActive())
			{
				// Fire command
				if(m_pendingOrdCmd->GetOffset() == entity::OPEN)		// For Open position command
				{
					m_lastPosiDirection = m_pendingOrdCmd->GetDirection();
					m_lastCostPx = m_pendingOrdCmd->Fire(pQuote, pPortfolio, timestamp);
					m_StopLoss = m_stopLossFactor * m_NATR;
					LOG_DEBUG(logger, boost::str(boost::format("Fired StrategyOrderCommand(OPEN). LastCost: %.2f, StopLoss: %.2f at %s")
						% m_lastCostPx % m_StopLoss % pQuote->update_time()));
				}
				else	// for close position command
				{
					// reset flags
					double closePx = m_pendingOrdCmd->Fire(pQuote, pPortfolio, timestamp);
					LOG_DEBUG(logger, boost::str(boost::format("Fired StrategyOrderCommand(CLOSE). ClosePx: %.2f at %s")
						% closePx % pQuote->update_time()));

					m_lastPosiDirection = entity::NET;
					m_lastCostPx = -1.0;
					m_StopLoss = 0;
					m_trending = false;
				}

				if(!m_pendingOrdCmd->IsActive())		// command reverted will not be reset
				{
					LOG_DEBUG(logger, boost::str(boost::format("StrategyOrderCommand gets inactive, and removed.")));
					m_pendingOrdCmd.reset();
				}
				return;
			}
			else
			{
				LOG_DEBUG(logger, boost::str(boost::format("StrategyOrderCommand is inactive, and gets removed.")));
				m_pendingOrdCmd.reset();
			}
		}
	}
	else	// Still the current bar
	{
		if(m_pendingOrdCmd.get() != NULL)
		{
			if(m_pendingOrdCmd->GetRevertOnClose()
				&& m_pendingOrdCmd->GetOffset() == entity::OPEN)
			{
				// ONLY for revert Open position after close
				m_trending = true;
				m_lastPosiDirection = m_pendingOrdCmd->GetDirection();
				m_lastCostPx = m_pendingOrdCmd->Fire(pQuote, pPortfolio, timestamp);
				m_StopLoss = m_stopLossFactor * m_NATR;
				LOG_DEBUG(logger, boost::str(boost::format("Fired StrategyOrderCommand(Revert-OPEN). LastCost: %.2f, StopLoss: %.2f at %s")
					% m_lastCostPx % m_StopLoss % pQuote->update_time()));
				m_pendingOrdCmd.reset();
			}
		}
	}

	CPortfolioTrendOrderPlacer* pOrderPlacer = dynamic_cast<CPortfolioTrendOrderPlacer*>(pPortfolio->OrderPlacer());

	if(pOrderPlacer->IsClosing())
	{
		LOG_DEBUG(logger, boost::str(boost::format("[%s] Range Trend - Check for modifying closing order") % pPortfolio->InvestorId()));
		pOrderPlacer->OnQuoteReceived(timestamp, pQuote);
		return;
	}

	unsigned int hour = 0, min = 0, sec = -1;
	if(!ParseTimeString(pQuote->update_time(), &hour, &min, &sec))
		return;

	int secInBar = (min * 60 + sec) % m_timeFrame;
	bool isTestingBar = secInBar > m_timeFrame - 5;
	if(!isTestingBar)
		return;

	// Testing for Close Position
	if (pOrderPlacer->IsOpened())
	{
		bool meetCloseCondition = false;
		bool forceClosing = IsForceClosing();
		if(forceClosing // This close condition check is only effective on the bar after open
			|| currentBarIdx >= forceCloseBar)
		{
			LOG_DEBUG(logger, boost::str(boost::format("[%s] Range Trend - Portfolio(%s) Closing position due to Force close")
				% pPortfolio->InvestorId() % pPortfolio->ID()));

			CStrategyOrderCommand forceCloseCommand(entity::CLOSE, pOrderPlacer, this);
			forceCloseCommand.SetNote( forceClosing ? "手动平仓" : "收市前平仓");
			double px = forceCloseCommand.Fire(pQuote, pPortfolio, timestamp);
			return;
		}

		// Stop Gain & Stop Loss
		string closeComment;
		bool revertOffset = false;
		bool closePosition = TestForClose(pPortfolio, pQuote, m_upperBoundClose, m_lowerBoundClose, &closeComment, &revertOffset);
		if(closePosition)
		{
			if(m_pendingOrdCmd.get() == NULL)
			{
				m_pendingOrdCmd = OrderCommandPtr(new CStrategyOrderCommand(entity::CLOSE, pOrderPlacer, this));
				m_pendingOrdCmd->SetNote(closeComment);
				m_pendingOrdCmd->SetRevertOnClose(revertOffset);
				m_pendingOrdCmd->Activate();
			}
			else
			{
				if(!m_pendingOrdCmd->IsActive())
				{
					m_pendingOrdCmd->SetNote(closeComment);
					m_pendingOrdCmd->SetRevertOnClose(revertOffset);
					m_pendingOrdCmd->Activate();
				}
			}
		}
		else
		{
			if(m_pendingOrdCmd.get() != NULL)
				m_pendingOrdCmd->Deactivate();
		}
	}
	// Testing for Open position
	else if (currentBarIdx < forceCloseBar)
	{
		string openComment;
		entity::PosiDirectionType direction = TestForOpen(pPortfolio, pQuote, m_upperBoundOpen, m_lowerBoundOpen, &openComment);

		if(direction > entity::NET)
		{
			if(m_pendingOrdCmd.get() == NULL)
			{
				m_pendingOrdCmd = OrderCommandPtr(new CStrategyOrderCommand(entity::OPEN, pOrderPlacer, this));
				m_pendingOrdCmd->SetDirection(direction);
				m_pendingOrdCmd->SetNote(openComment);
				m_pendingOrdCmd->Activate();
			}
			else{
				m_pendingOrdCmd->SetDirection(direction);
				m_pendingOrdCmd->SetNote(openComment);

				if(!m_pendingOrdCmd->IsActive())
				{
					m_pendingOrdCmd->Activate();
				}
			}
		}
		else
		{
			if(m_pendingOrdCmd.get() != NULL)
				m_pendingOrdCmd->Deactivate();
		}
	}
}