public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var newOrderSingle = new NewOrderSingle { HandlInst = new HandlInst(HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE), Symbol = _modelConverter.ConvertLykkeSymbol(signal.Instrument.Name), Side = _modelConverter.ConvertSide(signal.TradeType), OrderQty = new OrderQty(signal.Volume), OrdType = _modelConverter.ConverOrderType(signal.OrderType), TimeInForce = new TimeInForce(TimeInForce.IMMEDIATE_OR_CANCEL), TransactTime = new TransactTime(DateTime.UtcNow), Price = new Price(signal.Price ?? 0m) }; var cts = new CancellationTokenSource(timeout); var report = await _connector.AddOrderAsync(newOrderSingle, cts.Token); var trade = _modelConverter.ConvertExecutionReport(report); try { var handlerTrade = _modelConverter.ConvertExecutionReport(report); handlerTrade.ExecType = ExecType.Trade; await _executionHandler.Handle(handlerTrade); } catch (Exception ex) { await _log.WriteErrorAsync(nameof(AddOrderAndWaitExecution), "Posting order to Jfd", ex); } return(trade); }
/// <summary> /// Adds the signal. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">The name.</param> /// <param name="action">The action.</param> /// <param name="trigger">The trigger.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">Universe trigger is empty for adding a trading event</exception> public TradingSignal AddSignal <T>(string name, Func <Security, bool> action, Dictionary <Security, T> trigger) where T : IndicatorBase <IndicatorDataPoint> { if (trigger.Count == 0) { throw new ArgumentNullException("Universe trigger is empty for adding a trading event"); } //Get first item var foundtrigger = trigger.Values.First(); //Create trading event TradingSignal nevent = new TradingSignal(Universe, name, action); foundtrigger.Updated += (sender, updated) => { if (IsRunning) { nevent.Execute(); } }; nevent.SignalFired += OnSignal; Signals[nevent.Name] = nevent; return(nevent); }
/// <summary> /// Adds the signal. /// </summary> /// <param name="name">The name.</param> /// <param name="action">The action.</param> /// <returns></returns> public TradingSignal AddSignal(string name, Func <Security, bool> action) { TradingSignal nevent = new TradingSignal(Universe, name, action); Signals[nevent.Name] = nevent; return(nevent); }
public override async Task <ExecutionReport> CancelOrderAndWaitExecution( TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { if (!Guid.TryParse(signal.OrderId, out var id)) { throw new ApiException("GDAX order id can be only Guid"); } var cts = CreateCancellationTokenSource(timeout); try { var response = await _restApi.CancelOrder(id, cts.Token, (sender, httpRequest) => OnSentHttpRequest(httpRequest, translatedSignal), (sender, httpResponse) => OnReceivedHttpRequest(httpResponse, translatedSignal)); if (!response) { return(null); } return(null); // TODO: Here we should just return boolean result } catch (StatusCodeException ex) { throw new ApiException(ex.Message); } }
public void SetSignal(TradingSignal signal) { TextView id = FindViewById <TextView>(Resource.Id.tv_ID_Value); id.Text = signal.Id.ToString(); TextView actualTime = FindViewById <TextView>(Resource.Id.tv_Act_Time_Value); actualTime.Text = signal.ActualTime; TextView comment = FindViewById <TextView>(Resource.Id.tv_comment_Value); comment.Text = signal.Comment; TextView pair = FindViewById <TextView>(Resource.Id.tv_pair_Value); pair.Text = signal.Pair; TextView cmd = FindViewById <TextView>(Resource.Id.tv_cmd_Value); cmd.Text = signal.Cmd.ToString(); TextView system = FindViewById <TextView>(Resource.Id.tv_trading_System_Value); system.Text = signal.TradingSystem.ToString(); TextView period = FindViewById <TextView>(Resource.Id.tv_period_Value); period.Text = signal.Period; TextView price = FindViewById <TextView>(Resource.Id.tv_price_Value); price.Text = Math.Round(signal.Price, 5).ToString(); TextView sl = FindViewById <TextView>(Resource.Id.tv_sl_Value); sl.Text = Math.Round(signal.Sl, 5).ToString(); TextView tp = FindViewById <TextView>(Resource.Id.tv_tp_Value); tp.Text = Math.Round(signal.Tp, 5).ToString(); }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var cts = new CancellationTokenSource(timeout); var request = _converter.CreateNewOrderSingle(signal); var response = await _tradeSessionConnector.AddOrderAsync(request, cts.Token); return(_converter.ConvertExecutionReport(response)); }
public AddStandardOrderRequest(TradingSignal tradingSignal, IReadOnlyCollection <CurrencySymbol> currencySymbols) { Pair = currencySymbols.Single(x => x.LykkeSymbol == tradingSignal.Instrument.Name).ExchangeSymbol; Type = tradingSignal.TradeType; OrderType = tradingSignal.OrderType; Price = tradingSignal.Price ?? 0; Volume = tradingSignal.Volume; }
/// <summary> /// Called when a trading signal is activated. /// </summary> /// <param name="signal">The signal.</param> /// <param name="securities">The securities.</param> public override void OnSignal(TradingSignal signal, Security[] securities) { //Check signals if (signal == CrossedOver) { EnterLong(securities); } else if (signal == CrossedBelow) { EnterShort(securities); } }
public void TradingSignal_IsTimeInThreshold() { var signal = new TradingSignal(null, "", OrderCommand.Create, TradeType.Buy, 100m, 100m, DateTime.UtcNow.AddMinutes(-5)); Assert.True(signal.IsTimeInThreshold(TimeSpan.FromMinutes(6))); Assert.False(signal.IsTimeInThreshold(TimeSpan.FromMinutes(4))); var signalInFuture = new TradingSignal(null, "", OrderCommand.Create, TradeType.Buy, 100m, 100m, DateTime.UtcNow.AddMinutes(5)); Assert.True(signalInFuture.IsTimeInThreshold(TimeSpan.FromMinutes(6))); Assert.False(signalInFuture.IsTimeInThreshold(TimeSpan.FromMinutes(4))); }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var cts = new CancellationTokenSource(timeout); var orderInfo = await privateData.AddOrder(signal, translatedSignal, cts.Token); string txId = orderInfo.TxId.FirstOrDefault(); translatedSignal.ExternalId = txId; return(new ExecutionReport(signal.Instrument, DateTime.UtcNow, signal.Price ?? 0, signal.Volume, signal.TradeType, signal.OrderId, OrderExecutionStatus.New)); }
public override async Task <ExecutionReport> CancelOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var ct = new CancellationTokenSource(timeout); var id = signal.OrderId; var response = await _exchangeApi.OrdercancelAsync(cancellationToken : ct.Token, orderID : id); if (response is Error error) { throw new ApiException(error.ErrorProperty.Message); } var res = EnsureCorrectResponse(id, response); return(BitMexModelConverter.OrderToTrade(res[0])); }
/// <summary> /// Adds the signal. /// </summary> /// <param name="name">The name.</param> /// <param name="action">The action.</param> /// <param name="interval">The interval.</param> /// <returns></returns> public TradingSignal AddSignal(string name, Func <Security, bool> action, TimeSpan interval) { TradingSignal nevent = new TradingSignal(Universe, name, action, true); ScheduledActionsKeeper.Event(QuantFund.FundId, Date.EveryDay(), Time.Every(interval), () => { if (IsRunning) { nevent.Execute(); } }); Signals[nevent.Name] = nevent; return(nevent); }
public override async Task <ExecutionReport> CancelOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var cts = new CancellationTokenSource(timeout); string result = await apiClient.MakePostRequestAsync <string>( $"{Config.EndpointUrl}/api/Orders/{signal.OrderId}/Cancel", CreateHttpContent(new object()), translatedSignal.RequestSent, translatedSignal.ResponseReceived, cts.Token); return(new ExecutionReport(signal.Instrument, DateTime.UtcNow, signal.Price ?? 0, signal.Volume, signal.TradeType, signal.OrderId, OrderExecutionStatus.Cancelled)); }
/// <summary> /// Adds the signal. /// </summary> /// <param name="name">The name.</param> /// <param name="action">The action.</param> /// <param name="trigger">The trigger.</param> /// <returns></returns> public TradingSignal AddSignal(string name, Func <Security, bool> action, DataAggregator trigger) { TradingSignal nevent = new TradingSignal(Universe, name, action); trigger.DataAggregated += (sender, aggregate) => { if (IsRunning) { nevent.Execute(); } }; nevent.SignalFired += OnSignal; Signals[nevent.Name] = nevent; return(nevent); }
public async Task <ExecutionReport> CancelOrder(string id, [FromQuery, Required] string exchangeName) { try { if (string.IsNullOrEmpty(exchangeName)) { throw new StatusCodeException(HttpStatusCode.InternalServerError, "Exchange has to be specified"); } var instrument = new Instrument(exchangeName, string.Empty); var tradingSignal = new TradingSignal(instrument, id, OrderCommand.Cancel, TradeType.Unknown, 0, 0, DateTime.UtcNow, OrderType.Unknown); var translatedSignal = new TranslatedSignalTableEntity(SignalSource.RestApi, tradingSignal) { ClientIP = HttpContext.Connection.RemoteIpAddress.ToString() }; try { var result = await Application.GetExchange(exchangeName) .CancelOrderAndWaitExecution(tradingSignal, translatedSignal, _timeout); if (result.ExecutionStatus == OrderExecutionStatus.Rejected) { throw new StatusCodeException(HttpStatusCode.BadRequest, $"Exchange return status: {result.ExecutionStatus}", null); } return(result); } catch (Exception e) { translatedSignal.Failure(e); throw; } finally { await _translatedSignalsRepository.SaveAsync(translatedSignal); } } catch (StatusCodeException) { throw; } catch (Exception e) { throw new StatusCodeException(HttpStatusCode.InternalServerError, e.Message, e); } }
public NewOrderSingle CreateNewOrderSingle(TradingSignal tradingSignal) { var newOrderSingle = new NewOrderSingle { Symbol = new Symbol(LykkeSymbolToExchangeSymbol(tradingSignal.Instrument.Name)), Currency = new Currency(tradingSignal.Instrument.Base), Side = ConvertSide(tradingSignal.TradeType), OrderQty = new OrderQty(tradingSignal.Volume), OrdType = ConvertOrderType(tradingSignal.OrderType), TimeInForce = new TimeInForce(TimeInForce.IMMEDIATE_OR_CANCEL), TransactTime = new TransactTime(DateTime.UtcNow), Price = new Price(tradingSignal.Price ?? 0m) }; return(newOrderSingle); }
public override async Task <ExecutionReport> CancelOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var result = await privateData.CancelOrder(signal.OrderId, translatedSignal); var executedTrade = new ExecutionReport(signal.Instrument, DateTime.UtcNow, signal.Price ?? 0, signal.Volume, signal.TradeType, signal.OrderId, result.Pending ? OrderExecutionStatus.Pending : OrderExecutionStatus.Cancelled); translatedSignal.SetExecutionResult(executedTrade); return(executedTrade); }
/// <summary> /// Adds the signal. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">The name.</param> /// <param name="action">The action.</param> /// <param name="trigger">The trigger.</param> /// <returns></returns> public TradingSignal AddSignal <T>(string name, Func <Security, bool> action, T trigger) where T : IndicatorBase <IndicatorDataPoint> { TradingSignal nevent = new TradingSignal(Universe, name, action); trigger.Updated += (sender, updated) => { if (IsRunning) { nevent.Execute(); } }; nevent.SignalFired += OnSignal; Signals[nevent.Name] = nevent; return(nevent); }
public void SetSignal(TradingSignal signal) { if (signal == null) { return; } lb_ID.Text = signal.Id.ToString(); lb_ActualTime.Text = signal.ActualTime; lb_Comment.Text = signal.Comment; lb_Pair.Text = signal.Pair; lb_CMD.Text = signal.Cmd.ToString(); lb_Price.Text = Math.Round(signal.Price, 5).ToString(); lb_SL.Text = Math.Round(signal.Sl, 5).ToString(); lb_TP.Text = Math.Round(signal.Tp, 5).ToString(); lb_TradingSystem.Text = signal.TradingSystem.ToString(); lb_Period.Text = signal.Period; }
public override Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { translatedSignal.RequestSentMessage("stub exchange don't send actual request"); // // SimulateWork(); // SimulateException(); // translatedSignal.ResponseReceived("stub exchange don't recevie actual response"); lock (syncRoot) { var s = new TradingSignal(signal.Instrument, Guid.NewGuid().ToString(), signal.Command, signal.TradeType, signal.Price, signal.Volume, signal.Time, signal.OrderType, signal.TimeInForce); ActualSignals[signal.Instrument.Name].AddLast(s); translatedSignal.ExternalId = s.OrderId; return(Task.FromResult(new ExecutionReport(s.Instrument, DateTime.UtcNow, s.Price ?? 0, s.Volume, s.TradeType, s.OrderId, OrderExecutionStatus.New))); } }
public TranslatedSignalTableEntity(SignalSource signalSource, TradingSignal signal) { ReceiveDateTime = DateTime.UtcNow; Status = TranslationStatus.Success; SignalSource = signalSource; Exchange = signal.Instrument.Exchange; Instrument = signal.Instrument.Name; SignalDateTime = signal.Time; OrderCommand = signal.Command; OrderId = signal.OrderId; Price = signal.Price; Volume = signal.Volume; OrderType = signal.OrderType; TradeType = signal.TradeType; TimeInForce = signal.TimeInForce; }
public void SerializeAndDeserializeTradingSignal() { var converter = new GenericRabbitModelConverter <TradingSignal>(); var signal = new TradingSignal(new Instrument("Exchange", "EURUSD"), "", OrderCommand.Create, TradeType.Buy, 100.2m, 10.1m, DateTime.UtcNow, OrderType.Limit); var serialized = converter.Serialize(signal); Assert.NotNull(serialized); var deserialized = converter.Deserialize(serialized); Assert.Equal(signal.TradeType, deserialized.TradeType); Assert.Equal(signal.Volume, deserialized.Volume); Assert.Equal(signal.OrderType, deserialized.OrderType); Assert.Equal(signal.Time, deserialized.Time); Assert.Equal(signal.OrderId, deserialized.OrderId); Assert.Equal(signal.Command, deserialized.Command); }
public override async Task <ExecutionReport> CancelOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var cts = new CancellationTokenSource(timeout); if (!long.TryParse(signal.OrderId, out var id)) { throw new ApiException("Bitfinex order id can be only integer"); } var response = await _exchangeApi.CancelOrder(id, cts.Token); if (response is Error error) { throw new ApiException(error.Message); } var trade = OrderToTrade((Order)response); return(trade); }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var symbol = "XBTUSD"; //HACK Hard code! var volume = BitMexModelConverter.ConvertVolume(signal.Volume); var orderType = BitMexModelConverter.ConvertOrderType(signal.OrderType); var side = BitMexModelConverter.ConvertTradeType(signal.TradeType); var price = (double?)signal.Price; var ct = new CancellationTokenSource(timeout); var response = await _exchangeApi.OrdernewAsync(symbol, orderQty : volume, price : price, clOrdID : signal.OrderId, ordType : orderType, side : side, cancellationToken : ct.Token); if (response is Error error) { throw new ApiException(error.ErrorProperty.Message); } var order = (Order)response; return(BitMexModelConverter.OrderToTrade(order)); }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var symbol = _modelConverter.LykkeSymbolToExchangeSymbol(signal.Instrument.Name); var volume = signal.Volume; var orderType = _modelConverter.ConvertOrderType(signal.OrderType); var side = _modelConverter.ConvertTradeType(signal.TradeType); var price = signal.Price == 0 ? 1 : signal.Price ?? 1; var cts = new CancellationTokenSource(timeout); var response = await _exchangeApi.AddOrder(symbol, volume, price, side, orderType, cts.Token); if (response is Error error) { throw new ApiException(error.Message); } var trade = OrderToTrade((Order)response); return(trade); }
public Task Handle(TradingSignal message) { if (message == null || message.Instrument == null || string.IsNullOrEmpty(message.Instrument.Name)) { return(logger.WriteWarningAsync( nameof(TradingSignalsHandler), nameof(Handle), message?.ToString(), "Received an unconsistent signal")); } if (!exchanges.ContainsKey(message.Instrument.Exchange)) { return(logger.WriteWarningAsync( nameof(TradingSignalsHandler), nameof(Handle), message.ToString(), $"Received a trading signal for unconnected exchange {message.Instrument.Exchange}")); } return(HandleTradingSignals(exchanges[message.Instrument.Exchange], message)); }
public override Task <ExecutionReport> CancelOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { translatedSignal.RequestSentMessage("stub exchange don't send actual request"); // SimulateWork(); // SimulateException(); translatedSignal.ResponseReceived("stub exchange don't recevie actual response"); bool isCanceled = false; lock (syncRoot) { TradingSignal existing = ActualSignals[signal.Instrument.Name].FirstOrDefault(x => x.OrderId == signal.OrderId); if (existing != null) { ActualSignals[signal.Instrument.Name].Remove(existing); isCanceled = true; } } return(Task.FromResult(new ExecutionReport(signal.Instrument, DateTime.UtcNow, signal.Price ?? 0, signal.Volume, signal.TradeType, signal.OrderId, isCanceled ? OrderExecutionStatus.Cancelled : OrderExecutionStatus.Unknown))); }
private async Task HandleCancellation(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, Exchange exchange) { try { var executedTrade = await exchange.CancelOrderAndWaitExecution(signal, translatedSignal, apiTimeout); if (executedTrade.ExecutionStatus == OrderExecutionStatus.Cancelled) { await _tradeHandler.Handle(executedTrade); } else { var message = $"Executed trade status {executedTrade.ExecutionStatus} after calling 'exchange.CancelOrderAndWaitExecution'"; translatedSignal.Failure(message); await logger.WriteWarningAsync(nameof(TradingSignalsHandler), nameof(HandleCancellation), signal.ToString(), message); } } catch (ApiException e) { translatedSignal.Failure(e); await logger.WriteInfoAsync(nameof(TradingSignalsHandler), nameof(HandleCancellation), signal.ToString(), e.Message); } catch (Exception e) { translatedSignal.Failure(e); await logger.WriteErrorAsync(nameof(TradingSignalsHandler), nameof(HandleCancellation), signal.ToString(), e); } }
private async Task HandleTradingSignals(Exchange exchange, TradingSignal signal) { await logger.WriteInfoAsync(nameof(TradingSignalsHandler), nameof(HandleTradingSignals), signal.ToString(), "New trading signal to be handled."); var translatedSignal = new TranslatedSignalTableEntity(SignalSource.RabbitQueue, signal); try { switch (signal.Command) { case OrderCommand.Create: await HandleCreation(signal, translatedSignal, exchange); break; case OrderCommand.Cancel: await HandleCancellation(signal, translatedSignal, exchange); break; default: throw new ArgumentOutOfRangeException(nameof(signal)); } } catch (Exception e) { translatedSignal.Failure(e); } finally { translatedSignalsRepository.Save(translatedSignal); await logger.WriteInfoAsync(nameof(TradingSignalsHandler), nameof(HandleTradingSignals), signal.ToString(), "Signal handled. Waiting for another one."); } }
public override async Task <ExecutionReport> AddOrderAndWaitExecution(TradingSignal signal, TranslatedSignalTableEntity translatedSignal, TimeSpan timeout) { var symbol = _converters.LykkeSymbolToExchangeSymbol(signal.Instrument.Name); var orderType = _converters.OrderTypeToGdaxOrderType(signal.OrderType); var side = _converters.TradeTypeToGdaxOrderSide(signal.TradeType); var volume = signal.Volume; var price = (!signal.Price.HasValue || signal.Price == 0) ? 1 : signal.Price.Value; var cts = CreateCancellationTokenSource(timeout); try { var response = await _restApi.AddOrder(symbol, volume, price, side, orderType, cts.Token, (sender, httpRequest) => OnSentHttpRequest(httpRequest, translatedSignal), (sender, httpResponse) => OnReceivedHttpRequest(httpResponse, translatedSignal)); var trade = _converters.OrderToTrade(response); return(trade); } catch (StatusCodeException ex) { throw new ApiException(ex.Message); } }