Exemplo n.º 1
0
        public AccountsMarginLevelResponse GetAccountsMarginLevels(decimal threshold)
        {
            var accounts = _accountsCacheService.GetAll()
                           .Select(a =>
                                   new AccountsMarginLevelContract
            {
                AccountId            = a.Id,
                ClientId             = a.ClientId,
                TradingConditionId   = a.TradingConditionId,
                BaseAssetId          = a.BaseAssetId,
                Balance              = a.Balance,
                MarginLevel          = a.GetMarginUsageLevel(),
                OpenedPositionsCount = a.GetOpenPositionsCount(),
                UsedMargin           = a.GetUsedMargin(),
                TotalBalance         = a.GetTotalCapital()
            })
                           .Where(a => a.MarginLevel <= threshold)
                           .ToArray();

            return(new AccountsMarginLevelResponse
            {
                DateTime = _dateService.Now(),
                Levels = accounts
            });
        }
Exemplo n.º 2
0
        public async Task <InitDataBackendResponse> InitData([FromBody] ClientIdBackendRequest request)
        {
            if (string.IsNullOrWhiteSpace(request?.ClientId))
            {
                throw new ArgumentNullException(nameof(ClientIdBackendRequest.ClientId));
            }

            var accounts = _accountsCacheService.GetAll(request.ClientId).ToArray();

            if (accounts.Length == 0 && !_marginSettings.IsLive)
            {
                accounts = await _accountManager.CreateDefaultAccounts(request.ClientId);
            }

            if (accounts.Length == 0)
            {
                return(InitDataBackendResponse.CreateEmpty());
            }

            var assets = _accountAssetsCacheService.GetClientAssets(accounts);

            var result = BackendContractFactory.CreateInitDataBackendResponse(accounts, assets, _marginSettings.IsLive);

            result.IsLive = _marginSettings.IsLive;

            return(result);
        }
Exemplo n.º 3
0
        private void ValidateClient(string clientId)
        {
            var userAccounts = _accountsCacheService.GetAll(clientId);

            if (!userAccounts.Any())
            {
                throw new ArgumentException("Invalid ClientId");
            }
        }
Exemplo n.º 4
0
        public async Task DumpReportData()
        {
            var positions   = _ordersCache.GetPositions();
            var accountStat = _accountsCacheService.GetAll();

            await Task.WhenAll(
                _openPositionsRepository.Dump(positions),
                _accountStatRepository.Dump(accountStat));
        }
Exemplo n.º 5
0
        private void HandleOvernightMarginWarnings()
        {
            foreach (var account in _accountsCacheService.GetAll())
            {
                var accountOvernightUsedMargin = _accountUpdateService.CalculateOvernightUsedMargin(account);
                var accountLevel = account.GetAccountLevel(accountOvernightUsedMargin);

                if (accountLevel == AccountLevel.StopOut)
                {
                    _marginCallEventChannel.SendEvent(this,
                                                      new MarginCallEventArgs(account, AccountLevel.OvernightMarginCall));
                }
            }
        }
