private async Task CheckStrategy(StrategyDetails strategy) { await Task.Run(() => { try { decimal?tradeFinValue = 0; decimal quote = GetCurrentPrice(strategy.Ticker); if ((strategy.Instruction == BuySell.Buy && quote <= strategy.TargetPrice) || (strategy.Instruction == BuySell.Sell && quote >= strategy.TargetPrice)) { tradeFinValue = ExecuteStrategy(strategy); this.DeleteStrategy(strategy.Id); #if DEBUG _logger.LogInformation(string.Format("### STRATEGY {0} EXECUTED ###: {1} {2} SHARES OF {3} AT {4} USD EACH. FINANCIAL VALUE: {5} USD", strategy.Id, strategy.Instruction == BuySell.Buy ? "BUY" : "SELL", strategy.Quantity, strategy.Ticker, quote, tradeFinValue.Value)); #endif } else { #if DEBUG _logger.LogInformation(string.Format("### STRATEGY {0} CHECKED ###: {1} - {2} - TARGET PRICE:{3} USD - CURRENT PRICE:{4} USD ", strategy.Id, strategy.Instruction == BuySell.Buy ? "BUY" : "SELL", strategy.Ticker, strategy.TargetPrice, quote)); #endif } } catch (Exception ex) { _logger.LogError(ex.Message); } }); }
private decimal ExecuteStrategy(StrategyDetails strategy) { decimal finValue = 0; int count = 0; string errMsg = string.Empty; while (count < Retries) { try { finValue = strategy.Instruction == BuySell.Buy ? CurrentReutbergService.Buy(strategy.Ticker, strategy.Quantity) : CurrentReutbergService.Sell(strategy.Ticker, strategy.Quantity); break; } catch (Exception ex) { count++; errMsg = ex.Message; } } if (!string.IsNullOrEmpty(errMsg)) { throw new Exception(string.Format("[BUY / SELL ID:{0}] REUTBERG OUTPUT ERROR: {1}", strategy.Id, errMsg)); } return(finValue); }
public void DeleteStrategy(string Id) { lock (_context) { StrategyDetails strategy = _context.Strategies.Find(Id); if (strategy == null) { throw new Exception("STRATEGY NOT FOUND!"); } _context.Remove(strategy); _context.SaveChanges(); #if DEBUG _logger.LogInformation($"REMOVING STRATEGY {Id}."); #endif } }
public void AddStrategy(StrategyDetailsDto entity) { var strategyDet = _mapper.Map <StrategyDetails>(entity); // Setting a new ID strategyDet.Id = Guid.NewGuid().ToString().Substring(0, 8).ToUpper(); strategyDet.Ticker = strategyDet.Ticker.ToUpper(); if (strategyDet == null || !IsValidQuantity(strategyDet.Quantity) || !IsValidTicker(strategyDet.Ticker) || !IsValidPriceMovement(strategyDet)) { throw new Exception("INVALID STRATEGY!"); } StrategyDetails strategy = _context.Strategies.Find(strategyDet.Id); if (strategy != null) { throw new Exception("STRATEGY ID ALREADY EXISTS!"); } decimal fullPercentage = 100; strategyDet.StartPrice = GetCurrentPrice(strategyDet.Ticker); strategyDet.TargetPrice = Math.Round(strategyDet.Instruction == BuySell.Buy ? strategyDet.StartPrice * (1 - (strategyDet.PriceMovement / fullPercentage)) : strategyDet.StartPrice * (1 + (strategyDet.PriceMovement / fullPercentage)), 2); lock (_context) { _context.Add(strategyDet); _context.SaveChanges(); #if DEBUG _logger.LogInformation(string.Format("ADDING NEW STRATEGY {0}: {1} {2} SHARES OF {3} AT PRICE {4} USD (CURRENT PRICE: {5} USD)", strategyDet.Id, strategyDet.Instruction == BuySell.Buy ? "BUY" : "SELL", strategyDet.Quantity, strategyDet.Ticker, strategyDet.TargetPrice, strategyDet.StartPrice)); #endif } }
/// <summary> /// Validates Price Movement /// Buy order: the price can drop from 0% to 100% exclusice in both cases /// Sell order: the price can goes up from 0% exclusive to infinity /// </summary> /// <param name="entity"></param> /// <returns></returns> private bool IsValidPriceMovement(StrategyDetails entity) { // Buy order: the price can drop from 0% to 100% exclusice in both cases // Sell order: the price can goes up from 0% exclusive to infinity return(entity.Instruction == BuySell.Buy ? (entity.PriceMovement > 0 && entity.PriceMovement < 100) : entity.PriceMovement > 0); }