COleDateTime CBCGPRecurrenceRuleYearly::GetNextEventDay (const COleDateTime& dtPrev) const
{
	if (dtPrev < GetDateStart ())
	{
		return COleDateTime ();
	}

	COleDateTime dt (dtPrev);

	{
		int y = dt.GetYear () + 1;
		int m = m_Type == BCGP_REC_RULE_YEARLY_TYPE_DAY ? m_dwDayMonth : m_dwDayTypeMonth;
		int d = GetPossibleDay (y);

		int nDays = CBCGPCalendar::GetMaxMonthDay (m, y);

		dt = COleDateTime (y, m, nDays < d ? nDays : d, 0, 0, 0);
	}

	BCGP_RECURRENCE_RULE_LIMIT limitType = GetLimitType ();

	if (limitType == BCGP_RECURRENCE_RULE_LIMIT_COUNT)
	{
		if (m_Type == BCGP_REC_RULE_YEARLY_TYPE_DAY)
		{
			int y = dt.GetYear () - GetDateStart ().GetYear () + 1;
			
			if ((int)GetLimitCount () < y)
			{
				dt = COleDateTime ();
			}
		}
	}
	else if (limitType == BCGP_RECURRENCE_RULE_LIMIT_DATE)
	{
		if (GetLimitDate () < dt)
		{
			dt = COleDateTime ();
		}
	}

	return dt;
}
Ejemplo n.º 2
0
char* CHSDownloadData::MakeReqPacket( CodeInfo* pCode, short nPeriod , long &lReqLen)
{
	if ( pCode == NULL || IsBadReadPtr(pCode,1))
		return NULL;
	BOOL bChangeRange = FALSE;
	BOOL bDownLoaded = FALSE;
	CString str;
	str.Format("%d-%s",pCode->m_cCodeType,pCode->GetCode());
/*	TaskItem* m_pTaskItem = NULL;*/
	if( m_pTaskItem && !IsBadReadPtr(m_pTaskItem,1) && m_pTaskItem->m_TaskName.Compare(str) )
	{
		m_pTaskItem->SetDayTaskFinished();
		m_pTaskItem->SetMinute1TaskFinished();
		m_pTaskItem->SetMinute5TaskFinished();
		return NULL;
	}

	m_DownLoadCount = 0;
	int nAfterBegin = 1300,nAfterEnd = 1500;
	short nGZIndex = MakeGZIndex(pCode->m_cCodeType);
	short nQihuo = MakeMarket(pCode->m_cCodeType);
	if (nQihuo == FUTURES_MARKET)
	{
		if (nGZIndex)
		{
			nAfterEnd = 1515;
		}
		else
		{
			nAfterBegin = 1330;
		}
	}
	//取本地缓存中已有的数据
	GetLocalData(pCode,nPeriod,m_pTaskItem);

	CArray<DateRange,DateRange> ayDate;
	CTime t1 = GetNowTime(nPeriod);
	CTimeSpan tSpan = GetTimeStep(nPeriod);
	unsigned long nLimitTime = GetLimitDate(pCode,nPeriod,m_nLimitedDay);//修正2012时间问题
	unsigned long nEarliestTime = GetIntTimeFromTime(t1,nPeriod);//修正2012时间问题
	unsigned long nTodayTime = nEarliestTime;//修正2012时间问题

	long lCurDate = 10;	
	
	CTime tmNow = CTime::GetCurrentTime();
	lCurDate = tmNow.GetYear() * 10000 + tmNow.GetMonth() * 100 + tmNow.GetDay();
	
	bDownLoaded = IsDownLoaded(lCurDate,pCode,nPeriod);

	try
	{

		BOOL bExistLastData = FALSE;
		BOOL bFirstDayRange = TRUE;
		CString strCode = pCode->GetCode();
		StockDay* pStockDay = (StockDay*)m_pTaskItem->m_localData;
		for(int i =  m_pTaskItem->m_localDataCount - 1; i >= 0; i--)
		{
			if (bDownLoaded)
			{
				break;
			}

			if(pStockDay[i].m_lDate <= 0)
				continue;

			if(pStockDay[i].m_lDate < nEarliestTime)
				nEarliestTime = pStockDay[i].m_lDate;

			if (pStockDay[i].m_lDate == 20000000) //修正错误的日期时间
			{
				pStockDay[i].m_lDate = 19991231;
			}

			///////////////若本地一存在的数据日期在限制时间内 则挑过数据的缺失检查/////////////////////////////
			if (i == m_pTaskItem->m_localDataCount - 1)
			{
				CTime tmNow = t1;
				CTime tmLastData = GetTimeFromIntTime(pStockDay[i].m_lDate,nPeriod);
				int nNowYear = tmNow.GetYear();
				int nNowMonth = tmNow.GetMonth();
				int nNowDay = tmNow.GetDay();
				if ( nNowYear == tmLastData.GetYear() && nNowMonth == tmLastData.GetMonth() && tmLastData.GetDay() == nNowDay)
				{
					CTime tmlimit = GetTimeFromIntTime(nLimitTime,nPeriod);
					CTime tmFirstDate = GetTimeFromIntTime(pStockDay[0].m_lDate,nPeriod);
					if (m_nLimitedDay == 0)
					{
						if ( PERIOD_TYPE_DAY != nPeriod)
						{
							int nMaxDays = 0;
							if (nGZIndex)
								nMaxDays = 36 - 1;  //36 = (10000/240 * 240)/270
							else
								nMaxDays = 41 - 1; //41= 10000/240

							long lLastDate = tmLastData.GetYear() * 10000 + tmLastData.GetMonth() * 100 + tmLastData.GetDay();
						
							if (lLastDate != lCurDate)
							{
								nMaxDays --;
							}

							CTimeSpan tmSpan(1,0,0,0);
							int nCount = 0;
							while(nCount < nMaxDays)
							{
								tmLastData -= tmSpan;
								if (tmLastData.GetDayOfWeek() != 1&& tmLastData.GetDayOfWeek() != 7)
								{
									nCount ++;
								}
							}				
						}
						if (PERIOD_TYPE_DAY == nPeriod)
						{
							if (tmFirstDate.GetYear() <= tmlimit.GetYear() && tmFirstDate.GetMonth() <= tmlimit.GetMonth() 
								&& tmFirstDate.GetDay() <= tmlimit.GetDay())
							{
								bExistLastData = TRUE;
							}
						}
						else if (tmFirstDate.GetYear() <= tmLastData.GetYear() && tmFirstDate.GetMonth() <= tmLastData.GetMonth() 
							&& tmFirstDate.GetDay() <= tmLastData.GetDay())
						{
							bExistLastData = TRUE;
						}
					}
					else
					{
						if (tmFirstDate.GetYear() <= tmlimit.GetYear() && tmFirstDate.GetMonth() <= tmlimit.GetMonth() 
							&& tmFirstDate.GetDay() <= tmlimit.GetDay())
						{
							bExistLastData = TRUE;
						}
					}
					if (bExistLastData)
					{
						break;
					}
				}
			}
			//////////////////////////////////////////////////////////////////////////

			int nCount = 0;	
			long lEndDate = 0;
			long lBeginDate = 0;

			CTime t2 = GetTimeFromIntTime(pStockDay[i].m_lDate,nPeriod);
			CTime t = t2;
			if (i != m_pTaskItem->m_localDataCount - 1)
			{
				t = t + tSpan;
			}
			while(t < t1)
			{
				if(t.GetDayOfWeek() != 1 &&  t.GetDayOfWeek() != 7 && t < t1) //1 = Sunday, 2 = Monday, ..., 7 = Saturday
				{
					if(lBeginDate == 0)
						lBeginDate = GetIntTimeFromTime(t,nPeriod);

					if (!bFirstDayRange)
					{
						lEndDate = GetIntTimeFromTime(t1 - tSpan,nPeriod);
					}
					else
					{
						while(t1.GetDayOfWeek()==1 || t1.GetDayOfWeek() == 7)
						{
							CTimeSpan OneDay(1,0,0,0);
							t1 -= OneDay;
						}
						lEndDate = GetIntTimeFromTime(t1,nPeriod);
					}
					nCount ++;
					break;
				}
				t = t + tSpan;
			};

			t1 = t2;
			bFirstDayRange = FALSE;

			if(nCount > 0 && lBeginDate >= nLimitTime )
			{
				if( lEndDate < nLimitTime)
					lEndDate = nLimitTime;

				CTime tmBegin = GetTimeFromIntTime(lBeginDate,nPeriod);
				CTime tmEnd = GetTimeFromIntTime(lEndDate,nPeriod);
				if (tmBegin.GetYear() == tmEnd.GetYear() && tmBegin.GetMonth() == tmEnd.GetMonth() && tmBegin.GetDay() == tmEnd.GetDay())
				{
					if (tmBegin.GetHour()*100 + tmBegin.GetMinute() > 1130 && tmEnd.GetHour()*100 + tmEnd.GetMinute() < nAfterBegin)
					{
						continue;
					}
				}

				if (lBeginDate > lEndDate)
				{
					continue ;
				}

				DateRange dr;
				dr.m_nBeginDate = lBeginDate;
				dr.m_nEndDate = lEndDate;
				ayDate.Add(dr);
			}

			if (nCount == 0 && pStockDay[i].m_lDate <= nLimitTime)
			{
				break;
			}
		}

		//下载分钟线数据时按9840的倍数根往前下载,若没有最近41天的数据,则下载最近82天数据,依次类推,最多倒退41*18天
		int nLimitedDays = 0,nPermitCount = 9840;
		if (ayDate.GetCount() < 1)
		{
			if(nEarliestTime > nLimitTime && !bExistLastData) 			//加入最后一段时间
			{
				DateRange dr;
				dr.m_nBeginDate = nLimitTime;
				dr.m_nEndDate = nEarliestTime;
				ayDate.Add(dr);
			}
		}
		else
		{
			int nMaxDays = 0;
			DateRange LastDateRage = ayDate.GetAt(ayDate.GetUpperBound());
			long nPreDate = GetPreDataDate(pCode,LastDateRage.m_nBeginDate,nPeriod);
			if (nGZIndex)
				nMaxDays = 36 - 1;  //36 = (10000/240 * 240)/270
			else
				nMaxDays = 41 - 1;  //41= 10000/240

			long nEarlyLimitedDate = nLimitTime;
			if (PERIOD_TYPE_DAY != nPeriod)
			{
				nEarlyLimitedDate = GetPreDate(pStockDay[m_pTaskItem->m_localDataCount -1].m_lDate,nMaxDays,nPeriod);
				long nCheckDataCount = GetDayDataCount(pCode,nEarlyLimitedDate,nTodayTime,nPeriod);
				if (nCheckDataCount > nPermitCount)
				{
					int nSurplusCount = nCheckDataCount - nPermitCount;
					nEarlyLimitedDate = GetChangedBeginDate(pCode,nEarlyLimitedDate,nSurplusCount,nPeriod);
				}
			}
			if (nPreDate >= nEarlyLimitedDate)
			{
				DateRange dr;
				dr.m_nBeginDate = nEarlyLimitedDate > nLimitTime ? nEarlyLimitedDate : nLimitTime;
				dr.m_nEndDate = nPreDate;
				ayDate.Add(dr);
			}
		}

		CArray<DateRange,DateRange> ayDateChange;
		int nDateCount = ayDate.GetCount();
		nPermitCount = nPermitCount*(m_nReloadDegree + 1);
		for (int i = nDateCount - 1; i>= 0; i--)
		{
			DateRange dateRange = ayDate.GetAt(i);
			long nRangeCount = GetDayDataCount(pCode,dateRange.m_nBeginDate,dateRange.m_nEndDate,nPeriod);
			nLimitedDays += nRangeCount;
			if (nLimitedDays < nPermitCount)
			{
				ayDateChange.Add(dateRange);
			}
			else
			{
				int nSpillCount = nLimitedDays - nPermitCount;
				dateRange.m_nBeginDate = GetChangedBeginDate(pCode,dateRange.m_nBeginDate,nSpillCount,nPeriod);
				ayDateChange.Add(dateRange);
				bChangeRange = TRUE;
				break;
			}
		}
		if (bChangeRange)
		{
			nDateCount = ayDateChange.GetCount();
		}

		if (bDownLoaded)
		{
			bChangeRange = TRUE;
			ayDateChange.RemoveAll();
			long nOutRangeDateB = 20101001; //国庆放假无交易行情
			long nOutRangeDateE = 20101001;
			if (PERIOD_TYPE_DAY != nPeriod)
			{
				nOutRangeDateB = 2010010930;
				nOutRangeDateE = 2010010930;
			}		
			DateRange dr;
			dr.m_nBeginDate = nOutRangeDateB;
			dr.m_nEndDate = nOutRangeDateE;
			nDateCount = ayDateChange.GetCount();
		}

		short nCount = sizeof(ReqDayData) / sizeof(CodeInfo);
		if( sizeof(ReqDayData) % sizeof(CodeInfo) )
			nCount++;
		int lLen = sizeof(AskData) + sizeof(CodeInfo) * (nCount - 1) + nDateCount * sizeof(DateRange);
		lReqLen = lLen;
		AskData* ask = (AskData*)(new char[lLen]);
		memset(ask,0,lLen);

		ask->m_nType  = RT_TECHDATA_RANGE;
		ask->m_nSize  = nCount;
		ask->m_lKey = nPeriod;
		memcpy(&ask->m_nPrivateKey, pCode, sizeof(CodeInfo));

		ReqRangeDayData* pRequest = (ReqRangeDayData*)ask->m_pCode;
		pRequest->m_lBeginPosition = 0;
		pRequest->m_nDay = 0;
		pRequest->m_cPeriod = nPeriod;
		memcpy(&pRequest->m_ciCode, pCode, sizeof(CodeInfo));
		pRequest->m_nDataRangCount = nDateCount;
		DateRange *pRane = pRequest->m_dataRange;

		CString strRequest,strRang;
		for(int nIndex = 0; nIndex < nDateCount; nIndex++)
		{
			if (bChangeRange)
				pRane[nIndex] = ayDateChange.GetAt(nIndex);
			else
				pRane[nIndex] = ayDate.GetAt(nIndex);

			m_DownLoadCount += GetDayDataCount(pCode,pRane[nIndex].m_nBeginDate,pRane[nIndex].m_nEndDate,nPeriod);
			strRang.Format("%d-%d;",pRane[nIndex].m_nBeginDate,pRane[nIndex].m_nEndDate);
			strRequest += strRang;
		}
		return (char*)ask;

	}
	catch (...)
	{
	}
	return NULL;
}
COleDateTime CBCGPRecurrenceRuleMonthly::GetNextEventDay (const COleDateTime& dtPrev) const
{
	if (dtPrev < GetDateStart ())
	{
		return COleDateTime ();
	}

	COleDateTime dt (dtPrev);

	DWORD dwSpan = m_Type == BCGP_REC_RULE_MONTHLY_TYPE_DAY ? m_dwDaySpan : m_dwDayTypeSpan;

	{
		int m = dt.GetMonth ();
		int y = dt.GetYear ();
		int nDays = 0;

		dt = COleDateTime (y, m, 1, 0, 0, 0);

		for (DWORD i = 0; i < dwSpan; i++)
		{
			m++;

			if (m == 13)
			{
				m = 1;
				y++;
			}

			nDays = CBCGPCalendar::GetMaxMonthDay (m, y);
			dt += COleDateTimeSpan (nDays, 0, 0, 0);
		}

		int d = GetPossibleDay (m, y);

		dt = COleDateTime (y, m, nDays < d ? nDays : d, 0, 0, 0);
	}

	BCGP_RECURRENCE_RULE_LIMIT limitType = GetLimitType ();

	if (limitType == BCGP_RECURRENCE_RULE_LIMIT_COUNT)
	{
		if (m_Type == BCGP_REC_RULE_MONTHLY_TYPE_DAY)
		{
			int m = ((dt.GetYear () - GetDateStart ().GetYear ()) * 12 +
				(dt.GetMonth () - GetDateStart ().GetMonth () + dwSpan)) / dwSpan;
			
			if ((int)GetLimitCount () < m)
			{
				dt = COleDateTime ();
			}
		}
	}
	else if (limitType == BCGP_RECURRENCE_RULE_LIMIT_DATE)
	{
		if (GetLimitDate () < dt)
		{
			dt = COleDateTime ();
		}
	}

	return dt;
}
COleDateTime CBCGPRecurrenceRuleDaily::GetNextEventDay (const COleDateTime& dtPrev) const
{
	if (dtPrev < GetDateStart ())
	{
		return COleDateTime ();
	}

	COleDateTime dt (dtPrev);
	
	if (m_Type == BCGP_REC_RULE_DAILY_TYPE_WEEKDAYS)
	{
		dt += COleDateTimeSpan (1, 0, 0, 0);

		int nWD = dt.GetDayOfWeek ();

		if (nWD == 1)
		{
			dt += COleDateTimeSpan (1, 0, 0, 0);
		}
		else if (nWD == 7)
		{
			dt += COleDateTimeSpan (2, 0, 0, 0);
		}
	}
	else
	{
		dt += COleDateTimeSpan (m_dwSpan, 0, 0, 0);
	}

	BCGP_RECURRENCE_RULE_LIMIT limitType = GetLimitType ();

	if (limitType == BCGP_RECURRENCE_RULE_LIMIT_COUNT)
	{
		if (m_Type == BCGP_REC_RULE_DAILY_TYPE_WEEKDAYS)
		{
			COleDateTime dtF (
				CBCGPPlannerView::GetFirstWeekDay (GetDateStart (), 
					2));

			int nDaysCount = (dt - GetDateStart ()).GetDays () + 1;
			int nWeekCount = (dt - dtF).GetDays () / 7;

			if ((nDaysCount - nWeekCount * 2) > (int)GetLimitCount ())
			{
				dt = COleDateTime ();
			}
		}
		else
		{
			if ((GetDateStart () + 
				 COleDateTimeSpan (m_dwSpan * GetLimitCount (), 0, 0, 0)) <= dt)
			{
				dt = COleDateTime ();
			}
		}
	}
	else if (limitType == BCGP_RECURRENCE_RULE_LIMIT_DATE)
	{
		if (GetLimitDate () < dt)
		{
			dt = COleDateTime ();
		}
	}

	return dt;
}
COleDateTime CBCGPRecurrenceRuleWeekly::GetNextEventDay (const COleDateTime& dtPrev) const
{
	if (dtPrev < GetDateStart ())
	{
		return COleDateTime ();
	}

	COleDateTime dt (dtPrev);

	int nWD  = dt.GetDayOfWeek ();
	BCGP_REC_RULE_WEEKLY typeWD = DayOfWeekToType (nWD);
	nWD--;

	int nWDL = TypeToDayOfWeek (m_LastDay) - 1;

	if (nWD == 0)
	{
		nWD = 7;
	}

	if (nWDL == 0)
	{
		nWDL = 7;
	}

	if (nWD == nWDL)
	{
		COleDateTime dtFirst (CBCGPPlannerView::GetFirstWeekDay (dtPrev, 
						2));//CBCGPPlannerManagerCtrl::GetFirstDayOfWeek () + 1));

		int nWDF = TypeToDayOfWeek (m_FirstDay) - 1;
		if (nWDF == 0)
		{
			nWDF = 7;
		}

		dt = dtFirst + COleDateTimeSpan (m_dwSpan * 7 + nWDF - 1, 0, 0, 0);
	}
	else
	{
		int nWDN = TypeToDayOfWeek (GetNextDay (typeWD)) - 1;

		if (nWDN == 0)
		{
			nWDN = 7;
		}

		int delta = nWDN - nWD;
		if (delta < 0)
		{
			delta += 7;
		}

		dt += COleDateTimeSpan (delta, 0, 0, 0);
	}


	BCGP_RECURRENCE_RULE_LIMIT limitType = GetLimitType ();

	if (limitType == BCGP_RECURRENCE_RULE_LIMIT_COUNT)
	{
		int nCount = GetLimitCount () % m_nCount;

		int delta  = GetLimitCount () / m_nCount;
		delta = delta * 7 * m_dwSpan;

		if (nCount > 0)
		{
			int i = 0;
			int c = 0;
			for (DWORD dwD = BCGP_REC_RULE_WEEKLY_FIRST; dwD <= BCGP_REC_RULE_WEEKLY_LAST; dwD = dwD << 1)
			{
				c++;

				if ((m_dwDays & dwD) != 0)
				{
					i++;

					if (i == nCount)
					{
						break;
					}
				}	
			}

			delta += c;
		}

		if (delta <= (dt - CBCGPPlannerView::GetFirstWeekDay (GetDateStart (), 
						2)))
		{
			dt = COleDateTime ();
		}
	}
	else if (limitType == BCGP_RECURRENCE_RULE_LIMIT_DATE)
	{
		if (dt > GetLimitDate ())
		{
			dt = COleDateTime ();
		}
	}

	return dt;
}