/// <summary> /// Queries the persistence layer for open trades and /// handles them, otherwise a new trade is created. /// </summary> /// <returns></returns> public async Task Process() { // Get our current trades. var tradeTable = await ConnectionManager.GetTableConnection(Constants.OrderTableName, Constants.IsDryRunning); var balanceTable = await ConnectionManager.GetTableConnection(Constants.BalanceTableName, Constants.IsDryRunning); var activeTrades = tradeTable.CreateQuery <Trade>().Where(x => x.IsOpen).ToList(); // Create two batches that we can use to update our tables. var batch = new TableBatchOperation(); var balanceBatch = new TableBatchOperation(); // Can't use FirstOrDefault directly because Linq for Table Storage doesn't support it. _totalBalance = balanceTable.CreateQuery <Balance>().Where(x => x.RowKey == "TOTAL").FirstOrDefault(); _dayBalance = balanceTable.CreateQuery <Balance>() .Where(x => x.RowKey == DateTime.UtcNow.ToString("yyyyMMdd")) .FirstOrDefault(); // Create both the balances if they don't exist yet. CreateBalancesIfNotExists(balanceBatch); // Handle our active trades. foreach (var trade in activeTrades) { var orders = await _api.GetOpenOrders(trade.Market); if (orders.Any(x => x.OrderUuid.ToString() == trade.OpenOrderId)) { // There's already an open order for this trade. // This means we're still buying it. _log($"Already an open order for trade {trade.OpenOrderId}"); } else { trade.OpenOrderId = null; // No open order with the order ID of the trade. // Check if this trade can be closed if (!await CloseTradeIfFulfilled(trade)) { // Check if we can sell our current pair await HandleTrade(trade); } batch.Add(TableOperation.Replace(trade)); } } // If we have less active trades than we can handle, find a new one. while (activeTrades.Count < Constants.MaxNumberOfConcurrentTrades) { var trade = await StartTrade(activeTrades, batch); if (trade != null) { // Add this to activeTrades so we don't trigger the same. activeTrades.Add(trade); batch.Add(TableOperation.Insert(trade)); } else { // No more trade to be found, kill it. break; } } _log($"Currently handling {activeTrades.Count} trades."); // If these actually changed make a roundtrip to the server to set them. if (_dayBalanceExists && _oldDayBalance != _dayBalance.Profit) { balanceBatch.Add(TableOperation.Replace(_dayBalance)); } if (_totalBalanceExists && _oldTotalBalance != _totalBalance.Profit) { balanceBatch.Add(TableOperation.Replace(_totalBalance)); } if (batch.Count > 0) { tradeTable.ExecuteBatch(batch); } if (balanceBatch.Count > 0) { balanceTable.ExecuteBatch(balanceBatch); } }