Example #1
0
        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;
                }
            }
        }
Example #2
0
        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();
            }
        }