/// <summary> /// Creates a new trade in our system and opens a buy order. /// </summary> /// <param name="freeTrader"></param> /// <param name="trade"></param> /// <returns></returns> private async Task CreateNewTrade(Trader freeTrader, string trade) { // Get our Bitcoin balance from the exchange var currentBtcBalance = await _api.GetBalance("BTC"); // Do we even have enough funds to invest? if (currentBtcBalance.Available < freeTrader.CurrentBalance) { throw new Exception("Insufficient BTC funds to perform a trade."); } var order = await CreateBuyOrder(freeTrader, trade); // We found a trade and have set it all up! if (order != null) { // Send a notification that we found something suitable _log($"New trade signal {order.Market}..."); // Update the trader to busy freeTrader.LastUpdated = DateTime.UtcNow; freeTrader.IsBusy = true; _traderBatch.Add(TableOperation.Replace(freeTrader)); // Create the trade record as well _orderBatch.Add(TableOperation.Insert(order)); } }
/// <summary> /// Creates a new trade in our system and opens a buy order. /// </summary> /// <returns></returns> private async Task CreateNewTrade(Trader freeTrader, TradeSignal signal) { // Get our Bitcoin balance from the exchange var currentBtcBalance = await _api.GetBalance(signal.QuoteCurrency); // Do we even have enough funds to invest? if (currentBtcBalance.Available < freeTrader.CurrentBalance) { _logger.LogWarning("Insufficient funds ({Available}) to perform a {MarketName} trade. Skipping this trade.", currentBtcBalance.Available, signal.MarketName); return; } var order = await CreateBuyOrder(freeTrader, signal.MarketName, signal.SignalCandle); // We found a trade and have set it all up! if (order != null) { // Save the order. await _dataStore.SaveTradeAsync(order); // Send a notification that we found something suitable _logger.LogInformation("New trade signal {Market}...", order.Market); // Update the trader to busy freeTrader.LastUpdated = DateTime.UtcNow; freeTrader.IsBusy = true; // Save the new trader state. await _dataStore.SaveTraderAsync(freeTrader); } }
/// <summary> /// Checks the implemented trading indicator(s), /// if one pair triggers the buy signal a new trade record gets created. /// </summary> /// <param name="trades"></param> /// <param name="amountOfBtcToInvestPerTrader"></param> /// <returns></returns> private async Task <Trade> FindTrade(List <Trade> trades, double amountOfBtcToInvestPerTrader) { // Get our Bitcoin balance from the exchange var currentBtcBalance = await _api.GetBalance("BTC"); // Do we even have enough funds to invest? if (currentBtcBalance < Constants.AmountOfBtcToInvestPerTrader) { throw new Exception("Insufficient BTC funds to perform a trade."); } // Retrieve our current markets var markets = await _api.GetMarketSummaries(); // Check if there are markets matching our volume. markets = markets.Where(x => (x.BaseVolume > Constants.MinimumAmountOfVolume || Constants.AlwaysTradeList.Contains(x.MarketName)) && x.MarketName.StartsWith("BTC-")).ToList(); // Remove existing trades from the list to check. foreach (var trade in trades) { markets.RemoveAll(x => x.MarketName == trade.Market); } // Remove items that are on our blacklist. foreach (var market in Constants.MarketBlackList) { markets.RemoveAll(x => x.MarketName == market); } // Check the buy signal! string pair = null; // Prioritize markets with high volume. foreach (var market in markets.Distinct().OrderByDescending(x => x.BaseVolume).ToList()) { if (await GetBuySignal(market.MarketName)) { // A match was made, buy that please! pair = market.MarketName; break; } } // No pairs found. Return. if (pair == null) { return(null); } var openRate = GetTargetBid(await _api.GetTicker(pair)); var amount = amountOfBtcToInvestPerTrader / openRate; var amountYouGet = (amountOfBtcToInvestPerTrader * (1 - Constants.TransactionFeePercentage)) / openRate; var orderId = await _api.Buy(pair, openRate, amount); return(new Trade() { Market = pair, StakeAmount = Constants.AmountOfBtcToInvestPerTrader, OpenRate = openRate, OpenDate = DateTime.UtcNow, Quantity = amountYouGet, OpenOrderId = orderId, BuyOrderId = orderId, IsOpen = true, StrategyUsed = _strategy.Name, PartitionKey = "TRADE", SellType = SellType.None, RowKey = $"MNT{(DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks):d19}" }); }