public async Task <IActionResult> LimitOrder(TradeViewModel model) { // if tripwire tripped cancel if (!_tripwire.TradingEnabled()) { _logger.LogError("Tripwire tripped, exiting LimitOrder()"); this.FlashError($"Trading not enabled"); return(RedirectToAction("Trade", new { market = model.Market })); } (var success, var error) = Utils.ValidateOrderParams(_settings, model.Order, model.Order.Price); if (!success) { this.FlashError(error); return(RedirectToAction("Trade", new { market = model.Market, side = model.Order.Side, amount = model.Order.Amount, price = model.Order.Price })); } var user = await GetUser(required : true); // lock process of performing trade lock (_userLocks.GetLock(user.Id)) { try { //TODO: move this to a ViaRpcProvider in /Services (like IWalletProvider) var via = new ViaJsonRpc(_settings.AccessHttpUrl); (var side, var error2) = Utils.GetOrderSide(model.Order.Side); if (error2 != null) { return(BadRequest(error2)); } var order = via.OrderLimitQuery(user.Exchange.Id, model.Market, side, model.Order.Amount, model.Order.Price, _settings.TakerFeeRate, _settings.MakerFeeRate, "viafront"); // send email: order created var amountUnit = _settings.Markets[model.Market].AmountUnit; var priceUnit = _settings.Markets[model.Market].PriceUnit; this.FlashSuccess($"Limit Order Created ({order.market} - {order.side}, Amount: {order.amount} {amountUnit}, Price: {order.price} {priceUnit})"); return(RedirectToAction("Trade", new { market = model.Market })); } catch (ViaJsonException ex) { if (ex.Err == ViaError.PUT_LIMIT__BALANCE_NOT_ENOUGH) { this.FlashError($"Limit Order Failed (balance too small)"); return(RedirectToAction("Trade", new { market = model.Market, side = model.Order.Side, amount = model.Order.Amount, price = model.Order.Price })); } throw; } } }
public void ProcessOrders() { // if tripwire tripped cancel if (!_tripwire.TradingEnabled() || !_tripwire.WithdrawalsEnabled()) { _logger.LogError("Tripwire tripped, exiting ProcessOrders()"); return; } // get lock - ensure that this function ends before it is started again lock (lockObj) { _logger.LogInformation("Process Orders - Broker"); var date = DateTimeOffset.Now.ToUnixTimeSeconds(); // process created orders var orders = _context.BrokerOrders.Where(o => o.Status == BrokerOrderStatus.Ready.ToString() || o.Status == BrokerOrderStatus.Incomming.ToString() || o.Status == BrokerOrderStatus.Confirmed.ToString() || o.Status == BrokerOrderStatus.PayoutWait.ToString()).ToList(); foreach (var order in orders) { if (_walletProvider.IsChain(order.AssetSend)) { ProcessOrderChain(order); } else { ProcessOrderFiat(order); } // we should save changes here because calls to the exchange backend could potentially throw exceptions // which this would leave the backend and frontend in conflicting state (if we save after the loop finishes) // I just eagerly load 'orders' using ToList() at the end of the linq statement to make sure that doesnt get invalidated or anything _context.SaveChanges(); } // expire orders var ordersToExpire = _context.BrokerOrders.Where(o => o.Status == BrokerOrderStatus.Created.ToString() || o.Status == BrokerOrderStatus.Ready.ToString()); foreach (var order in ordersToExpire) { if (date > order.Expiry + _apiSettings.Broker.TimeLimitGracePeriod) { order.Status = BrokerOrderStatus.Expired.ToString(); _context.BrokerOrders.Update(order); } } _context.SaveChanges(); } }