// Set [dataIsDailyPrice] = true if [priceTbl] contains all day data (not a real time data. /// <summary> /// Agrregate a data table to hourly,daily data... /// </summary> /// <param name="priceTbl">source data to be aggregated </param> /// <param name="cultureCode"></param> /// <param name="isDailyPrice"> /// Volume can be accumulated real-time or at the end of the day. /// - If data is collected in realtime, /// updateVolume table is used to culmulated the volume for each day and that will need some more resources. /// - If data is collected at the end of the day, the voulume alredy is the total volume and updateVolume table /// should not be used to save resources. /// </param> /// <param name="onAggregateDataFunc">function that was triggered after each agrregation</param> public static void AggregatePriceData(data.baseDS.priceDataDataTable priceTbl, CultureInfo cultureInfo, OnAggregateData onAggregateDataFunc) { data.baseDS.priceDataSumDataTable priceSumDataTbl = new data.baseDS.priceDataSumDataTable(); agrregateStat myAgrregateStat = new agrregateStat(); myAgrregateStat.maxCount = priceTbl.Count; priceTbl.DefaultView.Sort = priceTbl.onDateColumn.ColumnName + "," + priceTbl.stockCodeColumn.ColumnName; data.baseDS.priceDataRow priceDataRow; decimal changeVolume; int lastYear = int.MinValue; for (int idx = 0; idx < priceTbl.DefaultView.Count; idx++) { priceDataRow = (data.baseDS.priceDataRow)priceTbl.DefaultView[idx].Row; myAgrregateStat.count = idx; if (onAggregateDataFunc != null) { onAggregateDataFunc(myAgrregateStat); } if (myAgrregateStat.cancel) { priceSumDataTbl.Clear(); break; } changeVolume = priceDataRow.volume; foreach (AppTypes.TimeScale timeScale in AppTypes.myTimeScales) { if (timeScale.Type == AppTypes.TimeScaleTypes.RealTime) { continue; } AggregatePriceData(priceDataRow, changeVolume, timeScale, cultureInfo, priceSumDataTbl); Application.DoEvents(); } //Update and clear cache to speed up the performance if (lastYear != priceDataRow.onDate.Year) { application.DbAccess.UpdateData(priceSumDataTbl); priceSumDataTbl.Clear(); lastYear = priceDataRow.onDate.Year; } } application.DbAccess.UpdateData(priceSumDataTbl); }
public static data.baseDS.priceDataSumRow FindAndCache(data.baseDS.priceDataSumDataTable tbl, string stockCode, string timeScale, DateTime onDate) { data.baseDS.priceDataSumRow row = tbl.FindBytypestockCodeonDate(timeScale, stockCode, onDate); if (row != null) { return(row); } data.baseDSTableAdapters.priceDataSumTA dataTA = new data.baseDSTableAdapters.priceDataSumTA(); dataTA.ClearBeforeFill = false; dataTA.Fill(tbl, stockCode, timeScale, onDate, onDate); row = tbl.FindBytypestockCodeonDate(timeScale, stockCode, onDate); if (row != null) { return(row); } return(null); }
//Agrregate date time for hourly,daily data... //public static DateTime AggregateDateTime(AppTypes.timeScales type, DateTime onDateTime, CultureInfo ci) //{ // switch (type) // { // case AppTypes.timeScales.Hour1: // return onDateTime.Date.AddHours(onDateTime.Hour); // case AppTypes.timeScales.Hour2: // return onDateTime.Date.AddHours(onDateTime.Hour / 2); // case AppTypes.timeScales.Hour4: // return onDateTime.Date.AddHours(onDateTime.Hour / 4); // case AppTypes.timeScales.Daily: // return onDateTime.Date; // case AppTypes.timeScales.Weekly: // return common.dateTimeLibs.StartOfWeek(onDateTime, ci); // case AppTypes.timeScales.Monthly: // return common.dateTimeLibs.MakeDate(1, onDateTime.Month, onDateTime.Year); // case AppTypes.timeScales.Yearly: // return common.dateTimeLibs.MakeDate(1, 1, onDateTime.Year); // default: // common.system.ThrowException("Invalid argument in AggregateDateTime()"); // break; // } // return onDateTime; //} /// <summary> /// Agrregate a data row to hourly,daily data... /// </summary> /// <param name="priceRow"> source data arregated to [toSumTbl] </param> /// <param name="changeVolume"> volume qty changed and is cumulated to total volume </param> /// <param name="timeScale"> aggregate to hour,day,week... data </param> /// <param name="cultureInfo"> culture info that need to caculate the start of the week param> /// <param name="toSumTbl"> destination table</param> public static void AggregatePriceData(data.baseDS.priceDataRow priceRow, decimal changeVolume, AppTypes.TimeScale timeScale, CultureInfo cultureInfo, data.baseDS.priceDataSumDataTable toSumTbl) { DateTime dataDate = AggregateDateTime(timeScale, priceRow.onDate, cultureInfo); int dataTimeOffset = common.dateTimeLibs.DateDiffInMilliseconds(dataDate, priceRow.onDate); data.baseDS.priceDataSumRow priceDataSumRow; priceDataSumRow = libs.FindAndCache(toSumTbl, priceRow.stockCode, timeScale.Code, dataDate); if (priceDataSumRow == null) { priceDataSumRow = toSumTbl.NewpriceDataSumRow(); commonClass.AppLibs.InitData(priceDataSumRow); priceDataSumRow.type = timeScale.Code; priceDataSumRow.stockCode = priceRow.stockCode; priceDataSumRow.onDate = dataDate; priceDataSumRow.openPrice = priceRow.openPrice; priceDataSumRow.closePrice = priceRow.closePrice; toSumTbl.AddpriceDataSumRow(priceDataSumRow); } if (priceDataSumRow.openTimeOffset > dataTimeOffset) { priceDataSumRow.openPrice = priceRow.openPrice; priceDataSumRow.openTimeOffset = dataTimeOffset; } if (priceDataSumRow.closeTimeOffset <= dataTimeOffset) { priceDataSumRow.closePrice = priceRow.closePrice; priceDataSumRow.closeTimeOffset = dataTimeOffset; } if (priceDataSumRow.highPrice < priceRow.highPrice) { priceDataSumRow.highPrice = priceRow.highPrice; } if (priceDataSumRow.lowPrice > priceRow.lowPrice) { priceDataSumRow.lowPrice = priceRow.lowPrice; } priceDataSumRow.volume += changeVolume; }
// Set [dataIsDailyPrice] = true if [priceTbl] contains all day data (not a real time data. /// <summary> /// Agrregate a data table to hourly,daily data... /// </summary> /// <param name="priceTbl">source data to be aggregated </param> /// <param name="cultureCode"></param> /// <param name="isDailyPrice"> /// Volume can be accumulated real-time or at the end of the day. /// - If data is collected in realtime, /// updateVolume table is used to culmulated the volume for each day and that will need some more resources. /// - If data is collected at the end of the day, the voulume alredy is the total volume and updateVolume table /// should not be used to save resources. /// </param> /// <param name="onAggregateDataFunc">function that was triggered after each agrregation</param> public static void AggregatePriceData(data.baseDS.priceDataDataTable priceTbl, CultureInfo cultureInfo, OnAggregateData onAggregateDataFunc) { data.baseDS.priceDataSumDataTable priceSumDataTbl = new data.baseDS.priceDataSumDataTable(); agrregateStat myAgrregateStat = new agrregateStat(); myAgrregateStat.maxCount = priceTbl.Count; priceTbl.DefaultView.Sort = priceTbl.onDateColumn.ColumnName + "," + priceTbl.stockCodeColumn.ColumnName; data.baseDS.priceDataRow priceDataRow; decimal changeVolume; int lastYear = int.MinValue; for (int idx = 0; idx < priceTbl.DefaultView.Count; idx++) { priceDataRow = (data.baseDS.priceDataRow)priceTbl.DefaultView[idx].Row; myAgrregateStat.count = idx; if (onAggregateDataFunc != null) onAggregateDataFunc(myAgrregateStat); if (myAgrregateStat.cancel) { priceSumDataTbl.Clear(); break; } changeVolume = priceDataRow.volume; foreach (AppTypes.TimeScale timeScale in AppTypes.myTimeScales) { if (timeScale.Type == AppTypes.TimeScaleTypes.RealTime) continue; AggregatePriceData(priceDataRow, changeVolume, timeScale, cultureInfo, priceSumDataTbl); Application.DoEvents(); } //Update and clear cache to speed up the performance if (lastYear != priceDataRow.onDate.Year) { application.DbAccess.UpdateData(priceSumDataTbl); priceSumDataTbl.Clear(); lastYear = priceDataRow.onDate.Year; } } application.DbAccess.UpdateData(priceSumDataTbl); }
//Update #region Update public static void UpdateData(data.baseDS.priceDataSumDataTable tbl) { priceDataSumTA.Update(tbl); tbl.AcceptChanges(); }