/// <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); } }
private void SetTradingSignal(string label, string currencyPair, TradeSignal LongOrShort) { if (!tradingSignal_dic.ContainsKey(label)) { this.tradingSignal_dic.Add(label, LongOrShort); } }
private void OnSignal(TradeSignal signal) { Execute.OnUIThread(() => { Signals.Add(new SignalVM(signal)); }); }
/// <summary> /// Check if stop loss percent has been reached /// Sell if so /// </summary> /// <returns>Boolean true if hit, false otherwise</returns> private bool StopLossCheck() { if (_tradeType == TradeType.SELL) { var candleStick = _trader.GetCandlesticks(_botSettings.tradingPair, Interval.OneM, 1); var stopPrice = _lastBuy - (_lastBuy * (decimal)(_botSettings.stopLoss / 100)); if (stopPrice >= candleStick[0].close && _lastBuy > 0.00000000M) { _trader.CancelOpenOrders(); candleStick = _trader.GetCandlesticks(_botSettings.tradingPair, Interval.OneM, 1); _trader.SellCrypto(candleStick[0].close, TradeType.STOPLOSS); var signal = new TradeSignal { lastBuy = _lastBuy, lastSell = _lastSell, pair = _symbol, price = candleStick[0].close, signal = SignalType.OrderBook, tradeType = TradeType.STOPLOSS, transactionDate = DateTime.UtcNow }; _fileRepo.LogSignal(signal); return(true); } } return(false); }
/// <summary> /// Get price and place a buy order /// </summary> /// <returns>Boolean when complete</returns> private bool BuyCryptoCheck() { var price = OrderBookBuyPrice(); price = _trader.OrderBookBuyCheck(price); if (price != 0.00000000M && ((!_botSettings.tradingCompetition && price <= _lastSell) || _botSettings.tradingCompetition)) { _trader.BuyCrypto(price, TradeType.BUY, false, false); _tradeType = TradeType.SELL; _lastBuy = price; var signal = new TradeSignal { lastBuy = _lastBuy, lastSell = _lastSell, pair = _symbol, price = price, signal = SignalType.OrderBook, tradeType = TradeType.ORDERBOOKBUY, transactionDate = DateTime.UtcNow }; _fileRepo.LogSignal(signal); } return(true); }
/// <summary> /// Get price and place a sell order /// </summary> /// <returns>Boolean when complete</returns> private bool SellCryptoCheck() { var price = OrderBookSellPrice(); price = _trader.OrderBookSellCheck(price); if ((price != 0.00000000M && //&& _lastBuy > 0.00000000M price >= _lastBuy) || _samePriceCheck >= _botSettings.samePriceLimit) { _trader.SellCrypto(price, TradeType.SELL, false); _tradeType = TradeType.BUY; _lastSell = price; var signal = new TradeSignal { lastBuy = _lastBuy, lastSell = _lastSell, pair = _symbol, price = price, signal = SignalType.OrderBook, tradeType = TradeType.ORDERBOOKSELL, transactionDate = DateTime.UtcNow }; _fileRepo.LogSignal(signal); } return(true); }
public SignalStat(TradeSignal s, int tf, int timeframes) { side = s.Side; enter = (float)s.Enter; time = s.Time; this.timeframes = timeframes; endTime = s.Time.AddMinutes(tf * timeframes); proCons = new ProsCons[timeframes]; }
public bool AddSignal(TradeSignal tradeSignal, string userLogin, string signalName, bool canRetry = false) { if (tradeSignal == null) { return(false); //TODO find out } var res = false; using (var aConnection = new SqlConnection(_connectionString)) { var cmd = new SqlCommand("INSERT INTO [dbo].[Signals] ([SignalID],[UserLogin],[SignalName],[Date])" + "VALUES(@signalID, @userLogin, @signalName, @date)", aConnection); cmd.Parameters.AddWithValue("signalID", tradeSignal.Id); cmd.Parameters.AddWithValue("userLogin", userLogin); cmd.Parameters.AddWithValue("signalName", signalName); cmd.Parameters.AddWithValue("date", tradeSignal.Time); SqlTransaction transaction = null; try { aConnection.Open(); transaction = aConnection.BeginTransaction(); cmd.Transaction = transaction; res = cmd.ExecuteNonQuery() > 0; transaction.Commit(); } catch (Exception e) { if (canRetry && e is SqlException) { var code = ((SqlException)e).Number; if (code == 1205 || code == -2) //deadlock or timeout { Logger.Error( $"Failed to add {tradeSignal.Instrument.Symbol} signal to DB (will retry): {e.Message}"); AddSignal(tradeSignal, userLogin, signalName); return(res); } } Logger.Error($"Failed to add {tradeSignal.Instrument.Symbol} order to DB", e); transaction?.Rollback(); } } return(res); }
public void Analyze_NegativeSellPrice() { var action = new TradeSignal { BuyPriceMax = 0.00005, BuyPriceMin = 0.00005, Currency = "TRST", SellPrice = new[] { 1, -0.000575, 3 }, Term = Term.Short, }; Assert.Throws <InvalidOperationException>(() => Analyzer.Analyze(action)); }
public void Enqueue(TradeSignal signal) { if (signal == null) { throw new ArgumentNullException("signal"); } if (!_market.IsSupported(signal.Currency)) { throw new InvalidOperationException($"Currency {signal.Currency} is not supported."); } _newSignals.Add(signal); }
public void Analyze_BigGain() { var action = new TradeSignal { BuyPriceMax = 0.00005, BuyPriceMin = 0.00005, Currency = "TRST", SellPrice = new[] { 0.000575 }, Term = Term.Short, }; var result = Analyzer.Analyze(action); Assert.AreEqual(10.5, result.PossibleGains, 10.5 - 10.49); Assert.AreEqual(double.NaN, result.RiskReward); Assert.AreEqual("TRST", result.Currency); }
public void Analyze_ManySellPrices() { var action = new TradeSignal { BuyPriceMax = 100, BuyPriceMin = 100, Currency = "BTC", SellPrice = new[] { 110.0, 120.0, 130.0, 140.0 }, Term = Term.Short, }; var result = Analyzer.Analyze(action); Assert.AreEqual(0.25, result.PossibleGains); Assert.AreEqual(double.NaN, result.RiskReward); Assert.AreEqual("BTC", result.Currency); }
public void Analyze_RangeOfBuyPrices() { var action = new TradeSignal { BuyPriceMax = 150, BuyPriceMin = 100, Currency = "TRST", SellPrice = new[] { 200.0 }, Term = Term.Short, }; var result = Analyzer.Analyze(action); Assert.AreEqual(1, result.PossibleGains); Assert.AreEqual(double.NaN, result.RiskReward); Assert.AreEqual("TRST", result.Currency); }
public void Analyze_SingleSellPrice() { var action = new TradeSignal { BuyPriceMax = 100, BuyPriceMin = 100, Currency = "ASDA", SellPrice = new[] { 115.0 }, Term = Term.Short, }; var result = Analyzer.Analyze(action); Assert.AreEqual(0.15, result.PossibleGains); Assert.AreEqual(double.NaN, result.RiskReward); Assert.AreEqual("ASDA", result.Currency); }
public SignalVM(TradeSignal signal) { if (signal != null) { Currency = signal.Currency; BuyPriceMin = (decimal)signal.BuyPriceMin; BuyPriceMax = (decimal)signal.BuyPriceMax; StopLoss = (decimal)(double.IsNaN(signal.StopLoss) ? 0 : signal.StopLoss); Term = signal.Term; if (signal.SellPrice != null) { SellPrice = signal.SellPrice.Select(x => (decimal)x).ToArray(); UpdatePotentialGain(); } } }
/// <summary> /// Write trade signal to file /// </summary> /// <param name="signal">TradeSignal to write</param> /// <returns>Boolean when complete</returns> public bool LogSignal(TradeSignal signal, bool noWrite = true) { if (!noWrite) { var json = JsonConvert.SerializeObject(signal); using (StreamWriter s = File.AppendText(signalPath)) { s.WriteLine(json + ","); json = null; return(true); } } return(true); }
public void Analyze_SingleSellPriceAndStopLoss() { var action = new TradeSignal { BuyPriceMax = 100, BuyPriceMin = 100, Currency = "ASDA", SellPrice = new[] { 140.0 }, StopLoss = 80, Term = Term.Short, }; var result = Analyzer.Analyze(action); Assert.AreEqual(0.4, result.PossibleGains); Assert.AreEqual(20.0 / 40.0, result.RiskReward); Assert.AreEqual("ASDA", result.Currency); }
/// <summary> /// Creates a new trade in our system and opens a buy order. /// </summary> /// <returns></returns> private async Task CreateNewTrade(TradeSignal signal, ITradingStrategy strategy) { decimal currentQuoteBalance = 9999; if (!Global.Configuration.TradeOptions.PaperTrade) { // Get our Bitcoin balance from the exchange var exchangeQuoteBalance = await Global.ExchangeApi.GetBalance(signal.QuoteCurrency); // Check trading mode currentQuoteBalance = exchangeQuoteBalance.Available; } // Do we even have enough funds to invest? (only for SetAside; if you choose Reinvest we push a %) if (Global.Configuration.TradeOptions.ProfitStrategy == ProfitType.SetAside && currentQuoteBalance < Global.Configuration.TradeOptions.AmountToInvestPerTrader) { Global.Logger.Warning("Insufficient funds ({Available}) to perform a {MarketName} trade. Skipping this trade.", currentQuoteBalance, signal.MarketName); return; } await CreateBuyOrder(signal, strategy); }
/// <summary> /// Creates a new trade in our system and opens a buy order. /// </summary> /// <returns></returns> private async Task CreateNewTrade(TradeSignal signal, ITradingStrategy strategy) { decimal currentQuoteBalance = 9999; if (!Global.Configuration.TradeOptions.PaperTrade) { // Get our Bitcoin balance from the exchange var exchangeQuoteBalance = await Global.ExchangeApi.GetBalance(signal.QuoteCurrency); // Check trading mode currentQuoteBalance = exchangeQuoteBalance.Available; } // Do we even have enough funds to invest? (only for SetAside; if you choose Reinvest we push a %) if (Global.Configuration.TradeOptions.ProfitStrategy == ProfitType.SetAside && currentQuoteBalance < Global.Configuration.TradeOptions.AmountToInvestPerTrader) { Global.Logger.Warning("Insufficient funds ({Available}) to perform a {MarketName} trade. Skipping this trade.", currentQuoteBalance, signal.MarketName); return; } var trade = await CreateBuyOrder(signal, strategy); // We found a trade and have set it all up! if (trade != null) { // Save the order. await Global.DataStore.SaveTradeAsync(trade); //money area unavailable from wallet immediately await Global.DataStore.SaveWalletTransactionAsync(new WalletTransaction() { Amount = -(trade.OpenRate *trade.Quantity), Date = trade.OpenDate }); // Send a notification that we found something suitable await SendNotification($"Saved a BUY ORDER for: {this.TradeToString(trade)}"); } }
protected MarketOrder ProcessSignal(TradeSignal signal) { if (signal == null) { throw new ArgumentNullException("signal"); } var analysis = Analyzer.Analyze(signal); var currentPrice = _market.GetCurrentPrice(signal.Currency); // 1. currentPrice < MinBuyPrice // 2. currentPrice = [MinBuyPrice, MaxBuyPrice] // 3. currentPrice > MaxBuyPrice // RiskReward at least 1:2 var moneyAtRisk = _market.TradeCapitalSize * 0.05; var coins = Math.Floor(moneyAtRisk / currentPrice); if (currentPrice >= signal.BuyPriceMin && currentPrice <= signal.BuyPriceMax) { var order = _market.PlaceOrder(currentPrice, coins); return(order); } return(null); }
/// <summary> /// Creates a buy order on the exchange. /// </summary> /// <param name="pair">The pair we're buying</param> /// <param name="signalCandle"></param> /// <param name="strategy"></param> /// <returns></returns> private async Task <Trade> CreateBuyOrder(TradeSignal signal, ITradingStrategy strategy) { var pair = signal.MarketName; var signalCandle = signal.SignalCandle; // Take the amount to invest per trader OR the current balance for this trader. var fichesToSpend = Global.Configuration.TradeOptions.AmountToInvestPerTrader; if (Global.Configuration.TradeOptions.ProfitStrategy == ProfitType.Reinvest) { var exchangeQuoteBalance = Global.ExchangeApi.GetBalance(signal.QuoteCurrency).Result.Available; fichesToSpend = exchangeQuoteBalance * Global.Configuration.TradeOptions.AmountToReinvestPercentage / 100; } // The amount here is an indication and will probably not be precisely what you get. var ticker = await Global.ExchangeApi.GetTicker(pair); var openRate = GetTargetBid(ticker, signalCandle); var amount = fichesToSpend / openRate; // Get the order ID, this is the most important because we need this to check // up on our trade. We update the data below later when the final data is present. var orderId = Global.Configuration.TradeOptions.PaperTrade ? GetOrderId() : await Global.ExchangeApi.Buy(pair, amount, openRate); if (orderId == null) { Global.Logger.Error($"Error to open a BUY Order for: {pair} {amount} {openRate}"); return(null); } var fullApi = await Global.ExchangeApi.GetFullApi(); var symbol = await Global.ExchangeApi.ExchangeCurrencyToGlobalCurrency(pair); var trade = new Trade() { Market = pair, StakeAmount = fichesToSpend, OpenRate = openRate, OpenDate = signalCandle.Timestamp, Quantity = amount, OpenOrderId = orderId, BuyOrderId = orderId, SellOrderId = null, IsOpen = true, IsBuying = true, IsSelling = false, StrategyUsed = strategy.Name, SellType = SellType.None, TickerLast = ticker, GlobalSymbol = symbol, Exchange = fullApi.Name, PaperTrade = Global.Configuration.TradeOptions.PaperTrade }; if (Global.Configuration.TradeOptions.PlaceFirstStopAtSignalCandleLow) { trade.StopLossRate = signalCandle.Low; Global.Logger.Information("Automatic stop set at signal candle low {Low}", signalCandle.Low.ToString("0.00000000")); } //Global.Logger.Information($"Opened a BUY Order for: {this.TradeToString(trade)}"); return(trade); }
void ISignalExecute.ExecuteSignal(TradeSignal input) { //throw new NotImplementedException(); }
bool ISignalExecute.ExecuteSignal2(TradeSignal input, out TradeSignal updated) { updated = input; return(true); }
public DbSignal(TradeSignal signal, string login, string shortName) { Signal = signal ?? throw new ArgumentNullException(nameof(signal)); Login = !string.IsNullOrEmpty(login) ? login : throw new ArgumentNullException(nameof(login)); ShortName = !string.IsNullOrEmpty(shortName) ? shortName : throw new ArgumentNullException(nameof(shortName)); }
public void TradeSignal(TradeSignal tradeSignal) => _generatedSignals.Add(tradeSignal);
private static decimal GetUnrealizedPL(TradeSignal lastOpeningTrade, decimal price, decimal currentPL) { return(lastOpeningTrade.Side == Side.Buy ? currentPL + price : currentPL - price); }