public async Task <TradingResult> ExecuteAsync(BitstampExchange bitstampExchange) { // get the latest ticker var latestTicker = bitstampExchange.TickerHistory24H.OrderByDescending(t => t.Timestamp).Take(1).First(); // if the latest ticker is older than 30s then return //if (latestTicker.Timestamp < DateTime.Now.AddSeconds(-30)) return new TradingResult { Timestamp = DateTime.Now, Message = "Warning: latest ticker is older then 30s" }; // don't buy bitcoins if there is already another sell order within range (+- 2%) var openSellOrdersDbInRange = new SqlRepository <Order>(new BitstampTraderEntities()).Where(o => o.SellTimestamp == null && o.BuyPrice > latestTicker.Last * 0.980M && o.BuyPrice < latestTicker.Last * 1.020M); if (openSellOrdersDbInRange.Count() != 0) { return(new TradingResult { BuyThreshold = Math.Round(latestTicker.Last * 0.985M, 2) + " - " + Math.Round(latestTicker.Last * 1.015M, 2) }); } // get the minimum and maximums from the last x days var minMaxAveragePeriodInDays = int.Parse(ConfigurationManager.AppSettings["MinMaxAveragePeriodInDays"]); var tickerTimestampMinus180Days = latestTicker.Timestamp.AddDays(-minMaxAveragePeriodInDays); var minMaxLogDb = new SqlRepository <MinMaxLog>(new BitstampTraderEntities()).Where(l => l.Day > tickerTimestampMinus180Days).ToList(); var min180DayDb = latestTicker.Last; var max180DayDb = latestTicker.Last; if (minMaxLogDb.Count > 0) { min180DayDb = minMaxLogDb.OrderBy(l => l.Minimum).First().Minimum; max180DayDb = minMaxLogDb.OrderByDescending(l => l.Maximum).First().Maximum; } var relativePercentage = TradeHelpers.CalculateRelativePercentage(min180DayDb, max180DayDb, latestTicker.Last); var maxUsdAmountToBuy = TradeHelpers.CalculateMaxUsdAmountToBuy(bitstampExchange.AccountBalance); var btcAmountToBuy = TradeHelpers.CalculateBtcAmountToBuy(maxUsdAmountToBuy, 5M, relativePercentage, latestTicker); // buy bitcoins await bitstampExchange.BuyLimitOrderAsync(BitstampExchange.BitstampTickerCode.BtcUsd, Math.Round(btcAmountToBuy, 8), Math.Round(latestTicker.Last, 2)); return(new TradingResult { BuyThreshold = Math.Round(latestTicker.Last * 0.985M, 2) + " - " + Math.Round(latestTicker.Last * 1.015M, 2) }); }
public async Task <TradingResult> ExecuteAsync(BitstampExchange bitstampExchange) { // get the latest ticker var latestTicker = bitstampExchange.TickerHistory24H.OrderByDescending(t => t.Timestamp).Take(1).First(); // if the latest ticker is older than 30s then return if (latestTicker.Timestamp < DateTime.Now.AddSeconds(-30)) { return new TradingResult { Timestamp = DateTime.Now, Message = "Warning: latest ticker is older then 30s" } } ; // calculate the ticker average of the last x minutes (x = _averagePeriodInMinutes) var tickerOfLastXMinutes = bitstampExchange.TickerHistory24H.Where(t => t.Timestamp > DateTime.Now.AddMinutes(-_averagePeriodInMinutes)); var tickerAverage = tickerOfLastXMinutes.Average(t => t.Last); // todo: had to declare these variables outside the if statement, otherwise null execption on linq queries. Not sure why exactly decimal sellPrice; DateTime tickerTimestampMinus180Days; // is the current price lower than the average minus x percent? if (latestTicker.Last < tickerAverage * (1 - _averageBuyThresholdInPercents / 100)) { // don't buy bitcoins if there was already a buy order in the last x minutes if (bitstampExchange.LastBuyTimestamp > DateTime.Now.AddMinutes(-_pauseAfterBuyInMinutes)) { return new TradingResult { Timestamp = DateTime.Now, Message = "Bitcoins not bought, last buy was from " + bitstampExchange.LastBuyTimestamp } } ; // don't buy bitcoins if there is already another sell order within range (+- 5%) var sellOrderRangeInPercents = decimal.Parse(ConfigurationManager.AppSettings["SellOrderRangeInPercents"]); sellPrice = latestTicker.Last * (1 + sellOrderRangeInPercents / 100); var sellOrderExist = bitstampExchange.OpenOrders.Any(o => o.Type == BitstampOrderType.Sell && o.Price > sellPrice * 0.95M && o.Price < sellPrice * 1.05M); if (sellOrderExist) { return(new TradingResult { Timestamp = DateTime.Now, Message = "Bitcoins not bought, already an order in sell range" }); } // get the minimum and maximums from the last x days var minMaxAveragePeriodInDays = int.Parse(ConfigurationManager.AppSettings["MinMaxAveragePeriodInDays"]); tickerTimestampMinus180Days = latestTicker.Timestamp.AddDays(-minMaxAveragePeriodInDays); var minMaxLogDb = new SqlRepository <MinMaxLog>(new BitstampTraderEntities()).Where(l => l.Day > tickerTimestampMinus180Days).ToList(); var min180DayDb = latestTicker.Last; var max180DayDb = latestTicker.Last; if (minMaxLogDb.Count > 0) { min180DayDb = minMaxLogDb.OrderBy(l => l.Minimum).First().Minimum; max180DayDb = minMaxLogDb.OrderByDescending(l => l.Maximum).First().Maximum; } //calculate amount to buy var relativePercentage = TradeHelpers.CalculateRelativePercentage(min180DayDb, max180DayDb, latestTicker.Last); var maxUsdAmountToBuy = TradeHelpers.CalculateMaxUsdAmountToBuy(bitstampExchange.AccountBalance); var btcAmountToBuy = TradeHelpers.CalculateBtcAmountToBuy(maxUsdAmountToBuy, 5M, relativePercentage, latestTicker); // buy bitcoins await bitstampExchange.BuyLimitOrderAsync(BitstampExchange.BitstampTickerCode.BtcUsd, Math.Round(btcAmountToBuy, 8), Math.Round(latestTicker.Last, 2)); } return(new TradingResult { BuyThreshold = (tickerAverage * (1 - _averageBuyThresholdInPercents / 100)).ToString(CultureInfo.InvariantCulture) }); } } }