public async Task DeleteAsync(string assetPairId) { Instrument instrument = await GetByAssetPairIdAsync(assetPairId); if (instrument.Mode == InstrumentMode.Active) { throw new InvalidOperationException("Can not remove active instrument"); } IReadOnlyCollection <RemainingVolume> remainingVolumes = await _remainingVolumeService.GetAllAsync(); RemainingVolume remainingVolume = remainingVolumes.SingleOrDefault(o => o.AssetPairId == instrument.AssetPairId); if (remainingVolume != null && remainingVolume.Volume != 0) { throw new InvalidOperationException("Can not remove instrument while remaining volume exist"); } await _instrumentRepository.DeleteAsync(assetPairId); await _crossInstrumentRepository.DeleteAsync(assetPairId); await _remainingVolumeService.DeleteAsync(assetPairId); _cache.Remove(assetPairId); _log.InfoWithDetails("Instrument was deleted", instrument); }
private async Task CloseRemainingVolumeAsync() { IReadOnlyCollection <RemainingVolume> remainingVolumes = await _remainingVolumeService.GetAllAsync(); foreach (RemainingVolume remainingVolume in remainingVolumes) { MarketMakerState marketMakerState = await _marketMakerStateService.GetStateAsync(); if (marketMakerState.Status != MarketMakerStatus.Active) { continue; } Instrument instrument = await _instrumentService.GetByAssetPairIdAsync(remainingVolume.AssetPairId); if (Math.Abs(remainingVolume.Volume) < instrument.MinVolume) { continue; } decimal volume = Math.Round(Math.Abs(remainingVolume.Volume), instrument.VolumeAccuracy); PositionType positionType = remainingVolume.Volume > 0 ? PositionType.Long : PositionType.Short; ExternalTrade externalTrade = await ExecuteLimitOrderAsync(instrument.AssetPairId, volume, positionType); if (externalTrade != null) { await _positionService.CloseRemainingVolumeAsync(instrument.AssetPairId, externalTrade); await _remainingVolumeService.RegisterVolumeAsync(instrument.AssetPairId, volume *GetSign(positionType) * -1); } } }
public async Task <IReadOnlyCollection <RemainingVolumeModel> > GetAllAsync() { IReadOnlyCollection <RemainingVolume> instruments = await _remainingVolumeService.GetAllAsync(); return(Mapper.Map <RemainingVolumeModel[]>(instruments)); }
private async Task CloseRemainingVolumeAsync() { var startedAt = DateTime.UtcNow; // close remaining volumes once per 1 min lock (_remainingSync) { if ((startedAt - _lastCloseRemaining).TotalSeconds > 60) { _lastCloseRemaining = startedAt; } else { return; } } IReadOnlyCollection <RemainingVolume> remainingVolumes = await _remainingVolumeService.GetAllAsync(); foreach (RemainingVolume remainingVolume in remainingVolumes) { MarketMakerState marketMakerState = await _marketMakerStateService.GetStateAsync(); if (marketMakerState.Status != MarketMakerStatus.Active) { continue; } Instrument instrument = await _instrumentService.GetByAssetPairIdAsync(remainingVolume.AssetPairId); if (Math.Abs(remainingVolume.Volume) < instrument.MinVolume) { continue; } decimal volume = Math.Round(Math.Abs(remainingVolume.Volume), instrument.VolumeAccuracy); PositionType positionType = remainingVolume.Volume > 0 ? PositionType.Long : PositionType.Short; ExternalTrade externalTrade = await ExecuteLimitOrderAsync(instrument.AssetPairId, volume, positionType); if (externalTrade != null) { await _positionService.CloseRemainingVolumeAsync(instrument.AssetPairId, externalTrade); await _remainingVolumeService.RegisterVolumeAsync(instrument.AssetPairId, externalTrade.Volume *GetSign(positionType) * -1); } } var finishedAt = DateTime.UtcNow; _log.Info("HedgeService.CloseRemainingVolumeAsync() completed.", new { StartedAt = startedAt, FinishedAt = finishedAt, Latency = (finishedAt - startedAt).TotalMilliseconds }); }