Exemplo n.º 6
0
        public async Task <string> MakeTradingDataSnapshot(DateTime tradingDay, string correlationId)
        {
            if (!_scheduleSettingsCacheService.TryGetPlatformCurrentDisabledInterval(out var disabledInterval))
            {
                throw new Exception(
                          "Trading should be stopped for whole platform in order to make trading data snapshot.");
            }

            if (disabledInterval.Start.AddDays(-1) > tradingDay.Date || disabledInterval.End < tradingDay.Date)
            {
                throw new Exception(
                          $"{nameof(tradingDay)}'s Date component must be from current disabled interval's Start -1d to End: [{disabledInterval.Start.AddDays(-1)}, {disabledInterval.End}].");
            }

            await _semaphoreSlim.WaitAsync();

            try
            {
                var orders       = _orderReader.GetAllOrders();
                var positions    = _orderReader.GetPositions();
                var accountStats = _accountsCacheService.GetAll();
                var bestFxPrices = _fxRateCacheService.GetAllQuotes();
                var bestPrices   = _quoteCacheService.GetAllQuotes();

                await _tradingEngineSnapshotsRepository.Add(tradingDay,
                                                            correlationId,
                                                            _dateService.Now(),
                                                            orders.Select(x => x.ConvertToContract(_orderReader)).ToJson(),
                                                            positions.Select(x => x.ConvertToContract(_orderReader)).ToJson(),
                                                            accountStats.Select(x => x.ConvertToContract()).ToJson(),
                                                            bestFxPrices.ToDictionary(q => q.Key, q => q.Value.ConvertToContract()).ToJson(),
                                                            bestPrices.ToDictionary(q => q.Key, q => q.Value.ConvertToContract()).ToJson());

                return($@"Trading data snapshot was written to the storage. 
Orders: {orders.Length}, positions: {positions.Length}, accounts: {accountStats.Count}, 
best FX prices: {bestFxPrices.Count}, best trading prices: {bestPrices.Count}.");
            }
            finally
            {
                _semaphoreSlim.Release();
            }
        }
Exemplo n.º 7
0
        public Task Handle(MarketStateChangedEvent e, ICommandSender sender)
        {
            if (!e.IsEnabled)
            {
                return(Task.CompletedTask);
            }

            // resuming liquidations on corresponding accounts upon market open
            _accountsCacheService.GetAll()
            .Where(a => a.IsInLiquidation())
            .SelectMany(a => _ordersCache.Positions.GetPositionsByAccountIds(a.Id))
            .GroupBy(p => p.AccountId)
            .Where(AnyAssetRelatesToMarket)
            .ForEach(account => SendResumeCommand(account.Key));

            return(Task.CompletedTask);

            #region internal functions

            bool AnyAssetRelatesToMarket(IGrouping <string, Position> positions) =>
            positions
            .Select(p => _assetPairsCache.GetAssetPairById(p.AssetPairId))
            .Any(assetPair => assetPair.MarketId == e.Id);

            void SendResumeCommand(string accountId)
            {
                var account = _accountsCacheService.Get(accountId);

                sender.SendCommand(new ResumeLiquidationInternalCommand
                {
                    OperationId  = account.LiquidationOperationId,
                    CreationTime = DateTime.UtcNow,
                    IsCausedBySpecialLiquidation = false,
                    ResumeOnlyFailed             = true,
                    Comment = "Trying to resume liquidation because market has been opened"
                }, _cqrsContextNamesSettings.TradingEngine);
            }

            #endregion
        }
Exemplo n.º 8
0
        public Task <List <AccountStatContract> > GetAllAccountStats()
        {
            var stats = _accountsCacheService.GetAll();

            return(Task.FromResult(stats.Select(x => x.ConvertToContract()).ToList()));
        }
Exemplo n.º 9
0
        public MarginTradingAccountBackendContract[] GetAllAccounts()
        {
            var accounts = _accountsCacheService.GetAll();

            return(accounts.Select(item => item.ToFullBackendContract(_marginSettings.IsLive)).ToArray());
        }
Exemplo n.º 10
0
        public IActionResult GetAllMarginTradingAccounts(string clientId)
        {
            var accounts = _accountsCacheService.GetAll(clientId);

            return(Ok(accounts));
        }
Exemplo n.º 11
0
        /// <inheritdoc />
        public async Task <string> MakeTradingDataSnapshot(DateTime tradingDay, string correlationId, SnapshotStatus status = SnapshotStatus.Final)
        {
            if (!_scheduleSettingsCacheService.TryGetPlatformCurrentDisabledInterval(out var disabledInterval))
            {
                //TODO: remove later (if everything will work and we will never go to this branch)
                _scheduleSettingsCacheService.MarketsCacheWarmUp();

                if (!_scheduleSettingsCacheService.TryGetPlatformCurrentDisabledInterval(out disabledInterval))
                {
                    throw new Exception(
                              $"Trading should be stopped for whole platform in order to make trading data snapshot. Current schedule: {_scheduleSettingsCacheService.GetPlatformTradingSchedule()?.ToJson()}");
                }
            }

            if (disabledInterval.Start.AddDays(-1) > tradingDay.Date || disabledInterval.End < tradingDay.Date)
            {
                throw new Exception(
                          $"{nameof(tradingDay)}'s Date component must be from current disabled interval's Start -1d to End: [{disabledInterval.Start.AddDays(-1)}, {disabledInterval.End}].");
            }

            if (Lock.CurrentCount == 0)
            {
                throw new InvalidOperationException("Trading data snapshot creation is already in progress");
            }

            // We must be sure all messages have been processed by history brokers before starting current state validation.
            // If one or more queues contain not delivered messages the snapshot can not be created.
            _queueValidationService.ThrowExceptionIfQueuesNotEmpty(true);

            // Before starting snapshot creation the current state should be validated.
            var validationResult = await _snapshotValidationService.ValidateCurrentStateAsync();

            if (!validationResult.IsValid)
            {
                var ex = new InvalidOperationException(
                    $"The trading data snapshot might be corrupted. The current state of orders and positions is incorrect. Check the dbo.BlobData table for more info: container {LykkeConstants.MtCoreSnapshotBlobContainer}, correlationId {correlationId}");
                await _log.WriteFatalErrorAsync(nameof(SnapshotService),
                                                nameof(MakeTradingDataSnapshot),
                                                validationResult.ToJson(),
                                                ex);

                await _blobRepository.WriteAsync(LykkeConstants.MtCoreSnapshotBlobContainer, correlationId, validationResult);
            }
            else
            {
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          "The current state of orders and positions is correct.");
            }

            await Lock.WaitAsync();

            try
            {
                var orders     = _orderReader.GetAllOrders();
                var ordersJson = orders.Select(o => o.ConvertToSnapshotContract(_orderReader, status)).ToJson();
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Preparing data... {orders.Length} orders prepared.");

                var positions     = _orderReader.GetPositions();
                var positionsJson = positions.Select(p => p.ConvertToSnapshotContract(_orderReader, status)).ToJson();
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Preparing data... {positions.Length} positions prepared.");

                var accountStats = _accountsCacheService.GetAll();
                var accountsJson = accountStats.Select(a => a.ConvertToSnapshotContract(status)).ToJson();
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Preparing data... {accountStats.Count} accounts prepared.");

                var bestFxPrices     = _fxRateCacheService.GetAllQuotes();
                var bestFxPricesData = bestFxPrices.ToDictionary(q => q.Key, q => q.Value.ConvertToContract()).ToJson();
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Preparing data... {bestFxPrices.Count} best FX prices prepared.");

                var bestPrices     = _quoteCacheService.GetAllQuotes();
                var bestPricesData = bestPrices.ToDictionary(q => q.Key, q => q.Value.ConvertToContract()).ToJson();
                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Preparing data... {bestPrices.Count} best trading prices prepared.");

                var msg = $"TradingDay: {tradingDay:yyyy-MM-dd}, Orders: {orders.Length}, positions: {positions.Length}, accounts: {accountStats.Count}, best FX prices: {bestFxPrices.Count}, best trading prices: {bestPrices.Count}.";

                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Starting to write trading data snapshot. {msg}");

                var snapshot = new TradingEngineSnapshot(
                    tradingDay,
                    correlationId,
                    _dateService.Now(),
                    ordersJson: ordersJson,
                    positionsJson: positionsJson,
                    accountsJson: accountsJson,
                    bestFxPricesJson: bestFxPricesData,
                    bestTradingPricesJson: bestPricesData,
                    status: status);

                await _tradingEngineSnapshotsRepository.AddAsync(snapshot);

                await _log.WriteInfoAsync(nameof(SnapshotService), nameof(MakeTradingDataSnapshot),
                                          $"Trading data snapshot was written to the storage. {msg}");

                return($"Trading data snapshot was written to the storage. {msg}");
            }
            finally
            {
                Lock.Release();
            }
        }