protected override async Task <(RecipeAction ToSave, GetExchangeRateViewModel showViewModel)> BuildModel( GetExchangeRateViewModel viewModel, RecipeAction mainModel) { if (ModelState.IsValid) { var serviceData = await _externalServiceManager.GetExternalServiceData(viewModel.ExternalServiceId, GetUserId()); var exchangeService = new ExchangeService(serviceData); var symbols = (await(await exchangeService.ConstructClient()).GetMarketSymbolsAsync()).ToArray(); if (symbols.Contains(viewModel.MarketSymbol)) { mainModel.ExternalServiceId = viewModel.ExternalServiceId; mainModel.Set <GetExchangeRateData>(viewModel); return(mainModel, null); } ModelState.AddModelError(nameof(GetExchangeRateViewModel.MarketSymbol), $"The market symbols you entered is invalid. Please choose from the following: {string.Join(",", symbols)}"); } var services = await _externalServiceManager.GetExternalServicesData(new ExternalServicesDataQuery() { Type = new[] { ExchangeService.ExchangeServiceType }, UserId = GetUserId() }); viewModel.ExternalServices = new SelectList(services, nameof(ExternalServiceData.Id), nameof(ExternalServiceData.Name), viewModel.ExternalServiceId); return(null, viewModel); }
public async Task <IActionResult> Create(CreateDCAViewModel viewModel) { var services = await GetServices(); viewModel.ExchangeServices = new SelectList(services, nameof(ExternalServiceData.Id), nameof(ExternalServiceData.Name)); if (viewModel.FiatAmount <= 0) { ModelState.AddModelError(nameof(viewModel.FiatAmount), "Amount needs to be more than 0."); } if (ModelState.IsValid) { var serviceData = await _externalServiceManager.GetExternalServiceData(viewModel.SelectedExchangeServiceId, GetUserId()); var exchangeService = new ExchangeService(serviceData); var symbols = (await(await exchangeService.ConstructClient()).GetMarketSymbolsAsync()).ToArray(); if (!symbols.Contains(viewModel.MarketSymbol)) { viewModel.AddModelError(nameof(viewModel.MarketSymbol), $"The market symbols you entered is invalid. Please choose from the following: {string.Join(",", symbols)}", ModelState); } } if (!ModelState.IsValid) { return(View(viewModel)); } return(await SetItUp(viewModel)); }
public async Task <string[]> GetAvailableMarketSymbols(string externalServiceId) { var serviceData = await _externalServiceManager.GetExternalServiceData(externalServiceId, GetUserId()); var exchangeService = new ExchangeService(serviceData); return((await(await exchangeService.ConstructClient()).GetMarketSymbolsAsync()).ToArray()); }
public async Task <IActionResult> Create(CreateFiatExchangeConversionViewModel viewModel) { var services = await GetServices(); viewModel.BTCPayServices = new SelectList(services.btcPayServices, nameof(ExternalServiceData.Id), nameof(ExternalServiceData.Name)); viewModel.ExchangeServices = new SelectList(services.exchangeServices, nameof(ExternalServiceData.Id), nameof(ExternalServiceData.Name)); if (viewModel.Action.Equals("add-item", StringComparison.InvariantCultureIgnoreCase)) { viewModel.Conditions.Add(new CreateFiatExchangeConversionViewModel.ConversionConditionItem()); return(View(viewModel)); } if (viewModel.Action.StartsWith("remove-item", StringComparison.InvariantCultureIgnoreCase)) { var index = int.Parse(viewModel.Action.Substring(viewModel.Action.IndexOf(":") + 1)); viewModel.Conditions.RemoveAt(index); return(View(viewModel)); } if (!viewModel.Conditions.Any()) { ModelState.AddModelError(nameof(viewModel.Conditions), "You need to add at least one conversion scenario!"); } if (ModelState.IsValid) { for (var index = 0; index < viewModel.Conditions.Count; index++) { var condition = viewModel.Conditions[index]; var serviceData = await _externalServiceManager.GetExternalServiceData(condition.ExchangeServiceId, GetUserId()); var exchangeService = new ExchangeService(serviceData); var symbols = (await exchangeService.ConstructClient().GetMarketSymbolsAsync()).ToArray(); if (!symbols.Contains(condition.MarketSymbol)) { viewModel.AddModelError( $"{nameof(viewModel.Conditions)}[{index}].{nameof(CreateFiatExchangeConversionViewModel.ConversionConditionItem.MarketSymbol)}", $"The market symbols you entered is invalid. Please choose from the following: {string.Join(",", symbols)}", ModelState); } } } if (!ModelState.IsValid) { return(View(viewModel)); } return(await SetItUp(viewModel)); }
protected override async Task <TypedActionHandlerResult <ExchangeOrderResult> > Execute(Dictionary <string, object> data, RecipeAction recipeAction, PlaceOrderData actionData) { var externalService = await recipeAction.GetExternalService(); var exchangeService = new ExchangeService(externalService); var client = await exchangeService.ConstructClient(); var orderRequest = new ExchangeOrderRequest() { MarketSymbol = actionData.MarketSymbol, OrderType = actionData.OrderType, Price = Convert.ToDecimal(InterpolateString(actionData.Price, data)), Amount = Convert.ToDecimal(InterpolateString(actionData.Amount, data)), StopPrice = Convert.ToDecimal(InterpolateString(actionData.StopPrice, data)), IsBuy = actionData.IsBuy, IsMargin = actionData.IsMargin, ShouldRoundAmount = false }; try { var result = await client.PlaceOrderAsync(orderRequest); System.Threading.Thread.Sleep(500); result = await client.GetOrderDetailsAsync(result.OrderId, orderRequest.MarketSymbol); return(new TypedActionHandlerResult <ExchangeOrderResult>() { Executed = true, Result = $"Place order ({result.OrderId}) Status: {result.Result}", TypedData = result }); } catch (Exception e) { return(new TypedActionHandlerResult <ExchangeOrderResult>() { Executed = false, Result = $"Could not place order because {e.Message}. Order details: {JsonConvert.SerializeObject(orderRequest)}" }); } }
protected override async Task <TypedActionHandlerResult <ExchangeTicker> > Execute(Dictionary <string, object> data, RecipeAction recipeAction, GetExchangeRateData actionData) { var externalService = await recipeAction.GetExternalService(); var exchangeService = new ExchangeService(externalService); var client = exchangeService.ConstructClient(); var result = await client.GetTickerAsync(actionData.MarketSymbol); return(new TypedActionHandlerResult <ExchangeTicker>() { Executed = true, Result = $"{result}", TypedData = result }); }
public void ExchangeService_CanConstructClient() { var data = new ExchangeExternalServiceData() { PublicKey = "test", PairedDate = DateTime.Now }; var externalServiceData = new ExternalServiceData() { Type = ExchangeService.ExchangeServiceType, Name = "something" }; externalServiceData.Set(data); var exchangeService = new ExchangeService(externalServiceData); Assert.NotNull(exchangeService.ConstructClient()); }
protected override async Task <TypedActionHandlerResult <decimal> > Execute(Dictionary <string, object> data, RecipeAction recipeAction, GetExchangeBalanceData actionData) { var externalService = await recipeAction.GetExternalService(); var exchangeService = new ExchangeService(externalService); var client = exchangeService.ConstructClient(); var result = await client.GetAmountsAsync(); var amount = result.ContainsKey(actionData.Asset) ? result[actionData.Asset] : 0; return(new TypedActionHandlerResult <decimal>() { Executed = true, Result = $"Got exchange balance {amount}{actionData.Asset}", TypedData = amount }); }
protected override async Task <ActionHandlerResult> Execute(object triggerData, RecipeAction recipeAction, PlaceOrderData actionData) { var exchangeService = new ExchangeService(recipeAction.ExternalService); var client = exchangeService.ConstructClient(); var orderRequest = new ExchangeOrderRequest() { OrderType = actionData.OrderType, Price = Convert.ToDecimal(InterpolateString(actionData.Price, triggerData)), Amount = Convert.ToDecimal(InterpolateString(actionData.Amount, triggerData)), StopPrice = Convert.ToDecimal(InterpolateString(actionData.StopPrice, triggerData)), IsBuy = actionData.IsBuy, IsMargin = actionData.IsMargin, }; try { var result = await client.PlaceOrderAsync(orderRequest); System.Threading.Thread.Sleep(500); result = await client.GetOrderDetailsAsync(result.OrderId); return(new ActionHandlerResult() { Executed = true, Result = $"Place order ({result.OrderId}) Status: {result.Result}" }); } catch (Exception e) { return(new ActionHandlerResult() { Executed = false, Result = $"Could not place order because {e.Message}" }); } }
private async Task UpdateBalances_Continuously( CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var exchangeExternalServices = await _externalServiceManager.GetExternalServicesData(new ExternalServicesDataQuery() { Type = new string[] { ExchangeService.ExchangeServiceType } }); await Task.WhenAll(exchangeExternalServices.Select(async data => { var exchangeService = new ExchangeService(data); var client = exchangeService.ConstructClient(); var amounts = await client.GetAmountsAsync(); foreach (var keyValuePair in amounts) { _ = _triggerDispatcher.DispatchTrigger(new CheckExchangeBalanceTrigger() { Data = new CheckExchangeBalanceTriggerData() { Balance = keyValuePair.Value, Asset = keyValuePair.Key, ExternalServiceId = data.Id } }); } })); await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken); } }
protected override async Task <TypedActionHandlerResult <decimal> > Execute(Dictionary <string, object> data, RecipeAction recipeAction, GetExchangeBalanceData actionData) { var externalService = await recipeAction.GetExternalService(); var exchangeService = new ExchangeService(externalService); var client = exchangeService.ConstructClient(); var result = await client.GetAmountsAsync(); var matched = result .FirstOrDefault(pair => pair.Key.Equals(actionData.Asset, StringComparison.InvariantCultureIgnoreCase)); var amount = matched.Value; return(new TypedActionHandlerResult <decimal>() { Executed = true, Result = $"Got exchange balance {amount}{actionData.Asset}", TypedData = amount }); }