public static void Update(UpdateNavsParam p_updateParam) { Utils.Logger.Info($"UpdateNavsService.Update()"); DateTime etNow = Utils.ConvertTimeFromUtcToEt(DateTime.UtcNow); if (etNow.IsWeekend()) { return; } Dictionary <GatewayId, uint> GatewayId2SubTableId = new Dictionary <GatewayId, uint>() { { GatewayId.GyantalMain, 1 }, { GatewayId.CharmatMain, 2 }, { GatewayId.DeBlanzacMain, 3 } }; foreach (var gw2SubTableId in GatewayId2SubTableId) { GatewayId gatewayId = gw2SubTableId.Key; List <BrAccSum>?accSums = BrokersWatcher.gWatcher.GetAccountSums(gatewayId); if (accSums == null) { continue; } var navRounded = accSums.GetValue(AccountSummaryTags.NetLiquidation); UpdateAssetInDb(p_updateParam, new AssetId32Bits(AssetType.BrokerNAV, gw2SubTableId.Value), navRounded); } }
public static void SetTimer(UpdateNavsParam p_state) { DateTime etNow = Utils.ConvertTimeFromUtcToEt(DateTime.UtcNow); DateTime targetTimeEt = new DateTime(etNow.Year, etNow.Month, etNow.Day, 16, 1, 0); // 1 minute after market close to avoid too busy periods when VirtualBroker trades happen or when IB is busy TimeSpan tsTillTarget = targetTimeEt - etNow; if (tsTillTarget < TimeSpan.FromSeconds(10)) // if negative timespan or too close to targetTime, it means etNow is after target time. Then target next day. { targetTimeEt = targetTimeEt.AddDays(1); targetTimeEt = new DateTime(targetTimeEt.Year, targetTimeEt.Month, targetTimeEt.Day, 16, 1, 0); tsTillTarget = targetTimeEt - etNow; } Utils.Logger.Info($"UpdateNavsService next targetdate: {targetTimeEt.ToSqDateTimeStr()} ET"); if (g_updateTimer == null) { // g_updateTimer = new System.Threading.Timer(new TimerCallback(Timer_Elapsed), p_state, TimeSpan.FromMilliseconds(1*1000), TimeSpan.FromMilliseconds(-1.0)); // first time: start almost immediately g_updateTimer = new System.Threading.Timer(new TimerCallback(Timer_Elapsed), p_state, tsTillTarget, TimeSpan.FromMilliseconds(-1.0)); // first time: start almost immediately } else { g_updateTimer.Change(tsTillTarget, TimeSpan.FromMilliseconds(-1.0)); // runs only once per day } }
private static void UpdateAssetInDb(UpdateNavsParam p_updateParam, AssetId32Bits p_assetId, double p_todayNav) { var dailyNavStr = p_updateParam.Db !.GetAssetQuoteRaw(p_assetId); // "D/C" for Date/Closes: "D/C,20090102/16461,20090105/16827,..." int iFirstComma = dailyNavStr !.IndexOf(','); string formatString = dailyNavStr.Substring(0, iFirstComma); // "D/C" for Date/Closes if (formatString != "D/C") { return; } int nearestIntValue = (int)Math.Round(p_todayNav, MidpointRounding.AwayFromZero); // 0.5 is rounded to 1, -0.5 is rounded to -1. Good. // var dailyNavStrSplit = dailyNavStr.Substring(iFirstComma + 1, dailyNavStr.Length - (iFirstComma + 1)).Split(',', StringSplitOptions.RemoveEmptyEntries); // DateOnly[] dates = dailyNavStrSplit.Select(r => new DateOnly(Int32.Parse(r.Substring(0, 4)), Int32.Parse(r.Substring(4, 2)), Int32.Parse(r.Substring(6, 2)))).ToArray(); // double[] unadjustedClosesNav = dailyNavStrSplit.Select(r => Double.Parse(r.Substring(9))).ToArray(); //unadjustedClosesNav[dates.Length - 1] = todayNav; // update the last item. int iLastComma = dailyNavStr.LastIndexOf(','); string lastRecord = dailyNavStr.Substring(iLastComma + 1); DateTime lastDate = Utils.FastParseYYYYMMDD(lastRecord.Substring(0, 8)); DateTime todayEt = Utils.ConvertTimeFromUtcToEt(DateTime.UtcNow).Date; int lengthToUseFromOld = dailyNavStr.Length; if (lastDate == todayEt) // if updater runs twice a day, last item is the today already. Remove the last item from the old string. { lengthToUseFromOld = iLastComma; } // dailyNavStr = dailyNavStr.Substring(0, lengthToUseFromOld); var useFromOldSg = new StringSegment(dailyNavStr, 0, lengthToUseFromOld); // StringSegment doesn't duplicate the long string string newDailyNavStr = useFromOldSg + $",{todayEt.ToString("yyyyMMdd")}/{nearestIntValue}"; // append last record at end p_updateParam.Db !.SetAssetQuoteRaw(p_assetId, newDailyNavStr); }