public static void Set(this DefaultLegalEntitySettings defaults, AssetPairContract contract) { if (string.IsNullOrWhiteSpace(contract.LegalEntity)) { contract.LegalEntity = defaults.DefaultLegalEntity; } }
private static async Task CheckAssetPairsApiWorking(IHttpClientGenerator clientGenerator) { var assetPairContract = new AssetPairContract { Id = "t1", Name = "1", BaseAssetId = "1", QuoteAssetId = "1", Accuracy = 3, MarketId = "1", LegalEntity = "1", BasePairId = "1", MatchingEngineMode = MatchingEngineModeContract.MarketMaker, StpMultiplierMarkupBid = 1, StpMultiplierMarkupAsk = 1, }; var assetPairsApiClient = clientGenerator.Generate <IAssetPairsApi>(); await assetPairsApiClient.List().Dump(); if (await assetPairsApiClient.Get("t1") == null) { await assetPairsApiClient.Insert(assetPairContract).Dump(); } var obj = await assetPairsApiClient.Get("t1").Dump(); //TODO validate values here await assetPairsApiClient.Update("t1", new AssetPairUpdateRequest { Id = "t1", MarketId = "m11111" }).Dump(); await assetPairsApiClient.Delete("t1"); }
public async Task <AssetPairContract> Insert([FromBody] AssetPairContract assetPair) { await ValidatePairInsert(assetPair); _defaultLegalEntitySettings.Set(assetPair); var inserted = await _assetPairsRepository.InsertAsync( _convertService.Convert <AssetPairContract, AssetPair>(assetPair)); if (inserted == null) { throw new ArgumentException($"Asset pair with id {assetPair.Id} already exists", nameof(assetPair.Id)); } var insertedContract = _convertService.Convert <IAssetPair, AssetPairContract>(inserted); await _eventSender.SendSettingsChangedEvent($"{Request.Path}", SettingsChangedSourceType.AssetPair, inserted.Id); await _cqrsMessageSender.SendAssetPairChangedEvent(new AssetPairChangedEvent { OperationId = Guid.NewGuid().ToString("N"), AssetPair = insertedContract, }); return(insertedContract); }
private static AssetPairSettings CreateAssetPairSettings(AssetPairContract s) { s.Id.RequiredNotNullOrWhiteSpace(nameof(s.Id)); s.BasePairId.RequiredNotNullOrWhiteSpace(nameof(s.BasePairId)); s.MatchingEngineMode.RequiredEqualsTo(MatchingEngineModeContract.Stp, nameof(s.MatchingEngineMode)); s.StpMultiplierMarkupBid.RequiredGreaterThan(0, nameof(s.StpMultiplierMarkupBid)); s.StpMultiplierMarkupAsk.RequiredGreaterThan(0, nameof(s.StpMultiplierMarkupAsk)); return(new AssetPairSettings( new AssetPairMarkupsParams(s.StpMultiplierMarkupBid, s.StpMultiplierMarkupAsk), s.Id)); }
private AssetPairInfo Convert(AssetPairContract pair) { return(_convertService.Convert <AssetPairContract, AssetPairInfo>(pair)); }
// NOTE: Use Demo instances for tests private static async Task Run() { var services = new ServiceCollection(); var builder = new ContainerBuilder(); var retryStrategy = new LinearRetryStrategy(TimeSpan.FromSeconds(10), 50); services.RegisterMtBackendClient(HttpClientGenerator.BuildForUrl("http://localhost:5000") .WithApiKey("margintrading").WithRetriesStrategy(retryStrategy).Create()); services.RegisterMtDataReaderClient(HttpClientGenerator.BuildForUrl("http://localhost:5008") .WithApiKey("margintrading").WithRetriesStrategy(retryStrategy).Create()); builder.Populate(services); var container = builder.Build(); var backendClient = container.Resolve <IMtBackendClient>(); await backendClient.ScheduleSettings.ListExclusions().Dump(); var excl = await backendClient.ScheduleSettings.CreateExclusion(new DayOffExclusionInputContract { AssetPairRegex = "lol", Start = DateTime.Now.AddDays(-1), End = DateTime.Now.Date, IsTradeEnabled = false, }).Dump(); var id = excl.Id; var ex = await backendClient.ScheduleSettings.GetExclusion(id).Dump(); ex.AssetPairRegex = "^btc"; await backendClient.ScheduleSettings.UpdateExclusion(id, ex).Dump(); await backendClient.ScheduleSettings.GetExclusion(id).Dump(); await backendClient.ScheduleSettings.ListCompiledExclusions().Dump(); await backendClient.ScheduleSettings.DeleteExclusion(id).Dump(); await backendClient.ScheduleSettings.GetExclusion(id).Dump(); var s = await backendClient.ScheduleSettings.GetSchedule().Dump(); s.AssetPairsWithoutDayOff.Add("BTCRABBIT"); await backendClient.ScheduleSettings.SetSchedule(s).Dump(); s.AssetPairsWithoutDayOff.Remove("BTCRABBIT"); await backendClient.ScheduleSettings.SetSchedule(s).Dump(); var assetPairSettingsInputContract = new AssetPairContract { Id = "BTCUSD.test", BasePairId = "BTCUSD", LegalEntity = "LYKKETEST", StpMultiplierMarkupBid = 0.9m, StpMultiplierMarkupAsk = 1.1m, MatchingEngineMode = MatchingEngineModeContract.MarketMaker, Name = "BTCUSD.test name", Accuracy = 123, BaseAssetId = "BTC", QuoteAssetId = "USD", }; await backendClient.AssetPairsEdit.Delete("BTCUSD.test").Dump(); var result = await backendClient.AssetPairsEdit.Insert("BTCUSD.test", assetPairSettingsInputContract) .Dump(); CheckAssetPair(result, assetPairSettingsInputContract); assetPairSettingsInputContract.MatchingEngineMode = MatchingEngineModeContract.Stp; var result2 = await backendClient.AssetPairsEdit.Update("BTCUSD.test", assetPairSettingsInputContract) .Dump(); CheckAssetPair(result2, assetPairSettingsInputContract); var dataReaderClient = container.Resolve <IMtDataReaderClient>(); var list = await dataReaderClient.AssetPairsRead.List().Dump(); var ours = list.First(e => e.Id == "BTCUSD.test"); CheckAssetPair(ours, assetPairSettingsInputContract); var get = await dataReaderClient.AssetPairsRead.Get("BTCUSD.test").Dump(); CheckAssetPair(get, assetPairSettingsInputContract); var nonexistentGet = await dataReaderClient.AssetPairsRead.Get("nonexistent").Dump(); nonexistentGet.RequiredEqualsTo(null, nameof(nonexistentGet)); var getByMode = await dataReaderClient.AssetPairsRead.List("LYKKETEST", MatchingEngineModeContract.Stp) .Dump(); var ours2 = getByMode.First(e => e.Id == "BTCUSD.test"); CheckAssetPair(ours2, assetPairSettingsInputContract); var getByOtherMode = await dataReaderClient.AssetPairsRead .List("LYKKETEST", MatchingEngineModeContract.MarketMaker).Dump(); getByOtherMode.Count(e => e.Id == "BTCUSD.test").RequiredEqualsTo(0, "getByOtherMode.Count"); var result3 = await backendClient.AssetPairsEdit.Delete("BTCUSD.test").Dump(); CheckAssetPair(result3, assetPairSettingsInputContract); var nonexistentDelete = await backendClient.AssetPairsEdit.Delete("nonexistent").Dump(); nonexistentDelete.RequiredEqualsTo(null, nameof(nonexistentDelete)); #region TradeMonitoring var assetSumary = await dataReaderClient.TradeMonitoringRead.AssetSummaryList().Dump(); var openPositions = await dataReaderClient.TradeMonitoringRead.OpenPositions().Dump(); var openPosition = openPositions.FirstOrDefault(); if (openPosition != null) { string clientId = openPosition.ClientId; var openPositionsByClient = await dataReaderClient.TradeMonitoringRead.OpenPositionsByClient(clientId).Dump(); } var openPositionsByDate = await dataReaderClient.TradeMonitoringRead .OpenPositionsByDate(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow).Dump(); var openPositionsByVolume = await dataReaderClient.TradeMonitoringRead.OpenPositionsByVolume(100).Dump(); var pendingOrders = await dataReaderClient.TradeMonitoringRead.PendingOrders().Dump(); var pendingOrder = pendingOrders.FirstOrDefault(); if (pendingOrder != null) { string clientId = pendingOrder.ClientId; var pendingOrdersByClient = await dataReaderClient.TradeMonitoringRead.PendingOrdersByClient(clientId).Dump(); } var pendingOrdersByDate = await dataReaderClient.TradeMonitoringRead .PendingOrdersByDate(DateTime.UtcNow.AddDays(-30), DateTime.UtcNow).Dump(); var pendingOrdersByVolume = await dataReaderClient.TradeMonitoringRead.PendingOrdersByVolume(100).Dump(); var orderBooksByInstrument = await dataReaderClient.TradeMonitoringRead.OrderBooksByInstrument("BTCUSD"); #endregion var accountAssetPairs = await dataReaderClient.AccountAssetPairsRead .List() .Dump(); var firstAccountAssetPair = accountAssetPairs.First(); var secondAccountAssetPair = await dataReaderClient.AccountAssetPairsRead .Get(firstAccountAssetPair.TradingConditionId, firstAccountAssetPair.BaseAssetId, firstAccountAssetPair.Instrument) .Dump(); firstAccountAssetPair.Should().BeEquivalentTo(secondAccountAssetPair); var accountAssetPairsGetByTradingCondition = await dataReaderClient.AccountAssetPairsRead .Get(firstAccountAssetPair.TradingConditionId, firstAccountAssetPair.BaseAssetId) .Dump(); foreach (var accountAssetPair in accountAssetPairsGetByTradingCondition) { var item = accountAssetPairs .Single(x => x.TradingConditionId == accountAssetPair.TradingConditionId && x.BaseAssetId == accountAssetPair.BaseAssetId && x.Instrument == accountAssetPair.Instrument); item.Should().BeEquivalentTo(accountAssetPair); } firstAccountAssetPair.OvernightSwapLong = 0.1m; var updatedAccountAssetPair = await backendClient.TradingConditionsEdit .InsertOrUpdateAccountAsset(firstAccountAssetPair) .Dump(); updatedAccountAssetPair.Result.Should().BeEquivalentTo(firstAccountAssetPair); var tc = await backendClient.TradingConditionsEdit.InsertOrUpdate( new Contracts.TradingConditions.TradingConditionContract { Id = "LYKKETEST", LegalEntity = "LYKKEVA", IsDefault = false, Name = "Test Trading Condition", }).Dump(); tc.Result.Id.RequiredEqualsTo("LYKKETEST", "tc.Result.Id"); var ag = await backendClient.TradingConditionsEdit.InsertOrUpdateAccountGroup( new Contracts.TradingConditions.AccountGroupContract { BaseAssetId = "BTC", TradingConditionId = tc.Result.Id, DepositTransferLimit = 0.1m, ProfitWithdrawalLimit = 0.2m, MarginCall = 0.3m, StopOut = 0.4m }) .Dump(); ag.Result.StopOut.RequiredEqualsTo(0.4m, "ag.Result.StopOut"); var aa = await backendClient.TradingConditionsEdit.InsertOrUpdateAccountAsset(new AccountAssetPairContract { Instrument = "TSTLKK", BaseAssetId = "BTC", TradingConditionId = tc.Result.Id }) .Dump(); aa.Result.Instrument.RequiredEqualsTo("TSTLKK", "aa.Result.Instrument"); var ai = await backendClient.TradingConditionsEdit.AssignInstruments( new Contracts.TradingConditions.AssignInstrumentsContract { BaseAssetId = "BTC", TradingConditionId = tc.Result.Id, Instruments = new string[] { "TSTLKK" } }) .Dump(); ai.IsOk.RequiredEqualsTo(true, "ai.IsOk"); var tclist = await dataReaderClient.TradingConditionsRead.List().Dump(); await dataReaderClient.TradingConditionsRead.Get(tclist.First().Id).Dump(); var manualCharge = await backendClient.AccountsBalance.ChargeManually( new Contracts.AccountBalance.AccountChargeManuallyRequest { ClientId = "232b3b04-7479-44e7-a6b3-ac131d8e6ccd", AccountId = "d_f4c745f19c834145bcf2d6b5f1a871f3", Amount = 1, Reason = "API TEST" }) .Dump(); var accountGroups = await dataReaderClient.AccountGroups.List().Dump(); var accountGroup1 = accountGroups.FirstOrDefault(); if (accountGroup1 != null) { var accountGroup = (await dataReaderClient.AccountGroups.GetByBaseAsset(accountGroup1.TradingConditionId, accountGroup1.BaseAssetId)).Dump(); accountGroup.Should().BeEquivalentTo(accountGroup1); } var assetPairs = await dataReaderClient.Dictionaries.AssetPairs().Dump(); var matchingEngines = await dataReaderClient.Dictionaries.MatchingEngines().Dump(); var orderTypes = await dataReaderClient.Dictionaries.OrderTypes().Dump(); var routes = await dataReaderClient.Routes.List().Dump(); var route1 = routes.FirstOrDefault(); if (route1 != null) { var route = await dataReaderClient.Routes.GetById(route1.Id).Dump(); route.Should().BeEquivalentTo(route1); } var isEnabled = await dataReaderClient.Settings.IsMarginTradingEnabled("232b3b04-7479-44e7-a6b3-ac131d8e6ccd"); Console.WriteLine("Successfuly finished"); }
private static void CheckAssetPair(AssetPairContract actual, AssetPairContract expected) { actual.Should().BeEquivalentTo(expected); }
private async Task ValidatePairInsert(AssetPairContract assetPair) { if (assetPair == null) { throw new ArgumentNullException(nameof(assetPair), "Model is incorrect"); } if (string.IsNullOrWhiteSpace(assetPair.Id)) { throw new ArgumentNullException(nameof(assetPair.Id), "AssetPair Id must be set"); } if (!Enum.IsDefined(typeof(MatchingEngineModeContract), assetPair.MatchingEngineMode)) { throw new ArgumentNullException(nameof(assetPair.MatchingEngineMode), "AssetPair MatchingEngineMode must be set"); } if (await _assetsRepository.GetAsync(assetPair.BaseAssetId) == null) { throw new InvalidOperationException($"Base Asset {assetPair.BaseAssetId} does not exist"); } if (await _assetsRepository.GetAsync(assetPair.QuoteAssetId) == null) { throw new InvalidOperationException($"Quote Asset {assetPair.QuoteAssetId} does not exist"); } if (!string.IsNullOrEmpty(assetPair.MarketId) && await _marketRepository.GetAsync(assetPair.MarketId) == null) { throw new InvalidOperationException($"Market {assetPair.MarketId} does not exist"); } if (assetPair.StpMultiplierMarkupAsk <= 0) { throw new InvalidOperationException($"StpMultiplierMarkupAsk must be greater then zero"); } if (assetPair.StpMultiplierMarkupBid <= 0) { throw new InvalidOperationException($"StpMultiplierMarkupBid must be greater then zero"); } if (await _assetPairsRepository.GetByBaseQuoteAndLegalEntityAsync(assetPair.BaseAssetId, assetPair.QuoteAssetId, assetPair.LegalEntity) != null) { throw new InvalidOperationException($"Asset pair with base asset [{assetPair.BaseAssetId}], quote asset [{assetPair.QuoteAssetId}] and legal entity [{assetPair.LegalEntity}] already exists"); } //base pair check <-- the last one if (assetPair.BasePairId == null) { return; } if (await _assetPairsRepository.GetAsync(assetPair.BasePairId) == null) { throw new InvalidOperationException($"BasePair with Id {assetPair.BasePairId} does not exist"); } if (await _assetPairsRepository.GetByBaseAssetPairAsync(assetPair.BasePairId) != null) { throw new InvalidOperationException($"BasePairId {assetPair.BasePairId} does not exist"); } if (await _assetPairsRepository.GetByBaseAssetPairAndNotByIdAsync(assetPair.Id, assetPair.BasePairId) != null) { throw new InvalidOperationException($"BasePairId {assetPair.BasePairId} cannot be added twice"); } }