private static void MessageEventDispatcher(BinanceAggregateTradeData data) { if (!MonitoredSymbols.TryGetValue(data.Symbol, out var monitoredSymbolsProcessors)) { return; } foreach (var orderProcessor in monitoredSymbolsProcessors) { Task.Factory.StartNew(() => orderProcessor.MessageEventHandler(data)); } }
private void MessageEventHandler(BinanceAggregateTradeData data) { try { Console.WriteLine($"{nameof(this.MessageEventHandler)}: {DateTime.Now:O} {data.Symbol} {data.Price:N8}"); if (!this.ShouldReorder(data)) { return; } this.MoveUp(data).ConfigureAwait(false); } catch (Exception ex) { Console.WriteLine(ex); } }
public static AggregateTrade Map(BinanceAggregateTradeData data) { return(new AggregateTrade { AggregateTradeId = data.AggregateTradeId, EventTime = data.EventTime, EventType = data.EventType, FirstTradeId = data.FirstTradeId, LastTradeId = data.LastTradeId, Price = data.Price, Quantity = data.Quantity, Symbol = data.Symbol, TradeTime = data.TradeTime, WasBestPriceMatch = data.WasBestPriceMatch, WasBuyerMaker = data.WasBuyerMaker }); }
private bool ShouldReorder(BinanceAggregateTradeData data) { var orderStopPrice = this._orderResponse.StopPrice; var lastTradePrice = data.Price; if (lastTradePrice <= orderStopPrice) { // stop-loss is already over last trade price -> it should execute this.CheckOrder().ConfigureAwait(false); return(false); } // check if last trade price is over thresholds if (!this.OverThresholds(data)) { return(false); } return(true); }
private bool OverThresholds(BinanceAggregateTradeData data) { var orderStopPrice = this._orderResponse.StopPrice; var lastTradePrice = data.Price; if (Properties.Settings.Default.MoveUpStaticThreshold > 0 && lastTradePrice > orderStopPrice + Properties.Settings.Default.MoveUpStaticThreshold) { return(true); } if (Properties.Settings.Default.MoveUpPrcentageThreshold > 0 && lastTradePrice > orderStopPrice * (100 + Properties.Settings.Default.MoveUpPrcentageThreshold) / 100) { return(true); } // TODO: implement hysteresis return(false); }
private async Task MoveUp(BinanceAggregateTradeData data) { var newStopPrice = data.Price * (100 - Properties.Settings.Default.MoveUpPrecentageMarginUnderMarket) / 100; Console.WriteLine($"{nameof(this.MoveUp)}: {DateTime.Now:O} {data.Symbol} {data.Price:N8} -> {newStopPrice:N8}"); Console.WriteLine($"{nameof(this.MoveUp)}: {DateTime.Now:O} {data.Symbol} Canceling order '{this._orderResponse.OrderId}'..."); if (!Properties.Settings.Default.TestMode) { var cancelOrderResponse = await this._client.CancelOrder(new CancelOrderRequest { Symbol = this._orderResponse.Symbol, OrderId = this._orderResponse.OrderId, }, Properties.Settings.Default.ReceiveWindow); Console.WriteLine($"{nameof(this.MoveUp)}: {DateTime.Now:O} {data.Symbol} Order '{cancelOrderResponse.OrderId}' canceled"); } await this.RefreshOrderResponse(); Console.WriteLine($"{nameof(this.MoveUp)}: {DateTime.Now:O} {data.Symbol} Creating new order at {newStopPrice:N8}..."); if (!Properties.Settings.Default.TestMode) { var newOrderResponse = await this._client.CreateOrder(new CreateOrderRequest { Symbol = this._orderResponse.Symbol, NewOrderResponseType = NewOrderResponseType.Acknowledge, Quantity = this._orderResponse.OriginalQuantity - this._orderResponse.ExecutedQuantity, Side = OrderSide.Sell, StopPrice = newStopPrice, Type = OrderType.StopLoss, TimeInForce = TimeInForce.GTC }); Console.WriteLine($"{nameof(this.MoveUp)}: {DateTime.Now:O} {data.Symbol} Order '{newOrderResponse.OrderId}' created"); } }