private async Task ClosePositionsAsync(IEnumerable <Position> positions, PositionType positionType) { foreach (IGrouping <string, Position> group in positions.GroupBy(o => o.AssetPairId)) { var startedAt = DateTime.UtcNow; MarketMakerState marketMakerState = await _marketMakerStateService.GetStateAsync(); if (marketMakerState.Status != MarketMakerStatus.Active) { continue; } Instrument instrument = await _instrumentService.GetByAssetPairIdAsync(group.Key); decimal originalVolume = group.Sum(o => o.Volume); decimal volume = Math.Round(originalVolume, instrument.VolumeAccuracy); if (volume < instrument.MinVolume) { _log.InfoWithDetails("The volume of open positions is less than min volume", new { instrument.AssetPairId, positionType, volume, instrument.MinVolume }); continue; } ExternalTrade externalTrade = await ExecuteLimitOrderAsync(group.Key, volume, positionType); if (externalTrade != null) { await _positionService.CloseAsync(group.ToArray(), externalTrade); await _remainingVolumeService.RegisterVolumeAsync(group.Key, (originalVolume - externalTrade.Volume) *GetSign(positionType)); } var finishedAt = DateTime.UtcNow; _log.Info("HedgeService.ClosePositionsAsync() completed.", new { AssetPairId = instrument.AssetPairId, TradeIds = positions.Select(x => x.TradeId).ToList(), StartedAt = startedAt, FinishedAt = finishedAt, Latency = (finishedAt - startedAt).TotalMilliseconds }); PrometheusMetrics.HedgeAssetPairLatency.Inc((finishedAt - startedAt).TotalMilliseconds); } }
private async Task ClosePositionsAsync(IEnumerable <Position> positions, PositionType positionType) { foreach (IGrouping <string, Position> group in positions.GroupBy(o => o.AssetPairId)) { MarketMakerState marketMakerState = await _marketMakerStateService.GetStateAsync(); if (marketMakerState.Status != MarketMakerStatus.Active) { continue; } Instrument instrument = await _instrumentService.GetByAssetPairIdAsync(group.Key); decimal originalVolume = group.Sum(o => o.Volume); decimal volume = Math.Round(originalVolume, instrument.VolumeAccuracy); if (volume < instrument.MinVolume) { _log.InfoWithDetails("The volume of open positions is less than min volume", new { instrument.AssetPairId, positionType, volume, instrument.MinVolume }); continue; } ExternalTrade externalTrade = await ExecuteLimitOrderAsync(group.Key, volume, positionType); if (externalTrade != null) { await _positionService.CloseAsync(group.ToArray(), externalTrade); await _remainingVolumeService.RegisterVolumeAsync(group.Key, (originalVolume - volume) *GetSign(positionType)); } } }
private async Task ValidateMarketMakerStateAsync(IEnumerable <OrderBook> orderBooks) { MarketMakerState state = await _marketMakerStateService.GetStateAsync(); if (state.Status == MarketMakerStatus.Error) { SetError(orderBooks.SelectMany(o => o.LimitOrders), LimitOrderError.MarketMakerError); } else if (state.Status == MarketMakerStatus.Disabled) { SetError(orderBooks.SelectMany(o => o.LimitOrders), LimitOrderError.Idle); } }
public async Task <MarketMakerStateModel> GetStateAsync() { MarketMakerState state = await _marketMakerStateService.GetStateAsync(); return(Mapper.Map <MarketMakerStateModel>(state)); }