public override TradingOperationResult ModifyOrder(ModifyOrderRequestParameters parameters) { var result = new TradingOperationResult(); string orderId = parameters.OrderId; decimal quantity = (decimal)parameters.Quantity; decimal price = -1; if (parameters.OrderTypeId == OrderType.Limit || parameters.OrderTypeId == OrderType.StopLimit) { price = (decimal)parameters.Price; } else { price = (decimal)parameters.TriggerPrice; } var response = this.CheckHitResponse(this.socketApi.ReplaceOrderAsync(orderId, quantity, price, cancellationToken: parameters.CancellationToken).Result, out var error, true); if (response != null) { result.Status = TradingOperationResultStatus.Success; result.OrderId = response.ClientOrderId; } else { result.Status = TradingOperationResultStatus.Failure; result.Message = error?.ToString() ?? "Unknown error"; } return(result); }
private void QuoteHandler(Symbol instrument, Quote quote) { if (Core.Instance.Positions.Length != 0) { //Закрытие позиций if (this.indicatorFastMA.GetValue(1) < this.indicatorSlowMA.GetValue(1) || this.indicatorFastMA.GetValue(1) > this.indicatorSlowMA.GetValue(1)) { TradingOperationResult result = Core.Instance.ClosePosition(new ClosePositionRequestParameters() { Position = Core.Instance.Positions[0], CloseQuantity = Core.Instance.Positions[0].Quantity }); if (result.Status == TradingOperationResultStatus.Success) { Log($"{result.Status}. Position was closed.", StrategyLoggingLevel.Trading); } } } if (Core.Instance.Positions.Length == 0) { //Открытие новых позиций if (this.indicatorFastMA.GetValue(1) > this.indicatorSlowMA.GetValue(1)) { TradingOperationResult result = Core.Instance.PlaceOrder(new PlaceOrderRequestParameters() { OrderTypeId = OrderType.Market, Quantity = quantity, Side = Side.Buy, Account = this.account, Symbol = this.symbol }); if (result.Status == TradingOperationResultStatus.Success) { Log($"{result.Status}. Long position was placed.", StrategyLoggingLevel.Trading); } longPositionsCount++; } else if (this.indicatorFastMA.GetValue(1) < this.indicatorSlowMA.GetValue(1)) { TradingOperationResult result = Core.Instance.PlaceOrder(new PlaceOrderRequestParameters() { OrderTypeId = OrderType.Market, Quantity = quantity, Side = Side.Sell, Account = this.account, Symbol = this.symbol }); if (result.Status == TradingOperationResultStatus.Success) { Log($"{result.Status}. Short position was placed.", StrategyLoggingLevel.Trading); } shortPositionsCount++; } } }
public override TradingOperationResult PlaceOrder(PlaceOrderRequestParameters parameters) { var result = new TradingOperationResult(); string symbol = parameters.Symbol.Id; HitSide side = parameters.Side == Side.Buy ? HitSide.Buy : HitSide.Sell; decimal quantity = (decimal)parameters.Quantity; decimal price = -1; decimal stopPrice = -1; if (parameters.OrderTypeId == OrderType.Limit || parameters.OrderTypeId == OrderType.StopLimit) { price = (decimal)parameters.Price; } if (parameters.OrderTypeId == OrderType.Stop || parameters.OrderTypeId == OrderType.StopLimit) { stopPrice = (decimal)parameters.TriggerPrice; } HitTimeInForce timeInForce = this.ConvertTimeInForce(parameters.TimeInForce); DateTime expireTime = default; if (timeInForce == HitTimeInForce.GTD) { expireTime = parameters.ExpirationTime; } var response = this.CheckHitResponse(this.socketApi.PlaceNewOrderAsync(symbol, side, quantity, price, stopPrice, timeInForce, expireTime, cancellationToken: parameters.CancellationToken).Result, out var error, true); if (response != null) { result.Status = TradingOperationResultStatus.Success; result.OrderId = response.ClientOrderId; } else { result.Status = TradingOperationResultStatus.Failure; result.Message = error?.ToString() ?? "Unknown error"; } return(result); }
public override TradingOperationResult CancelOrder(CancelOrderRequestParameters parameters) { var result = new TradingOperationResult(); var response = this.CheckHitResponse(this.socketApi.CancelOrderAsync(parameters.Order.Id, parameters.CancellationToken).Result, out var error, true); if (response != null) { result.Status = TradingOperationResultStatus.Success; result.OrderId = response.ClientOrderId; } else { result.Status = TradingOperationResultStatus.Failure; result.Message = error?.ToString() ?? "Unknown error"; } return(result); }
private void StrategyProcess(MessageQuote message) { if (historicalData.Count <= maxPeriod) { return; } // Calculation of trend Trend trend = (Trend)threeMaIndicator.GetValue(); switch (trend) { case Trend.Up: // Up trend detected. If we were in short position, first closing it if (tradingState == TradingState.EnteredSell) { // If request for closing has been sent, setting the current state - // we have already exit the market Position position = Core.Instance.GetPositionById(currentOrderResult.OrderId, symbol.ConnectionId); if (position == null) { return; } var result = position.Close(); if (result.Status == TradingOperationResultStatus.Success) { tradingState = TradingState.ExitMarket; Log($"{currentOrderResult.Status}. Position was closed.", StrategyLoggingLevel.Trading); } // exitting the program to give some time to // the system for processing the order. Entrance will // be performed on the next quote return; } // If we haven't aleady entered the market, do it if (tradingState != TradingState.EnteredBuy) { var orderPrice = symbol.Bid; if (message is Last last) { orderPrice = last.Price; } if (message is Quote quote) { orderPrice = quote.Ask; } // Sending request for opening long position, and // setting the state - "Entered long position" currentOrderResult = Core.PlaceOrder(new PlaceOrderRequestParameters { Account = account, Symbol = this.symbol, Price = orderPrice, OrderTypeId = OrderType.Market, Quantity = quantity, Side = Side.Buy, }); longOrdersCount++; tradingState = TradingState.EnteredBuy; if (currentOrderResult.Status == TradingOperationResultStatus.Success) { Log($"{currentOrderResult.Status}. Long position was placed.", StrategyLoggingLevel.Trading); } else { Log($"{currentOrderResult.Status}. {currentOrderResult.Message}", StrategyLoggingLevel.Trading); } } break; case Trend.Down: //Down trend detected. If we were in long position, firstly closing it if (tradingState == TradingState.EnteredBuy) { // If request for closing has been sent, setting the current state - // we have already exit the market Position position = Core.Instance.GetPositionById(currentOrderResult.OrderId, symbol.ConnectionId); if (position == null) { return; } var result = position.Close(); if (result.Status == TradingOperationResultStatus.Success) { tradingState = TradingState.ExitMarket; Log($"{currentOrderResult.Status}. Position was closed.", StrategyLoggingLevel.Trading); } // exitting the program to give some time to // the system for processing the order. Entrance will // be performed on the next quote return; } // If we haven't aleady entered the market, do it if (tradingState != TradingState.EnteredSell) { var orderPrice = symbol.Bid; if (message is Last last) { orderPrice = last.Price; } if (message is Quote quote) { orderPrice = quote.Bid; } // Sending request for opening long position, and // if request is sent, then setting the state - "Entered short position" currentOrderResult = Core.PlaceOrder(new PlaceOrderRequestParameters { Account = account, Symbol = this.symbol, Price = orderPrice, OrderTypeId = OrderType.Market, Quantity = quantity, Side = Side.Sell, }); shortOrdersCount++; tradingState = TradingState.EnteredSell; if (currentOrderResult.Status == TradingOperationResultStatus.Success) { Log($"{currentOrderResult.Status}. Short position was placed.", StrategyLoggingLevel.Trading); } else { Log($"{currentOrderResult.Status}. {currentOrderResult.Message}", StrategyLoggingLevel.Trading); } } break; } }
private void CreateLimitOrder(Side side) { if (_operationResult != null) { if (Core.GetPositionById(_operationResult.OrderId, symbol.ConnectionId) != null) { return; } var order = Core.Orders.FirstOrDefault(o => o.ConnectionId == symbol.ConnectionId && o.Id == _operationResult.OrderId); if (order != null) { if (order.Side == Side.Buy) { longOrdersCount--; } else { shortOrdersCount--; } order.Cancel(); Log("Order was canceled.", StrategyLoggingLevel.Trading); } } var sign = (side == Side.Buy) ? -1 : 1; var orderPrice = (side == Side.Buy) ? symbol.CalculatePrice(symbol.Ask, stopOffset * sign) : symbol.CalculatePrice(symbol.Bid, stopOffset * sign); var slPrice = orderPrice + sign * SL * symbol.TickSize; var tpPrice = orderPrice - sign * TP * symbol.TickSize; _operationResult = Core.PlaceOrder(new PlaceOrderRequestParameters() { Account = account, Symbol = symbol, Side = side, OrderTypeId = OrderType.Limit, Price = orderPrice, StopLoss = SlTpHolder.CreateSL(slPrice), TakeProfit = SlTpHolder.CreateTP(tpPrice), Quantity = Amount }); var formatedSide = string.Empty; if (side == Side.Buy) { formatedSide = "Long"; longOrdersCount++; } else { formatedSide = "Short"; shortOrdersCount++; } if (_operationResult.Status == TradingOperationResultStatus.Success) { Log($"{_operationResult.Status}. {formatedSide} order was placed.", StrategyLoggingLevel.Trading); } }