示例#1
0
        public virtual RequestID Prepare(string resType, string name, string group, bool isManual,
                                         IManualResourceLoader loader, NameValuePairList loadParams,
                                         OnOperationCompleted listener)
#endif
        {
#if AXIOM_THREAD_SUPPORT
            // queue a request
            ResourceRequest req = new ResourceRequest();
            req.Type         = RequestType.PrepareResource;
            req.ResourceType = resType;
            req.ResourceName = name;
            req.GroupName    = group;
            req.IsManual     = isManual;
            req.Loader       = loader;
            // Make instance copy of loadParams for thread independence
            req.LoadParams = (loadParams != null ? new NameValuePairList(loadParams) : null);
            req.Listener   = listener;
            return(AddRequest(req));
#else
            // synchronous
            ResourceManager rm = ResourceGroupManager.Instance.ResourceManagers[resType];
            rm.Prepare(name, group, isManual, loader, loadParams);
            return(0);
#endif
        }
示例#2
0
        public async Task RefreshCodalMessagesAsync()
        {
            try
            {
                OnOperationStart?.Invoke(this, 3);

                var new_messages = await CodalData.GetNewMessages();

                OnOperationStep?.Invoke(this, null);
                new_messages.Reverse();

                foreach (var message in new_messages)
                {
                    var instance = WebService.Instruments.FirstOrDefault(x => x.Symbol == message.Symbol);
                    if (instance != null)
                    {
                        message.InsCode = instance.InsCode;
                    }
                }
                OnOperationStep?.Invoke(this, null);

                if (new_messages.Any())
                {
                    await Storage.SaveMessagesAsync(new_messages);
                }
                OnOperationStep?.Invoke(this, null);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshCodalMessages", exception);
            }
        }
