/// <summary author="Richard Carroll" created="2019/01/30"> /// Passes information from the Presentation Layer to the Data Access /// Layer and returns the result of the Insertion attempt. /// </summary> public bool CreateInternalOrder(InternalOrder itemOrder, List <VMInternalOrderLine> lines) { bool result = false; try { if (!itemOrder.isValid()) { throw new ArgumentException("Data entered for this order is invalid\n " + itemOrder.ToString()); } foreach (var line in lines) { if (!line.isValid()) { throw new ArgumentException("Data entered for this order is invalid\n" + line.ToString()); } } result = (_itemOrderAccessor.InsertItemOrder(itemOrder, lines) > 0); } catch (Exception ex) { ExceptionLogManager.getInstance().LogException(ex); throw ex; } return(result); }
private async Task <bool> ValidateInstrumentAsync(InternalOrder internalOrder) { Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); string error = null; if (instrument == null) { error = Errors.AssetPairNotSupported; } else if (Math.Round(internalOrder.Volume, instrument.VolumeAccuracy) < instrument.MinVolume) { error = Errors.TooSmallVolume; } else if (Math.Abs(internalOrder.Volume) % 1 * (decimal)Math.Pow(10, instrument.VolumeAccuracy) % 1 != 0) { error = Errors.InvalidVolume; } if (!string.IsNullOrEmpty(error)) { internalOrder.Status = InternalOrderStatus.Rejected; internalOrder.RejectReason = error; await _internalOrderRepository.UpdateAsync(internalOrder); return(false); } return(true); }
public void AddItemOrderTestValidInput() { internalOrder = new InternalOrder() { InternalOrderID = 8000, EmployeeID = 100000, DepartmentID = "Events", Description = "Food Order... maybe", OrderComplete = false, DateOrdered = DateTime.Now }; _internalOrderLine = new VMInternalOrderLine() { ItemID = 100000, OrderQty = 100, QtyReceived = 100 }; lines = new List <VMInternalOrderLine>(); lines.Add(_internalOrderLine); _internalOrderManager.CreateInternalOrder(internalOrder, lines); retrievedOrders = _internalOrderManager.RetrieveAllInternalOrders(); retrievedLines = _internalOrderManager.RetrieveOrderLinesByID(internalOrder.InternalOrderID); Assert.IsNotNull(retrievedOrders.Find(o => o.InternalOrderID == internalOrder.InternalOrderID && o.EmployeeID == internalOrder.EmployeeID && o.DepartmentID == internalOrder.DepartmentID && o.Description == internalOrder.Description && o.OrderComplete == internalOrder.OrderComplete && o.DateOrdered == internalOrder.DateOrdered)); Assert.IsNotNull(retrievedLines.Find(l => l.ItemID == _internalOrderLine.ItemID && l.OrderQty == _internalOrderLine.OrderQty && l.QtyReceived == _internalOrderLine.QtyReceived)); }
/// <summary> /// Richard Carroll /// Created: 2019/01/30 /// /// Pulls Order Data from the fields and Line data from /// the temporary list to call the insert method in the Logic Layer /// </summary> private void BtnSave_Click(object sender, RoutedEventArgs e) { if (checkOrderFields() && lines.Count != 0) { InternalOrder internalOrder = new InternalOrder(); internalOrder.EmployeeID = int.Parse(txtEmployeeID.Text); internalOrder.OrderComplete = ((string)cboOrderComplete.SelectedItem == "Yes"); internalOrder.DateOrdered = dtpDateOrdered.DisplayDate; internalOrder.Description = txtDescription.Text; internalOrder.DepartmentID = txtDepartmentID.Text; try { _internalOrderManager.CreateInternalOrder(internalOrder, lines); MessageBox.Show("Order Submitted Successfully"); this.DialogResult = true; this.Close(); } catch (Exception ex) { MessageBox.Show("Failed to Insert Internal order records: \n" + ex.Message); } } }
private async Task <bool> ReserveFundsAsync(InternalOrder internalOrder) { Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); string assetId; decimal amount; if (internalOrder.Type == LimitOrderType.Sell) { assetId = assetPair.BaseAssetId; amount = internalOrder.Volume; } else { Asset asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); assetId = assetPair.QuotingAssetId; amount = (internalOrder.Volume * internalOrder.Price).TruncateDecimalPlaces(asset.Accuracy, true); } _log.InfoWithDetails("Reserve funds for internal trade", new { OrderId = internalOrder.Id, Asset = assetId, Amount = amount }); string error = null; string walletId = await _settingsService.GetWalletIdAsync(); try { await _lykkeExchangeService.TransferAsync(internalOrder.WalletId, walletId, assetId, amount); } catch (NotEnoughFundsException) { error = Errors.NotEnoughFunds; } catch (Exception) { error = "An unexpected error occurred during reserving funds"; } if (!string.IsNullOrEmpty(error)) { internalOrder.Status = InternalOrderStatus.Rejected; internalOrder.RejectReason = error; await _internalOrderRepository.UpdateAsync(internalOrder); return(false); } internalOrder.Status = InternalOrderStatus.Reserved; await _internalOrderRepository.UpdateAsync(internalOrder); return(true); }
public async Task <string> CreateOrderAsync(string walletId, string assetPairId, LimitOrderType type, decimal price, decimal volume, bool fullExecution) { var internalOrder = new InternalOrder(walletId, assetPairId, type, price, volume, fullExecution); await _internalOrderRepository.InsertAsync(internalOrder); return(internalOrder.Id); }
public static async void ReplaceOrderTimeOnInternalOrder() { // create internal order InternalOrder internalOrder; using (var dbContext = new EfTestDbContext()) { var repo = new InternalOrderRepository(dbContext); var seq = await repo.NextOrderNumber(); internalOrder = new InternalOrder("W-{seq}"); internalOrder.SetTime(new OrderTime("Test")); await repo.Update(internalOrder); await repo.SaveAsync(); Debug.Assert(internalOrder.ID != Guid.Empty); Debug.Assert(null != internalOrder.OrderTimeID); } // replace order time Guid previousOrderTimeId; using (var dbContext = new EfTestDbContext()) { var repo = new InternalOrderRepository(dbContext); // get untracked InternalOrder var order = await dbContext.InternalOrders.Include(x => x.OrderTime).SingleAsync(x => x.ID == internalOrder.ID); previousOrderTimeId = order.OrderTime.ID; order.SetTime(new OrderTime("Test 1234")); Console.WriteLine($"Previous order time id {previousOrderTimeId}"); Console.WriteLine($"Current order time id {order.OrderTime.ID}"); await repo.Update(order); await Task.Delay(1000); // for sensitive logging to settle Console.WriteLine($"-- Before save changes --"); await repo.SaveAsync(); Console.WriteLine($"Current order time id after save {order.OrderTime.ID}"); } // check if OrderTime was deleted using (var dbContext = new EfTestDbContext()) { var repo = new InternalOrderRepository(dbContext); var order = repo.Get(internalOrder.ID); Debug.Assert(false == dbContext.OrderTimes.Any(x => x.ID == previousOrderTimeId), "OrderTime is still present"); Debug.Assert(null != order.OrderTime); Debug.Assert("Test 1234" == order.OrderTime.Display); } }
public async Task <OrderModel> LimitOrderStatusAsync(string orderId) { InternalOrder internalOrder = await _internalOrderService.GetByIdAsync(orderId); if (internalOrder == null) { throw new ValidationApiException(HttpStatusCode.NotFound, "Order not found"); } return(Mapper.Map <OrderModel>(internalOrder)); }
public async Task InsertAsync(InternalOrder internalOrder) { var entity = new InternalOrderEntity(GetPartitionKey(internalOrder.CreatedDate), GetRowKey(internalOrder.Id)); Mapper.Map(internalOrder, entity); await _storage.InsertAsync(entity); AzureIndex index = new AzureIndex(GetIndexPartitionKey(internalOrder.Id), GetIndexRowKey(internalOrder.Id), entity); await _indicesStorage.InsertAsync(index); }
private async Task <bool> TransferFundsAsync(InternalOrder internalOrder) { if (internalOrder.ExecutedVolume == null || internalOrder.ExecutedPrice == null) { throw new InvalidOperationException("The executed volume and price not specified"); } Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); string assetId; decimal amount; if (internalOrder.Type == LimitOrderType.Sell) { Asset asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); assetId = assetPair.QuotingAssetId; amount = (internalOrder.ExecutedVolume.Value * internalOrder.ExecutedPrice.Value) .TruncateDecimalPlaces(asset.Accuracy, true); } else { assetId = assetPair.BaseAssetId; amount = internalOrder.ExecutedVolume.Value; } _log.InfoWithDetails("Transfer funds according internal trade", new { OrderId = internalOrder.Id, Asset = assetId, Amount = amount }); string walletId = await _settingsService.GetWalletIdAsync(); try { await _lykkeExchangeService.TransferAsync(walletId, internalOrder.WalletId, assetId, amount); } catch (Exception exception) { _log.ErrorWithDetails(exception, "Can not transfer funds to destination wallet", internalOrder); return(false); } internalOrder.Status = InternalOrderStatus.Transferred; await _internalOrderRepository.UpdateAsync(internalOrder); return(true); }
private async Task <bool> TransferRemainingFundsAsync(InternalOrder internalOrder) { if (internalOrder.ExecutedVolume == null || internalOrder.ExecutedPrice == null) { throw new InvalidOperationException("The executed volume and price not specified"); } if (internalOrder.Type != LimitOrderType.Buy) { return(true); } Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); Asset asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); decimal originalAmount = internalOrder.Volume * internalOrder.Price; decimal executedAmount = (internalOrder.ExecutedVolume.Value * internalOrder.ExecutedPrice.Value) .TruncateDecimalPlaces(asset.Accuracy, true); decimal amount = originalAmount - executedAmount; amount = Math.Round(amount, asset.Accuracy); if (amount > 0) { _log.InfoWithDetails("Transfer remaining funds according internal trade", new { OrderId = internalOrder.Id, Asset = asset.Id, Amount = amount }); string walletId = await _settingsService.GetWalletIdAsync(); try { await _lykkeExchangeService.TransferAsync(walletId, internalOrder.WalletId, asset.Id, amount); } catch (Exception exception) { _log.ErrorWithDetails(exception, "Can not transfer remaining funds to destination wallet", internalOrder); return(false); } } return(true); }
public async Task UpdateAsync(InternalOrder internalOrder) { AzureIndex index = await _indicesStorage.GetDataAsync(GetIndexPartitionKey(internalOrder.Id), GetIndexRowKey(internalOrder.Id)); if (index == null) { throw new EntityNotFoundException(); } InternalOrderEntity entity = await _storage.GetDataAsync(index); Mapper.Map(internalOrder, entity); await _storage.InsertOrReplaceAsync(entity); }
/// <summary> /// Richard Carroll /// Created: 2019/01/30 /// /// This Method inserts Order Data into the database /// and returns the result to the /// Logic Layer. /// </summary> public int InsertItemOrder(InternalOrder internalOrder, List <VMInternalOrderLine> lines) { int rowsAffected = 0; var cmdText1 = "sp_insert_internal_order"; var cmdText2 = "sp_insert_internal_order_line"; try { using (TransactionScope scope = new TransactionScope()) { using (var conn = DBConnection.GetDbConnection()) { conn.Open(); var cmd1 = new SqlCommand(cmdText1, conn); cmd1.CommandType = CommandType.StoredProcedure; cmd1.Parameters.AddWithValue("@EmployeeID", internalOrder.EmployeeID); cmd1.Parameters.AddWithValue("@DepartmentID", internalOrder.DepartmentID); cmd1.Parameters.AddWithValue("@Description", internalOrder.Description); cmd1.Parameters.AddWithValue("@OrderComplete", internalOrder.OrderComplete); cmd1.Parameters.AddWithValue("@DateOrdered", internalOrder.DateOrdered); var temp = cmd1.ExecuteScalar(); int internalOrderID = Convert.ToInt32(temp); foreach (var line in lines) { var cmd2 = new SqlCommand(cmdText2, conn); cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.AddWithValue("@ItemID", line.ItemID); cmd2.Parameters.AddWithValue("@InternalOrderID", internalOrderID); cmd2.Parameters.AddWithValue("@OrderQty", line.OrderQty); cmd2.Parameters.AddWithValue("@QtyReceived", line.QtyReceived); rowsAffected += cmd2.ExecuteNonQuery(); } } scope.Complete(); } } catch (Exception) { throw; } return(rowsAffected); }
/// <summary> /// Load the list of pending work orders. /// </summary> private void LoadOrders() { try { InternalOrder.ReadInternalOrder(); this.dgvInternalOrder.DataSource = null; this.dgvInternalOrder.DataSource = CoreSystem.InternalOrders; this.lblErrorList.Visible = false; } catch (Exception ex) { this.btnAceptOrder.Enabled = false; this.lblErrorList.Visible = true; this.lblErrorList.Text = "There are no work orders to carry out."; InternalOrder.SaveErrorLogOrder(ex.Message); } }
public static async void RemoveOrderTimeFromInternalOrder() { // create internal order InternalOrder internalOrder; using (var dbContext = new EfTestDbContext()) { var repo = new InternalOrderRepository(dbContext); var seq = await repo.NextOrderNumber(); internalOrder = new InternalOrder("W-{seq}"); internalOrder.SetTime(new OrderTime("Test")); await repo.Update(internalOrder); await repo.SaveAsync(); Debug.Assert(internalOrder.ID != Guid.Empty); Debug.Assert(null != internalOrder.OrderTimeID); } // remove order time Guid previousOrderTimeId; using (var dbContext = new EfTestDbContext()) { var repo = new InternalOrderRepository(dbContext); var order = repo.Get(internalOrder.ID); previousOrderTimeId = order.OrderTime.ID; order.RemoveTime(); Console.WriteLine($"Previous order time id {previousOrderTimeId}"); await repo.Update(order); await repo.SaveAsync(); } // check if OrderTime was deleted using (var dbContext = new EfTestDbContext()) { var order = dbContext.InternalOrders .Include(x => x.OrderTime) .Single(x => x.ID == internalOrder.ID); Debug.Assert(false == dbContext.OrderTimes.Any(x => x.ID == previousOrderTimeId), "OrderTime is still present"); } }
private async Task <bool> ExecuteAsync(InternalOrder internalOrder) { ExternalTrade externalTrade = null; string error = null; try { externalTrade = await _externalExchangeService.ExecuteLimitOrderAsync(internalOrder.AssetPairId, internalOrder.Volume, internalOrder.Price, internalOrder.Type); } catch (NotEnoughLiquidityException) { error = Errors.NotEnoughLiquidity; } catch (Exception) { error = "An unexpected error occurred while executing order"; } if (!string.IsNullOrEmpty(error)) { internalOrder.Status = InternalOrderStatus.Failed; internalOrder.RejectReason = error; await _internalOrderRepository.UpdateAsync(internalOrder); return(false); } // ReSharper disable once PossibleNullReferenceException internalOrder.ExecutedPrice = externalTrade.Price; internalOrder.ExecutedVolume = externalTrade.Volume; internalOrder.TradeId = externalTrade.Id; internalOrder.Status = InternalOrderStatus.Executed; await _internalOrderRepository.UpdateAsync(internalOrder); await _positionService.CloseAsync(internalOrder, externalTrade); return(true); }
public void AddItemOrderTestInValidDepartmentLength() { internalOrder = new InternalOrder() { InternalOrderID = 8000, EmployeeID = 100000, DepartmentID = createString(51), Description = "Food Order... maybe", OrderComplete = false, DateOrdered = DateTime.Now }; _internalOrderLine = new VMInternalOrderLine() { ItemID = 100000, OrderQty = 100, QtyReceived = 100 }; lines = new List <VMInternalOrderLine>(); lines.Add(_internalOrderLine); _internalOrderManager.CreateInternalOrder(internalOrder, lines); }
public async Task <CancelLimitOrderResponse> CancelLimitOrderAsync([FromBody] CancelLimitOrderRequest request) { InternalOrder internalOrder = await _internalOrderService.GetByIdAsync(request.OrderId); if (internalOrder == null) { throw new ValidationApiException(HttpStatusCode.NotFound, "Order not found"); } if (internalOrder.Status != InternalOrderStatus.Cancelled && internalOrder.Status != InternalOrderStatus.Rejected && internalOrder.Status != InternalOrderStatus.Completed) { throw new ValidationApiException(HttpStatusCode.BadRequest, "Can not cancel order"); } return(new CancelLimitOrderResponse { OrderId = request.OrderId }); }
public void AddItemOrderTestInValidDescriptionBlank() { internalOrder = new InternalOrder() { InternalOrderID = 8000, EmployeeID = 100000, DepartmentID = "Events", Description = "", OrderComplete = false, DateOrdered = DateTime.Now }; _internalOrderLine = new VMInternalOrderLine() { ItemID = 100000, OrderQty = 100, QtyReceived = 100 }; lines = new List <VMInternalOrderLine>(); lines.Add(_internalOrderLine); _internalOrderManager.CreateInternalOrder(internalOrder, lines); }
private async Task ReleaseReservedFundsAsync(InternalOrder internalOrder) { Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); string assetId; decimal amount; if (internalOrder.Type == LimitOrderType.Sell) { assetId = assetPair.BaseAssetId; amount = internalOrder.Volume; } else { Asset asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); assetId = assetPair.QuotingAssetId; amount = (internalOrder.Volume * internalOrder.Price).TruncateDecimalPlaces(asset.Accuracy, true); } _log.InfoWithDetails("Releasing reserved funds for internal trade", new { OrderId = internalOrder.Id, Asset = assetId, Amount = amount }); string walletId = await _settingsService.GetWalletIdAsync(); try { await _lykkeExchangeService.TransferAsync(walletId, internalOrder.WalletId, assetId, amount); } catch (Exception exception) { _log.ErrorWithDetails(exception, "Can not transfer back reserved funds", internalOrder); } internalOrder.Status = InternalOrderStatus.Cancelled; await _internalOrderRepository.UpdateAsync(internalOrder); }
public async Task CloseAsync(InternalOrder internalOrder, ExternalTrade externalTrade) { await _tradeService.RegisterAsync(externalTrade); Position position = Position.Create(internalOrder, externalTrade); await _positionRepository.InsertAsync(position); try { await _positionRepositoryPostgres.InsertAsync(position); } catch (Exception exception) { _log.ErrorWithDetails(exception, "An error occurred while updating position in the postgres DB", position); } await _summaryReportService.RegisterClosePositionAsync(position); _log.InfoWithDetails("Position closed", position); }
public int InsertItemOrder(InternalOrder internalOrder, List <VMInternalOrderLine> lines) { int count = 0; _orders.Add(new VMInternalOrder() { InternalOrderID = internalOrder.InternalOrderID, EmployeeID = internalOrder.EmployeeID, DepartmentID = internalOrder.DepartmentID, Description = internalOrder.Description, OrderComplete = internalOrder.OrderComplete, DateOrdered = internalOrder.DateOrdered }); foreach (var line in lines) { count++; line.InternalOrderId = internalOrder.InternalOrderID; _lines.Add(line); } return(count); }
public static void Run() { var orderHandler = new OrderHandler(); var onlineOrder = new OnlineOrder { ItemId = "XP-23", Amount = 42, EmailAddress = "*****@*****.**", PricePerItem = 12.4m }; orderHandler.HandleOnlineOrder(onlineOrder); var internalOrder = new InternalOrder { ItemId = "IW-41", Amount = 2, DepartmentId = "LAB-01" }; orderHandler.HandleInternalOrder(internalOrder); }
private async Task <bool> ValidateBalanceAsync(InternalOrder internalOrder) { Instrument instrument = await _instrumentService.TryGetByAssetPairIdAsync(internalOrder.AssetPairId); AssetPair assetPair = await _assetsServiceWithCache.TryGetAssetPairAsync(instrument.AssetPairId); Asset asset; decimal amount; if (internalOrder.Type == LimitOrderType.Sell) { asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.QuotingAssetId); amount = (internalOrder.Volume * internalOrder.Price).TruncateDecimalPlaces(asset.Accuracy, true); } else { asset = await _assetsServiceWithCache.TryGetAssetAsync(assetPair.BaseAssetId); amount = internalOrder.Volume; } Balance balance = await _balanceService.GetByAssetIdAsync(ExchangeNames.Lykke, asset.Id); if (balance.Amount < amount) { internalOrder.Status = InternalOrderStatus.Rejected; internalOrder.RejectReason = Errors.NotEnoughLiquidity; await _internalOrderRepository.UpdateAsync(internalOrder); return(false); } return(true); }
public async Task <InternalOrderModel> GetByIdAsync(string internalOrderId) { InternalOrder internalOrder = await _internalOrderService.GetByIdAsync(internalOrderId); return(Mapper.Map <InternalOrderModel>(internalOrder)); }
private async Task CompleteAsync(InternalOrder internalOrder) { internalOrder.Status = InternalOrderStatus.Completed; await _internalOrderRepository.UpdateAsync(internalOrder); }
/// <summary> /// Creates or updates an existing internal order /// </summary> /// <param name="order">The updated order to be saved</param> /// <param name="orderConflictHandler">Handler for getting order conflict notifications. First parameter is original order, second parameter is the new order</param> public async Task Update(InternalOrder order, Action <InternalOrder, InternalOrder> orderConflictHandler = null) { // detach if already attached var entry = _context.Entry(order); if (entry.State != EntityState.Detached) { entry.State = EntityState.Detached; } // check if another entity is attached var existingTrackedEntities = _context.ChangeTracker.Entries <InternalOrder>().Where(x => x.Entity.ID == order.ID).ToList(); foreach (var e in existingTrackedEntities) { e.State = EntityState.Detached; } // find original order var originalOrder = await _context.InternalOrders .AsNoTracking() .Include(io => io.OrderTime) .SingleOrDefaultAsync(x => x.ID == order.ID); if (originalOrder == null) { // only order is in the added state _context.Attach(order); _context.Entry(order).State = EntityState.Added; if (order.OrderTime != null) { _context.Entry(order.OrderTime).State = EntityState.Added; } return; } _context.Attach(order); _context.Entry(order).State = EntityState.Modified; if (originalOrder.OrderTime != null) { // remove & add or update if (order.OrderTime == null) { var trackedOrderTime = _context.ChangeTracker.Entries <OrderTime>().Where(x => x.Entity.ID == originalOrder.OrderTimeID).SingleOrDefault(); if (trackedOrderTime != null) { trackedOrderTime.State = EntityState.Deleted; } else { _context.Remove(originalOrder.OrderTime); } } else { // new or updated OrderTime if (order.OrderTime.ID == originalOrder.OrderTime.ID) { // modify _context.Entry(order.OrderTime).State = EntityState.Modified; } else { var trackedOrderTime = _context.ChangeTracker.Entries <OrderTime>().Where(x => x.Entity.ID == originalOrder.OrderTimeID).SingleOrDefault(); if (trackedOrderTime != null) { trackedOrderTime.State = EntityState.Deleted; } else { _context.Remove(originalOrder.OrderTime); } _context.Entry(order.OrderTime).State = EntityState.Added; } } } }