Exemple #1
0
        void IEventConsumer <StopOutEventArgs> .ConsumeEvent(object sender, StopOutEventArgs ea)
        {
            var account   = ea.Account;
            var orders    = ea.Orders;
            var eventTime = _dateService.Now();
            var accountMarginEventMessage = AccountMarginEventMessageConverter.Create(account, true, eventTime);
            var accuracy = _assetsCache.GetAssetAccuracy(account.BaseAssetId);
            var totalPnl = Math.Round(orders.Sum(x => x.GetTotalFpl()), accuracy);

            _threadSwitcher.SwitchThread(async() =>
            {
                _operationsLogService.AddLog("stopout", account.ClientId, account.Id, "", ea.ToJson());

                var marginEventTask = _rabbitMqNotifyService.AccountMarginEvent(accountMarginEventMessage);

                _notifyService.NotifyAccountStopout(account.ClientId, account.Id, orders.Length, totalPnl);

                var notificationTask = SendMarginEventNotification(account.ClientId,
                                                                   string.Format(MtMessages.Notifications_StopOutNotification, orders.Length, totalPnl,
                                                                                 account.BaseAssetId));

                var clientEmail = await _clientAccountService.GetEmail(account.ClientId);

                var emailTask = !string.IsNullOrEmpty(clientEmail)
                    ? _emailService.SendStopOutEmailAsync(clientEmail, account.BaseAssetId, account.Id)
                    : Task.CompletedTask;

                await Task.WhenAll(marginEventTask, notificationTask, emailTask);
            });
        }
Exemple #2
0
        public async Task SendMarginCallEmailAsync(IMarginTradingAccount account)
        {
            var clientEmail = await _clientAccountService.GetEmail(account.ClientId);

            if (string.IsNullOrEmpty(clientEmail))
            {
                return;
            }

            var message =
                _templateGenerator.Generate(GetMarginCallTemplate(account.LegalEntity), new { account.BaseAssetId, AccountId = account.Id, System.DateTime.UtcNow.Year });

            await _emailSender.SendAsync(
                new EmailMessage
            {
                HtmlBody = message,
                Subject  = "Margin call"
            },
                new EmailAddressee
            {
                EmailAddress = clientEmail
            });
        }
Exemple #3
0
        void IEventConsumer <MarginCallEventArgs> .ConsumeEvent(object sender, MarginCallEventArgs ea)
        {
            var account   = ea.Account;
            var eventTime = _dateService.Now();

            var(level, lastNotifications) = LevelAndNotificationsCache(ea.MarginCallLevel);

            if (lastNotifications == null)
            {
                return;
            }

            var accountMarginEventMessage = AccountMarginEventMessageConverter.Create(account, level, eventTime);

            _threadSwitcher.SwitchThread(async() =>
            {
                if (lastNotifications.TryGetValue(account.Id, out var lastNotification) &&
                    lastNotification.AddMinutes(_settings.Throttling.MarginCallThrottlingPeriodMin) > eventTime)
                {
                    _log.WriteInfo(nameof(MarginCallConsumer), nameof(IEventConsumer <MarginCallEventArgs> .ConsumeEvent),
                                   $"MarginCall event is ignored for accountId {account.Id} because of throttling: event time {eventTime}, last notification was sent at {lastNotification}");
                    return;
                }

                var marginEventTask = _rabbitMqNotifyService.AccountMarginEvent(accountMarginEventMessage);

                _operationsLogService.AddLog($"margin call: {level.ToString()}", account.Id, "", ea.ToJson());

                var clientEmail = await _clientAccountService.GetEmail(account.ClientId);

                var emailTask = !string.IsNullOrEmpty(clientEmail)
                    ? _emailService.SendMarginCallEmailAsync(clientEmail, account.BaseAssetId, account.Id)
                    : Task.CompletedTask;

                await Task.WhenAll(marginEventTask, emailTask);

                lastNotifications.AddOrUpdate(account.Id, eventTime, (s, times) => eventTime);
            });
        }