示例#3
0
        public async Task RefreshObserverMessagesAsync()
        {
            try
            {
                OnOperationStart?.Invoke(this, 2);
                var new_messages = await Online.GetNewMessagesAsync();

                OnOperationStep?.Invoke(this, null);
                if (new_messages.Any())
                {
                    var ins_codes = new_messages.Where(x => x.RelativeInstances != null).SelectMany(x => x.RelativeInstances);
                    var miss      = ins_codes.Where(x => !WebService.Instruments.Any(y => y.InsCode == x)).Distinct().ToList();
                    if (miss.Any())
                    {
                        await SaveWebServiceInstruments();
                    }

                    await Storage.SaveMessagesAsync(new_messages.Reverse());
                }
                OnOperationStep?.Invoke(this, null);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshObserverMessages", exception);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
示例#4
0
        public void ExportSolution(ContextService context, string id, ExportSolutionReq request)
        {
            var operationEventArgs = new OperationEventArgs(OperationType.ExportSolution, id);

            OnOperationStarted?
            .Invoke(this, operationEventArgs);

            CrmProvider.ExportSolution(Service, request.Managed, request.UniqueName, request.Path);
            OnOperationCompleted?
            .Invoke(this, operationEventArgs);
        }
示例#5
0
        public virtual RequestID InitializeAllResourceGroups(OnOperationCompleted listener)
#endif
        {
#if AXIOM_THREAD_SUPPORT
            //queue a request
            ResourceRequest req = new ResourceRequest();
            req.Type     = RequestType.InitializeAllGroups;
            req.Listener = listener;
            return(AddRequest(req));
#else
            // synchronous
            ResourceGroupManager.Instance.InitializeAllResourceGroups();
            return(0);
#endif
        }
示例#6
0
        public virtual RequestID UnloadResourceGroup(string name, OnOperationCompleted listener)
#endif
        {
#if AXIOM_THREAD_SUPPORT
            // queue a request
            ResourceRequest req = new ResourceRequest();
            req.Type      = RequestType.UnloadGroup;
            req.GroupName = name;
            req.Listener  = listener;
            return(AddRequest(req));
#else
            // synchronous
            ResourceGroupManager.Instance.UnloadResourceGroup(name);
            return(0);
#endif
        }
示例#7
0
        public virtual RequestID Unload(string resType, ResourceHandle handle, OnOperationCompleted listener)
#endif
        {
#if AXIOM_THREAD_SUPPORT
            // queue a request
            ResourceRequest req = new ResourceRequest();
            req.Type           = RequestType.UnloadResource;
            req.ResourceType   = resType;
            req.ResourceHandle = handle;
            req.Listener       = listener;
            return(AddRequest(req));
#else
            // synchronous
            ResourceManager rm = ResourceGroupManager.Instance.ResourceManagers[resType];
            rm.Unload(handle);
            return(0);
#endif
        }
示例#8
0
        public void ImportSolutionsAsync(ContextService context, string id, ImportSolutionReq request)
        {
            var operationEventArgs = new OperationEventArgs(OperationType.ImportSolutionAsync, id);

            OnOperationStarted?
            .Invoke(this, operationEventArgs);

            var data  = File.ReadAllBytes(request.Path);
            var jobId = CrmProvider
                        .ImportSolutionAsync(
                Service,
                data,
                request.OverwriteUnmanagedCustomizations,
                request.MigrateAsHold,
                request.PublishWorkflows);

            WaitAsnycOperation(jobId);
            OnOperationCompleted?
            .Invoke(this, operationEventArgs);
        }
示例#9
0
        public async Task RefreshInstrumentsAsync()
        {
            try
            {
                OnOperationStart?.Invoke(this, 4);
                await Online.LoadDataAsync();

                OnOperationStep?.Invoke(this, null);
                _update_instruments();
                OnOperationStep?.Invoke(this, null);
                await SaveWebServiceInstruments();

                OnOperationStep?.Invoke(this, null);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshInstruments", exception);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
示例#10
0
        /// <summary>
        /// Initialise a resource group in the background.
        /// </summary>
        /// <param name="name">The name of the resource group to initialise</param>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        /// <see cref="ResourceGroupManager.InitializeResourceGroup"/>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID InitializeResourceGroup(string name, OnOperationCompleted listener = null)
示例#11
0
        /// <summary>
        /// Unloads a resource group in the background.
        /// </summary>
        /// <param name="name">The name of the resource group to load</param>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        /// <see cref="ResourceGroupManager.UnloadResourceGroup(string)"/>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID UnloadResourceGroup(string name, OnOperationCompleted listener = null)
示例#12
0
        /// <summary>
        /// Unload a single resource in the background.
        /// </summary>
        /// <param name="resType">The type of the resource (from ResourceManager.ResourceType)</param>
        /// <param name="handle">Handle to the resource</param>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID Unload(string resType, ResourceHandle handle, OnOperationCompleted listener = null)
示例#13
0
        /// <summary>
        /// Unload a single resource in the background.
        /// </summary>
        /// <param name="resType">The type of the resource (from ResourceManager.ResourceType)</param>
        /// <param name="name">The name of the Resource</param>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID Unload(string resType, string name, OnOperationCompleted listener = null)
示例#14
0
        /// <summary>
        /// Load a single resource in the background.
        /// </summary>
        /// <param name="resType">The type of the resource (from ResourceManager.ResourceType)</param>
        /// <param name="name">The name of the Resource</param>
        /// <param name="group">The resource group to which this resource will belong</param>
        /// <param name="isManual">Is the resource to be manually loaded? If so, you should
        /// provide a value for the loader parameter</param>
        /// <param name="loader">The manual loader which is to perform the required actions
        /// when this resource is loaded; only applicable when you specify true
        /// for the previous parameter. NOTE: must be thread safe!!</param>
        /// <param name="loadParams">Optional pointer to a list of name/value pairs
        /// containing loading parameters for this type of resource. Remember
        /// that this must have a lifespan longer than the return of this call!</param>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID Load(string resType, string name, string group, bool isManual = false, IManualResourceLoader loader = null,
                                      NameValuePairList loadParams = null, OnOperationCompleted listener = null)
示例#15
0
        public async Task RefreshClosingPricesAsync()
        {
            try
            {
                var hSrv = StaticServiceFactory.Create <IHistoryService>();

                var newClosingPrices = await WebService.UpdateClosingPricesAsync(null, null);

                if (newClosingPrices != null && newClosingPrices.Count > 0)
                {
                    var dbdevens = await Storage.GetLastDevensAsync();

                    OnOperationStep?.Invoke(this, null);
                    int counter = 0, total = WebService.Instruments.Count;

                    var insCodes = newClosingPrices.Select(x => x.InsCode).Distinct();
                    total = insCodes.Count();


                    var devens         = newClosingPrices.Select(x => x.DayDate).Distinct();
                    var ctsrv          = StaticServiceFactory.Create <IClientTypeService>();
                    var maxVisitCounts = await ctsrv.GetDefaultQuery()
                                         .Where(x => devens.Contains(x.DayDt))
                                         .GroupBy(x => new { x.InsCode, x.DayDt })
                                         .Select(x => new { x.Key.DayDt, x.Key.InsCode, VisitCount = x.Max(y => y.VisitCount) })
                                         .ToListAsync();

                    OnOperationStep?.Invoke(this, null);

                    foreach (var insCode in insCodes)
                    {
                        var ins = StaticData.Instruments.FirstOrDefault(x => x.InsCode == insCode);
                        if (ins == null)
                        {
                            continue;
                        }
                        ++counter;
                        if (!dbdevens.ContainsKey(ins.InsCode) || dbdevens[ins.InsCode] < ins.LastDeven)
                        {
                            var closingPricesFromFile = newClosingPrices.Where(x => x.InsCode == ins.InsCode);

                            List <History> histories = null;
                            if (!dbdevens.ContainsKey(ins.InsCode))
                            {
                                _logger.InfoFormat("update database {2}% for instrument {0} closing price to {1}", ins.InsCode, ins.LastDeven, Math.Round(counter * 1.0 / total * 100));

                                histories = closingPricesFromFile.Select(x => new History(x)).ToList();
                            }
                            else
                            {
                                _logger.InfoFormat("update database {3}%  for instrument {0} closing price from {1} to {2}", ins.InsCode, dbdevens[ins.InsCode], ins.LastDeven, Math.Round(counter * 1.0 / total * 100));

                                histories = closingPricesFromFile.Where(x => x.DEven > dbdevens[ins.InsCode])
                                            .Select(x => new History(x))
                                            .ToList();
                            }

                            var vcs = maxVisitCounts.Where(x => x.InsCode == ins.InsCode).ToList();
                            foreach (var vc in vcs)
                            {
                                histories.Where(x => x.Date == vc.DayDt)
                                .ForEachAction(x => x.VisitCount = vc.VisitCount);
                            }

                            vcs.Clear();
                            vcs = null;

                            await hSrv.BulkSaveAsync(histories);

                            histories.Clear();
                            histories.TrimExcess();
                            histories = null;
                        }
                        OnOperationStep?.Invoke(this, null);
                    }

                    dbdevens = await Storage.GetLastDevensAsync();

                    OnOperationStep?.Invoke(this, null);

                    foreach (var ins in WebService.Instruments)
                    {
                        if (dbdevens.ContainsKey(ins.InsCode))
                        {
                            ins.LastDbDeven = dbdevens[ins.InsCode];
                        }
                    }
                    OnOperationStep?.Invoke(this, null);

                    newClosingPrices.Clear();
                    newClosingPrices.TrimExcess();
                    newClosingPrices = null;
                }

                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshClosingPrices", exception);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
示例#16
0
        /// <summary>
        /// Initialise all resource groups which are yet to be initialised in
        /// the background.
        /// </summary>
        /// <param name="listener">Optional callback interface, take note of warnings in
        /// the header and only use if you understand them.</param>
        /// <returns>Ticket identifying the request, use isProcessComplete() to
        /// determine if completed if not using listener</returns>
        /// <see cref="ResourceGroupManager.InitializeAllResourceGroups"/>
        //[OgreVersion(1, 7, 2)]
#if NET_40
        public virtual RequestID InitializeAllResourceGroups(OnOperationCompleted listener = null)
示例#17
0
        public async Task RefreshIndexes()
        {
            try
            {
                var indexCodes = StaticData.Instruments.Where(x => x.CompanyCode == Constants.CompanyCodes.IDXS)
                                 .Select(x => x.InsCode)
                                 .ToArray();

                OnOperationStart?.Invoke(this, indexCodes.Length + 3);

                List <Index> indices          = new List <Index>();
                var          readWebSiteBlock = new ActionBlock <long>(
                    async inxCode =>
                {
                    indices.Add(await Online.GetIndex(inxCode, false));
                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                }, new ExecutionDataflowBlockOptions
                {
                    MaxDegreeOfParallelism = 15
                });

                foreach (var code in indexCodes)
                {
                    readWebSiteBlock.Post(code);
                }

                readWebSiteBlock.Complete();
                await readWebSiteBlock.Completion;

                var indexLastValue = await Online.GetIndexLastValue();

                OnOperationStep?.Invoke(this, EventArgs.Empty);

                if (indices.Count > 0)
                {
                    var idxSrvf = StaticServiceFactory.Create <IIndexLastDayTimeValueService>();
                    var today   = DateTime.Now.Date;
                    var idxData = idxSrvf.GetDefaultQuery()
                                  .Where(x => x.Dt > today)
                                  .ToList();
                    OnOperationStep?.Invoke(this, EventArgs.Empty);

                    var newData = indices.Where(x => x != null).SelectMany(x => x.LastDayTimeValue)
                                  .Where(x => x.Dt >= today)
                                  .Where(x => !idxData.Any(y => y.InsCode == x.InsCode && x.Dt == y.Dt))
                                  .ToArray();

                    foreach (var dtv in newData)
                    {
                        var lv = indexLastValue.FirstOrDefault(x => x.Code == dtv.InsCode);
                        if (lv != null)
                        {
                            dtv.ChangePercent = lv.ChangePercent;
                            dtv.ChangeValue   = lv.ChangeValue;
                        }
                    }

                    await idxSrvf.SaveEntitiesAsync(newData);

                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                }
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshIndexes", exception);
                OnOperationBreak?.Invoke(this, exception);
            }
        }
示例#18
0
        public async Task WarmupAsync()
        {
            try
            {
                OnOperationStart?.Invoke(this, 10);

                _logger.Info("Warmup start");

                await WebService.FillDataAsync();

                OnOperationStep?.Invoke(this, EventArgs.Empty);

                List <Task> tasks = new List <Task>();

                tasks.Add(Storage.GetAllInstrumentsAsync());      // 0
                tasks.Add(Online.LoadDataAsync());                // 1
                tasks.Add(WebService.UpdateInstrumentsAsync());   // 2
                tasks.Add(Storage.GetLastMessageAsync());         // 3
                tasks.Add(Storage.GetLastCodalMessageAsync());    // 4
                tasks.Add(Storage.GetLastDevensAsync());          // 5

                foreach (var task in tasks)
                {
                    task.ContinueWith(x =>
                    {
                        OnOperationStep?.Invoke(this, EventArgs.Empty);
                    });
                }

                await Task.WhenAll(tasks);

                var dbInstruments = ((Task <List <Instrument> >)tasks[0]).Result;
                Online.LastObserverMessage = ((Task <ObserverMessage>)tasks[3]).Result;
                CodalData.Last             = ((Task <CodalMessage>)tasks[4]).Result;
                var dbdevens = ((Task <Dictionary <long, int> >)tasks[5]).Result;

                _update_instruments();
                OnOperationStep?.Invoke(this, EventArgs.Empty);

                var instruments = WebService.Instruments;

                foreach (var dbins in dbInstruments.Where(x => !instruments.Any(y => y.InsCode == x.InsCode)))
                {
                    instruments.Add(dbins);
                }

                foreach (var ins in instruments)
                {
                    ins.StartTracking();
                    var index = dbInstruments.FindIndex(x => x.InsCode == ins.InsCode);
                    if (index >= 0)
                    {
                        if (ins.Type == null && dbInstruments[index].Type != null)
                        {
                            ins.Type = dbInstruments[index].Type;
                        }

                        if (ins.Equals(dbInstruments[index]))
                        {
                            ins.ChangeTracker.ResetChanges();
                            ins.ChangeTracker.State = Exir.Framework.Common.ObjectState.Unchanged;
                        }
                        else
                        {
                            ins.ChangeTracker.State = Exir.Framework.Common.ObjectState.Modified;
                        }

                        dbInstruments.RemoveAt(index);
                    }
                    else
                    {
                        ins.ChangeTracker.State = Exir.Framework.Common.ObjectState.Added;
                    }

                    if (dbdevens.ContainsKey(ins.InsCode))
                    {
                        ins.LastDbDeven = dbdevens[ins.InsCode];
                    }
                    else
                    {
                        ins.LastDbDeven = 0;
                    }
                }
                OnOperationStep?.Invoke(this, EventArgs.Empty);

                await Storage.UpdateInstancesAsync(instruments);

                OnOperationStep?.Invoke(this, EventArgs.Empty);

                _is_last_refresh_success = true;

                await addClientTypesAsync();

                _logger.Info("Warmup completed");

                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("WarmupAsync", exception);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
示例#19
0
        public async Task RefreshLiveStates(bool fast)
        {
            try
            {
                var watch = new Stopwatch();
                watch.Start();
                var indexCodes = StaticData.Instruments
                                 .Where(x => x.Flow != (byte)FlowTypes.Ati && x.CompanyCode != Constants.CompanyCodes.IDXS)
                                 .Select(x => x.InsCode)
                                 .ToList();

                if (fast)
                {
                    indexCodes.RemoveFromIList(x => !Online.Data.ContainsKey(x));
                }

                OnOperationStart?.Invoke(this, indexCodes.Count * 2 + 3);

                var liveSrv   = StaticServiceFactory.Create <ILiveInstDataService>();
                var today     = DateTime.Now.Date;
                var savedData = await liveSrv.GetDefaultQuery()
                                .Where(x => x.DEven >= today)
                                .ToListAsync();

                OnOperationStep?.Invoke(this, EventArgs.Empty);
                int i = 0;
                var readWebSiteBlock = new TransformBlock <long, LiveInstData>(
                    async inxCode =>
                {
                    InstrumentLastInfo ins = null;
                    try
                    {
                        ins = await Online.FindAsync(null, inxCode);
                    }
                    catch (Exception ex)
                    {
                        _logger.WarnFormat("Cannot find instrument by code {0}; operation skip from this error.", ex, inxCode);
                        return(null);
                    }
                    if (ins == null)
                    {
                        _logger.WarnFormat("cannot find instrument with code {0}", inxCode);
                        return(null);
                    }
                    else
                    {
                        _logger.InfoFormat("instance {0} live data fetched {1}% completed", inxCode, Math.Ceiling(i++ *1.0 / indexCodes.Count * 100));
                    }

                    var r = new LiveInstData();
                    foreach (var field in r.GetFields().Where(x => x.Kind == FieldKinds.Primitive))
                    {
                        var value = ins.GetPropertyValue(field.Name);
                        r.SetValue(field.Name, Typing.ChangeType(value, field.PropertyType));
                    }
                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                    return(r);
                }, new ExecutionDataflowBlockOptions
                {
                    MaxDegreeOfParallelism = 15
                });

                List <LiveInstData> newData   = new List <LiveInstData>();
                List <LiveInstData> dirtyData = new List <LiveInstData>();
                var writeLiveInstData         = new ActionBlock <LiveInstData>(r =>
                {
                    if (r == null)
                    {
                        return;
                    }

                    var savedInst = savedData.FirstOrDefault(x => x.InsCode == r.InsCode);
                    if (savedInst != null)
                    {
                        savedInst.ResetChanges();
                        foreach (var field in r.GetFields().Where(x => x.Kind == FieldKinds.Primitive))
                        {
                            var value = r.GetPropertyValue(field.Name);
                            savedInst.SetValue(field.Name, Typing.ChangeType(value, field.PropertyType));
                        }
                        if (savedInst.ChangeTracker.State == ObjectState.Modified)
                        {
                            dirtyData.Add(savedInst);
                        }
                    }
                    else
                    {
                        r.DEven = today;
                        newData.Add(r);
                    }

                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                });

                readWebSiteBlock.LinkTo(writeLiveInstData);


                foreach (var code in indexCodes)
                {
                    readWebSiteBlock.Post(code);
                }

                readWebSiteBlock.Complete();
                await readWebSiteBlock.Completion;

                var ov = ObjectRegistry.GetObject <IValidationProvider>();
                newData.RemoveFromIList(x => !ov.Validate(x, Mode.OnInsert.ToString()).IsValid);
                if (newData.Count > 0)
                {
                    await liveSrv.Repository.BulkInsertAsync(newData);
                }
                OnOperationStep?.Invoke(this, EventArgs.Empty);

                dirtyData.RemoveFromIList(x => !ov.Validate(x, Mode.OnUpdate.ToString()).IsValid);
                if (dirtyData.Count > 0)
                {
                    await liveSrv.SaveEntitiesAsync(dirtyData.ToArray());
                }
                OnOperationStep?.Invoke(this, EventArgs.Empty);

                newData.Clear();
                newData.TrimExcess();
                dirtyData.Clear();
                dirtyData.TrimExcess();

                watch.Stop();
                _logger.InfoFormat("RefreshLiveStates take {0}ms", watch.ElapsedMilliseconds);
                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("RefreshLiveStates", exception);
                OnOperationBreak?.Invoke(this, exception);
            }
        }
示例#20
0
        private async Task UpdateDayTradesAsync(DateTime dt)
        {
            try
            {
                var hSrv  = StaticServiceFactory.Create <IHistoryService>();
                var blSrv = StaticServiceFactory.Create <IBestLimitService>();
                var tSrv  = StaticServiceFactory.Create <ITradeService>();
                var shSrv = StaticServiceFactory.Create <IShareHolderChangeService>();
                var cpSrv = StaticServiceFactory.Create <IClosingPriceService>();

                var codes = Online.Data.Values.Select(x => x.inscode);

                OnOperationStart?.Invoke(this, codes.Count() * 5);

                var extractDayDetailsBlock = new TransformBlock <long, DayTradeDetails>(
                    async insCode =>
                {
                    var r = await Online.ExtractDayDetailsAsync(insCode, dt);
                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                    return(r);
                }, new ExecutionDataflowBlockOptions
                {
                    MaxDegreeOfParallelism = 15
                });


                var writeBestLimits = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c =>
                {
                    try
                    {
                        if (c != null && c.BestLimits.Count > 0 && !await blSrv.GetDefaultQuery()
                            .Where(x => x.InsCode == c.InsCode && x.DateTime == dt)
                            .AnyAsync())
                        {
                            await blSrv.Repository.BulkInsertAsync(c.BestLimits);

                            _logger.InfoFormat("write {0} Best Limits to database.", c.BestLimits.Count);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    OnOperationStep?.Invoke(this, EventArgs.Empty);

                    return(c);
                });

                var writeTrades = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c =>
                {
                    try
                    {
                        if (c != null && c.Trades.Count > 0 && !await tSrv.GetDefaultQuery()
                            .Where(x => x.InsCode == c.InsCode && x.DateTime == dt)
                            .AnyAsync())
                        {
                            _logger.InfoFormat("write {0} Trades to database.", c.Trades.Count);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    OnOperationStep?.Invoke(this, EventArgs.Empty);

                    return(c);
                });

                var writeClosingPrices = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c =>
                {
                    var tomorow = dt.AddDays(1);
                    if (c != null && c.ClosingPriceData.Count > 0 && !await cpSrv.GetDefaultQuery()
                        .Where(x => x.InsCode == c.InsCode && x.DateTime >= dt && x.DateTime < tomorow)
                        .AnyAsync())
                    {
                        try
                        {
                            await cpSrv.Repository.BulkInsertAsync(c.ClosingPriceData);
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                        _logger.InfoFormat("write {0} Closing Price to database.", c.ClosingPriceData.Count);
                    }
                    OnOperationStep?.Invoke(this, EventArgs.Empty);

                    return(c);
                });

                var writeShareHolderStates = new ActionBlock <DayTradeDetails>(async c =>
                {
                    try
                    {
                        if (c != null && c.ShareHolderStates.Count > 0 && !await shSrv.GetDefaultQuery()
                            .Where(x => x.InsCode == c.InsCode && x.DateTime == dt)
                            .AnyAsync())
                        {
                            await shSrv.Repository.BulkInsertAsync(c.ShareHolderStates);
                            _logger.InfoFormat("write {0} Share Holder States to database.", c.ShareHolderStates.Count);
                        }

                        hSrv.Repository.BulkUpdate(x => x.InsCode == c.InsCode && x.Date == c.DayDate, x => new History
                        {
                            HasDetails = true
                        });
                    }
                    catch (Exception)
                    {
                        throw;
                    }

                    OnOperationStep?.Invoke(this, EventArgs.Empty);
                });

                extractDayDetailsBlock.LinkTo(writeBestLimits, new DataflowLinkOptions()
                {
                    PropagateCompletion = true
                });
                writeBestLimits.LinkTo(writeClosingPrices, new DataflowLinkOptions()
                {
                    PropagateCompletion = true
                });
                writeClosingPrices.LinkTo(writeTrades, new DataflowLinkOptions()
                {
                    PropagateCompletion = true
                });
                writeTrades.LinkTo(writeShareHolderStates, new DataflowLinkOptions()
                {
                    PropagateCompletion = true
                });

                foreach (var code in codes)
                {
                    extractDayDetailsBlock.Post(code);
                }

                extractDayDetailsBlock.Complete();
                await Task.WhenAll(writeShareHolderStates.Completion, writeTrades.Completion, writeClosingPrices.Completion, writeBestLimits.Completion, extractDayDetailsBlock.Completion);

                OnOperationCompleted?.Invoke(this, EventArgs.Empty);
            }
            catch (Exception exception)
            {
                _logger.Error("UpdateDayTradesAsync", exception);
                OnOperationBreak?.Invoke(this, exception);
            }
        }