Exemple #4
0
        void IEventConsumer <MarginCallEventArgs> .ConsumeEvent(object sender, MarginCallEventArgs ea)
        {
            var account   = ea.Account;
            var eventTime = _dateService.Now();
            var accountMarginEventMessage = AccountMarginEventMessageConverter.Create(account, false, eventTime);

            _threadSwitcher.SwitchThread(async() =>
            {
                if (LastNotifications.TryGetValue(account.Id, out var lastNotification) &&
                    lastNotification.AddMinutes(NotificationsTimeout) > eventTime)
                {
                    return;
                }

                var marginEventTask = _rabbitMqNotifyService.AccountMarginEvent(accountMarginEventMessage);

                _operationsLogService.AddLog("margin call", account.ClientId, account.Id, "", ea.ToJson());

                var marginUsageLevel = account.GetMarginUsageLevel();
                var marginUsedPerc   = marginUsageLevel == 0 ? 0 : 1 / marginUsageLevel;

                var notificationTask = SendMarginEventNotification(account.ClientId, string.Format(
                                                                       MtMessages.Notifications_MarginCall, marginUsedPerc,
                                                                       account.BaseAssetId));

                var clientEmail = await _clientAccountService.GetEmail(account.ClientId);

                var emailTask = !string.IsNullOrEmpty(clientEmail)
                    ? _emailService.SendMarginCallEmailAsync(clientEmail, account.BaseAssetId, account.Id)
                    : Task.CompletedTask;

                await Task.WhenAll(marginEventTask, notificationTask, emailTask);

                LastNotifications.AddOrUpdate(account.Id, eventTime, (s, time) => eventTime);
            });
        }
Exemple #5
0
        public void PerformEmailNotification(DateTime calculationTime)
        {
            _threadSwitcher.SwitchThread(async() =>
            {
                await _semaphore.WaitAsync();

                try
                {
                    var processedCalculations = (await _overnightSwapHistoryRepository.GetAsync(calculationTime, null))
                                                .Where(x => x.IsSuccess && x.Time >= calculationTime)
                                                .ToList();

                    var notifications = processedCalculations
                                        .GroupBy(x => x.ClientId)
                                        .Select(c => new OvernightSwapNotification
                    {
                        CliendId = c.Key,
                        CalculationsByAccount = c.GroupBy(a => a.AccountId)
                                                .Select(a =>
                        {
                            var account = _accountsCacheService.Get(c.Key, a.Key);
                            if (account == null)
                            {
                                return(null);
                            }
                            return(new OvernightSwapNotification.AccountCalculations()
                            {
                                AccountId = a.Key,
                                AccountCurrency = account.BaseAssetId,
                                Calculations = a.Select(calc =>
                                {
                                    var instrumentName = _assetPairsCache.GetAssetPairByIdOrDefault(calc.Instrument)?.Name
                                                         ?? calc.Instrument;
                                    return new OvernightSwapNotification.SingleCalculation
                                    {
                                        Instrument = instrumentName,
                                        Direction = calc.Direction == OrderDirection.Buy ? "Long" : "Short",
                                        Volume = calc.Volume,
                                        SwapRate = calc.SwapRate,
                                        Cost = calc.Value,
                                        PositionId = calc.OpenOrderId,
                                    };
                                }).ToList()
                            });
                        }).Where(x => x != null).ToList()
                    }
                                                );

                    var clientsWithIncorrectMail = new List <string>();
                    var clientsSentEmails        = new List <string>();
                    foreach (var notification in notifications)
                    {
                        try
                        {
                            var clientEmail = await _clientAccountService.GetEmail(notification.CliendId);
                            if (string.IsNullOrEmpty(clientEmail))
                            {
                                clientsWithIncorrectMail.Add(notification.CliendId);
                                continue;
                            }

                            await _emailService.SendOvernightSwapEmailAsync(clientEmail, notification);
                            clientsSentEmails.Add(notification.CliendId);
                        }
                        catch (Exception e)
                        {
                            await _log.WriteErrorAsync(nameof(OvernightSwapNotificationService),
                                                       nameof(PerformEmailNotification), e, DateTime.UtcNow);
                        }
                    }

                    if (clientsWithIncorrectMail.Any())
                    {
                        await _log.WriteWarningAsync(nameof(OvernightSwapNotificationService), nameof(PerformEmailNotification),
                                                     $"Emails of some clients are incorrect: {string.Join(", ", clientsWithIncorrectMail)}.", DateTime.UtcNow);
                    }
                    if (clientsSentEmails.Any())
                    {
                        await _log.WriteInfoAsync(nameof(OvernightSwapNotificationService), nameof(PerformEmailNotification),
                                                  $"Emails sent to: {string.Join(", ", clientsSentEmails)}.", DateTime.UtcNow);
                    }
                }
                finally
                {
                    _semaphore.Release();
                }
            });
        }