Пример #1
0
 public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
 {
     if (string.IsNullOrEmpty(order.ExpertComment))
     {
         Logger.ErrorFormat("SignalDealer.SendCloseRequest({0}) - поле ExpertComment не заполнено",
             order.ID);
         //return RequestStatus.DealerError;
     }
     // получить цену
     var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);
     if (quote == null)
         return RequestStatus.NoPrice;
     var price = order.Side > 0 ? quote.GetPrice(QuoteType.Bid) : quote.GetPrice(QuoteType.Ask);
     // отправить сигнал
     var signal = new ManagerSignal {Id = order.ExpertComment, PriceClose = (decimal)price, Category = signalCategoryCode,
         Symbol = order.Symbol, Leverage = 0, Price = (decimal)order.PriceEnter, Side = order.Side};
     var timeExec = new ThreadSafeTimeStamp();
     timeExec.Touch();
     if (!string.IsNullOrEmpty(order.ExpertComment) && !SendSignal(signal, false))
         return RequestStatus.DealerError;
     var endTime = DateTime.Now - timeExec.GetLastHit();
     Logger.InfoFormat("Время исполнения SendCloseRequest SendSignal: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
     timeExec.Touch();
     // закрыть ордер немедленно
     var result = ServerInterface.CloseOrder(order, (decimal) price, reason);
     endTime = DateTime.Now - timeExec.GetLastHit();
     Logger.InfoFormat("Время исполнения SendCloseRequest - CloseOrder: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
     return result ? RequestStatus.OK : RequestStatus.ServerError;
 }
Пример #2
0
        private int SendCloseRequestsInner(int[] orderId, PositionExitReason reason, out RequestStatus lastStatus)
        {
            var countOk = 0;

            lastStatus = RequestStatus.OK;
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    foreach (var posId in orderId)
                    {
                        var pos = ctx.POSITION.FirstOrDefault(p => p.ID == posId);
                        lastStatus = pos == null ? RequestStatus.NotFound : managerTrade.SendCloseRequest(pos, reason);
                        if (lastStatus == RequestStatus.OK)
                        {
                            countOk++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в PlatformManager.SendCloseRequest", ex);
                lastStatus = RequestStatus.ServerError;
            }
            return(countOk);
        }
Пример #3
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            var requestedPrice = 0M;
            var quote          = QuoteStorage.Instance.ReceiveValue(order.Symbol);

            if (quote != null)
            {
                requestedPrice = (decimal)(order.Side > 0 ? quote.bid : quote.ask);
            }

            if (!order.MasterOrder.HasValue)
            {
                Logger.DebugFormat("{0}: SendCloseRequest - закрытие ордера {1} - MasterOrder не задан",
                                   DealerCode, order.ToStringShort());
                return(RequestStatus.DealerError);
            }

            var status = MakeMarketRequest(new TradeTransactionRequest
            {
                Account           = order.AccountID,
                ClosingPositionId = order.MasterOrder,
                Comment           = order.Comment,
                ExpertComment     = order.ExpertComment,
                Id             = order.ID,
                Magic          = order.Magic,
                RequestedPrice = requestedPrice,
                SlippageAbs    = 0,
                Side           = order.Side,
                Symbol         = order.Symbol,
                Volume         = order.Volume
            }, order);

            return(status);
        }
Пример #4
0
        public RequestStatus SendCloseRequest(int orderId, PositionExitReason reason)
        {
            RequestStatus status;

            SendCloseRequestsInner(new[] { orderId }, reason, out status);
            return(status);
        }
Пример #5
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            // получить счет
            RequestStatus error;
            var           acDecorated = ServerInterface.GetAccount(order.AccountID);

            if (acDecorated == null)
            {
                return(RequestStatus.ServerError);
            }

            // подготовить запрос
            TradeSharp.ProviderProxyContract.Entity.MarketOrder request;
            if (!MakeMarketRequest(acDecorated, order.Symbol, order.Magic, order.Volume, -order.Side,
                                   OrderType.Market,
                                   0, 0,
                                   string.Format("close order #{0}", order.ID),
                                   order.ID, order.Comment, order.ExpertComment, order.TrailLevel1, order.TrailTarget1,
                                   out error, out request))
            {
                return(error);
            }
            exitReasonByOrderId.UpdateValues(order.ID, reason);

            // отправить запрос на вход в рынок (оно же - закрытие позиции) в соотв сессию
            if (!request.SendToQueue(false))
            {
                errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОшибкаОтправки,
                                                         "Невозможно отправить сообщение (CloseOrder) в очередь MQ", null));
                return(RequestStatus.DealerError);
            }
            return(RequestStatus.OK);
        }
Пример #6
0
        public RequestStatus SendCloseRequestSafe(int accountId, int orderId, PositionExitReason reason)
        {
            if (InvokeRequired)
            {
                return((RequestStatus)Invoke(new Func <int, int, PositionExitReason, RequestStatus>(SendCloseRequestUnsafe),
                                             accountId, orderId, reason));
            }

            return(SendCloseRequestUnsafe(accountId, orderId, reason));
        }
Пример #7
0
        /// <summary>
        /// Вспомогательный метод - закрывает позицию текушими значниями времени и катеровок
        /// </summary>
        /// <param name="closeDealIdValue"></param>
        /// <param name="warningList"></param>
        /// <param name="validationErrorList"></param>
        /// <param name="timeExit"></param>
        /// <param name="ddlExitReasonValue"></param>
        /// <returns></returns>
        private ActionResult CloseDaelCurrentTimeValues(string closeDealIdValue, List <string> warningList, List <string> validationErrorList,
                                                        DateTime timeExit, PositionExitReason ddlExitReasonValue)
        {
            var strings   = GetSidePriceListById(closeDealIdValue);
            var adoHalper = new DatabaseQuoteEnquirer();
            var tickers   = strings.Select(x => x.Split('_')[0]).Distinct();

            var quotes = tickers.ToDictionary(x => x, x => adoHalper.GetQuoteStoredProc(x));


            var lstStoragePrice = new List <Tuple <string, int, float> >();

            foreach (var inp in strings)
            {
                var input = inp.Split('_');
                var side  = Utils.dealSide[input[1]];
                var quote = quotes.Where(x => x.Key == input[0]).ToList();


                if (quote.Any())
                {
                    var price = quote.First().Value.bid;
                    if (side == -1)
                    {
                        price = quote.First().Value.ask;
                    }
                    lstStoragePrice.Add(new Tuple <string, int, float>(input[0], side, price));
                }
                else
                {
                    warningList.Add(String.Format("{0} : {1} {2}. {3}.",
                                                  Resource.ErrorMessage, Resource.ErrorMessageQuoteNotFound, input[0], Resource.ErrorMessageTransactionsOnPairWillNotClosed));
                    Logger.Error(String.Format("CloseOrCancelDeal - попытка принудительно закрыть сделки администратором. " +
                                               "Ошибка: для валютной пары {0} не найдены катировка. Сделки по этой валютной паре не будут закрыты.", input[0]));
                }
            }

            if (validationErrorList.Count > 0)
            {
                ViewBag.ErrorList   = validationErrorList;
                ViewBag.WarningList = warningList;
                var model = GetPositionsEditModel(closeDealIdValue);
                return(View("SafePositionEdit", model));
            }


            var successCloseDeals = positionRepository.ClosingPositions(closeDealIdValue, timeExit, ddlExitReasonValue, lstStoragePrice);
            var msg = successCloseDeals.Count < 10 ?
                      string.Format("{0}: {1}. {2}",
                                    Resource.MessageMarketOrderClosed, string.Join(", ", successCloseDeals), Resource.ErrorMessageClosedNotAllTransactions) :
                      string.Format("{0} {1} {2}. {3}",
                                    Resource.MessageMarketOrderClosed, string.Join(", ", successCloseDeals.Take(10)), Resource.TextEtc, Resource.ErrorMessageClosedNotAllTransactions);

            return(RedirectToAction("PositionList", new { message = msg, positionId = -1 }));
        }
Пример #8
0
        public RequestStatus SendCloseByTickerRequestSafe(int accountId, string ticker,
                                                          PositionExitReason reason)
        {
            if (InvokeRequired)
            {
                return((RequestStatus)Invoke(new Func <int, string, PositionExitReason, RequestStatus>(SendCloseByTickerRequestUnsafe),
                                             accountId, ticker, reason));
            }

            return(SendCloseByTickerRequestUnsafe(accountId, ticker, reason));
        }
Пример #9
0
        public virtual RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            // получить цену
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);
            if (quote == null)
                return RequestStatus.NoPrice;
            var price = order.Side > 0 ? quote.GetPrice(QuoteType.Bid) : quote.GetPrice(QuoteType.Ask);

            // закрыть ордер немедленно
            return ServerInterface.CloseOrder(order, (decimal)price, reason)
                ? RequestStatus.OK : RequestStatus.ServerError;
        }
Пример #10
0
        public virtual RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            // получить цену
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            var price = order.Side > 0 ? quote.GetPrice(QuoteType.Bid) : quote.GetPrice(QuoteType.Ask);

            // закрыть ордер немедленно
            return(ServerInterface.CloseOrder(order, (decimal)price, reason)
                ? RequestStatus.OK : RequestStatus.ServerError);
        }
Пример #11
0
        public bool CloseOrder(int orderId, decimal price, PositionExitReason exitReason)
        {
            MarketOrder orderDecor;

            using (var ctx = DatabaseContext.Instance.Make())
            {
                var orderQuery = ctx.POSITION.Where(p => p.ID == orderId).ToList();
                if (orderQuery.Count == 0)
                {
                    Logger.ErrorFormat("CloseOrder(Id = {0}) - позиция не найдена", orderId);
                    return(false);
                }
                orderDecor = LinqToEntity.DecorateOrder(orderQuery[0]);
            }
            return(CloseOrder(orderDecor, price, exitReason));
        }
Пример #12
0
        public override RequestStatus SendCloseRequest(ProtectedOperationContext ctx,
                                                       int accountId, int orderId, PositionExitReason reason)
        {
            var pos = positions.FirstOrDefault(o => o.ID == orderId);

            if (pos == null)
            {
                return(RequestStatus.NotFound);
            }
            var quote = quotesStorage.ReceiveValue(pos.Symbol);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            ClosePositionAndCalculateProfit(pos, quote, reason);
            return(RequestStatus.OK);
        }
Пример #13
0
 public RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker,
                                               PositionExitReason reason)
 {
     try
     {
         return(Proxy.SendCloseByTickerRequest(ctx, accountId, ticker, reason));
     }
     catch (Exception ex)
     {
         RenewChannel();
         try
         {
             return(Proxy.SendCloseByTickerRequest(ctx, accountId, ticker, reason));
         }
         catch (Exception ex2)
         {
             return(RequestStatus.ServerError);
         }
     }
 }
Пример #14
0
        private void TryCloseOrder(MarketOrder pos, PositionExitReason reason)
        {
            // проверка - не вызывается ли метод раз за разом для одной и той же позиции,
            // которую невозможно закрыть, например, из-за недостатка свободной маржи
            DateTime lastTime;

            if (orderFloodTimes.TryGetValue(pos.ID, out lastTime))
            {
                if (DateTime.Now < lastTime)
                {
                    return;
                }
            }
            orderFloodTimes.Remove(pos.ID);

            // отправить запрос
            proxyTrade.SendCloseRequest(ProtectedOperationContext.MakeServerSideContext(), pos.AccountID, pos.ID, reason);

            // не допустить забивание потока попытками закрыть позу...
            orderFloodTimes.Add(pos.ID, DateTime.Now.AddMilliseconds(OrderFloodTimeoutMils));
        }
Пример #15
0
        public override RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId,
                                                               string ticker, PositionExitReason reason)
        {
            var posToClose = positions.Where(p => p.Symbol == ticker).ToList();

            if (posToClose.Count == 0)
            {
                return(RequestStatus.OK);
            }

            var quote = quotesStorage.ReceiveValue(ticker);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            foreach (var pos in posToClose)
            {
                ClosePositionAndCalculateProfit(pos, quote, reason);
            }
            return(RequestStatus.OK);
        }
Пример #16
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            if (string.IsNullOrEmpty(order.ExpertComment))
            {
                Logger.ErrorFormat("SignalDealer.SendCloseRequest({0}) - поле ExpertComment не заполнено",
                                   order.ID);
                //return RequestStatus.DealerError;
            }
            // получить цену
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);

            if (quote == null)
            {
                return(RequestStatus.NoPrice);
            }
            var price = order.Side > 0 ? quote.GetPrice(QuoteType.Bid) : quote.GetPrice(QuoteType.Ask);
            // отправить сигнал
            var signal = new ManagerSignal {
                Id     = order.ExpertComment, PriceClose = (decimal)price, Category = signalCategoryCode,
                Symbol = order.Symbol, Leverage = 0, Price = (decimal)order.PriceEnter, Side = order.Side
            };
            var timeExec = new ThreadSafeTimeStamp();

            timeExec.Touch();
            if (!string.IsNullOrEmpty(order.ExpertComment) && !SendSignal(signal, false))
            {
                return(RequestStatus.DealerError);
            }
            var endTime = DateTime.Now - timeExec.GetLastHit();

            Logger.InfoFormat("Время исполнения SendCloseRequest SendSignal: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            timeExec.Touch();
            // закрыть ордер немедленно
            var result = ServerInterface.CloseOrder(order, (decimal)price, reason);

            endTime = DateTime.Now - timeExec.GetLastHit();
            Logger.InfoFormat("Время исполнения SendCloseRequest - CloseOrder: {0} секунд, {1} миллисекунд", endTime.TotalSeconds, endTime.TotalMilliseconds);
            return(result ? RequestStatus.OK : RequestStatus.ServerError);
        }
Пример #17
0
        public RequestStatus SendCloseRequest(POSITION order, PositionExitReason reason)
        {
            Account account;
            var     dealer = GetDealerByAccount(order.AccountID, out account);

            if (dealer == null)
            {
                return(RequestStatus.GroupUnsupported);
            }

            // проверить маржинальные требования
            decimal equity;

            if (!tradeManager.IsEnterEnabled(order.AccountID, order.Symbol, -order.Side, order.Volume, out equity))
            {
                return(RequestStatus.MarginOrLeverageExceeded);
            }

            try
            {
                var res = dealer.SendCloseRequest(LinqToEntity.DecorateOrder(order), reason);
                if (res == RequestStatus.OK)
                {
                    Logger.InfoFormat("Ордер {0} закрыт, счет {1} символ {2}, объем {3}, тип {4}", order.ID, order.AccountID, order.Symbol, order.Volume, order.Side == 1 ? "buy": "sell");
                }
                else
                {
                    Logger.ErrorFormat("Ошибка закрытия ордера {0} - ответ дилера:{1}", order.ID, res);
                }
                return(res);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("Ошибка дилера {0}: {1}", dealer, ex);
                return(RequestStatus.DealerError);
            }
        }
Пример #18
0
        public RequestStatus SendCloseRequest(ProtectedOperationContext secCtx,
                                              int accountId, int orderId, PositionExitReason reason)
        {
            if (UserOperationRightsStorage.IsProtectedOperation(UserOperation.CloseOrder))
            {
                if (!UserSessionStorage.Instance.PermitUserOperation(secCtx,
                                                                     UserOperationRightsStorage.IsTradeOperation(UserOperation.ModifyOrder), true))
                {
                    return(RequestStatus.Unauthorized);
                }
            }

            // получить позу
            POSITION order;

            using (var ctx = DatabaseContext.Instance.Make())
            {
                order = ctx.POSITION.FirstOrDefault(p => p.ID == orderId && p.AccountID == accountId);
                if (order != null)
                {
                    if (order.State != (int)PositionState.Opened)
                    {
                        return(RequestStatus.BadRequest);
                    }
                }
            }
            if (order == null)
            {
                return(RequestStatus.NotFound);
            }

            AccountLogger.InfoFormat("Вызов SendCloseRequest(acc #{0}, orderId #{1}, us. machine \"{2}\")",
                                     accountId, orderId, secCtx.userMachineName);

            return(SendCloseRequest(order, reason));
        }
        /// <summary>
        /// Вспомогательный метод - закрывает позицию текушими значниями времени и катеровок
        /// </summary>
        /// <param name="closeDealIdValue"></param>
        /// <param name="warningList"></param>
        /// <param name="validationErrorList"></param>
        /// <param name="timeExit"></param>
        /// <param name="ddlExitReasonValue"></param>
        /// <returns></returns>
        private ActionResult CloseDaelCurrentTimeValues(string closeDealIdValue, List<string> warningList, List<string> validationErrorList,
                                                        DateTime timeExit, PositionExitReason ddlExitReasonValue)
        {
            var strings = GetSidePriceListById(closeDealIdValue);
            var adoHalper = new DatabaseQuoteEnquirer();
            var tickers = strings.Select(x => x.Split('_')[0]).Distinct();

            var quotes = tickers.ToDictionary(x => x, x => adoHalper.GetQuoteStoredProc(x));

            var lstStoragePrice = new List<Tuple<string, int, float>>();
            foreach (var inp in strings)
            {
                var input = inp.Split('_');
                var side = Utils.dealSide[input[1]];
                var quote = quotes.Where(x => x.Key == input[0]).ToList();

                if (quote.Any())
                {
                    var price = quote.First().Value.bid;
                    if (side == -1) price = quote.First().Value.ask;
                    lstStoragePrice.Add(new Tuple<string, int, float>(input[0], side, price));
                }
                else
                {
                    warningList.Add(String.Format("{0} : {1} {2}. {3}.",
                        Resource.ErrorMessage, Resource.ErrorMessageQuoteNotFound, input[0], Resource.ErrorMessageTransactionsOnPairWillNotClosed));
                    Logger.Error(String.Format("CloseOrCancelDeal - попытка принудительно закрыть сделки администратором. " +
                                               "Ошибка: для валютной пары {0} не найдены катировка. Сделки по этой валютной паре не будут закрыты.",input[0]));
                }
            }

            if (validationErrorList.Count > 0)
            {
                ViewBag.ErrorList = validationErrorList;
                ViewBag.WarningList = warningList;
                var model = GetPositionsEditModel(closeDealIdValue);
                return View("SafePositionEdit", model);
            }

            var successCloseDeals = positionRepository.ClosingPositions(closeDealIdValue, timeExit, ddlExitReasonValue, lstStoragePrice);
            var msg = successCloseDeals.Count < 10 ?
                string.Format("{0}: {1}. {2}",
                Resource.MessageMarketOrderClosed, string.Join(", ", successCloseDeals), Resource.ErrorMessageClosedNotAllTransactions) :
            string.Format("{0} {1} {2}. {3}",
            Resource.MessageMarketOrderClosed, string.Join(", ", successCloseDeals.Take(10)), Resource.TextEtc, Resource.ErrorMessageClosedNotAllTransactions);

            return RedirectToAction("PositionList", new { message = msg, positionId = -1 });
        }
Пример #20
0
 public override RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker, PositionExitReason reason)
 {
     if (IsDayOff()) return RequestStatus.WrongTime;
     return base.SendCloseByTickerRequest(ctx, accountId, ticker, reason);
 }
Пример #21
0
 public override RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     if (IsDayOff()) return RequestStatus.WrongTime;
     return base.SendCloseRequest(ctx, accountId, orderId, reason);
 }
Пример #22
0
 public int SendCloseRequests(int[] orderIds, PositionExitReason reason)
 {
     RequestStatus status;
     return SendCloseRequestsInner(orderIds, reason, out status);
 }
Пример #23
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            var requestedPrice = 0M;
            var quote = QuoteStorage.Instance.ReceiveValue(order.Symbol);
            if (quote != null)
                requestedPrice = (decimal) (order.Side > 0 ? quote.bid : quote.ask);

            if (!order.MasterOrder.HasValue)
            {
                Logger.DebugFormat("{0}: SendCloseRequest - закрытие ордера {1} - MasterOrder не задан",
                    DealerCode, order.ToStringShort());
                return RequestStatus.DealerError;
            }

            var status = MakeMarketRequest(new TradeTransactionRequest
            {
                Account = order.AccountID,
                ClosingPositionId = order.MasterOrder,
                Comment = order.Comment,
                ExpertComment = order.ExpertComment,
                Id = order.ID,
                Magic = order.Magic,
                RequestedPrice = requestedPrice,
                SlippageAbs = 0,
                Side = order.Side,
                Symbol = order.Symbol,
                Volume = order.Volume
            }, order);
            return status;
        }
Пример #24
0
        public bool CloseOrder(MarketOrder order, decimal price, PositionExitReason exitReason)
        {
            using (var ctx = DatabaseContext.Instance.Make())
            {
                var account = ctx.ACCOUNT.FirstOrDefault(ac => ac.ID == order.AccountID);
                if (account == null)
                {
                    Logger.ErrorFormat("Закрытие ордера #{0}: невозможно прочитать данные счета ({1})",
                                       order.ID, order.AccountID);
                    return(false);
                }

                // провести ордер через биллинг
                ORDER_BILL bill = null;
                if (order.State == PositionState.Opened)
                {
                    bill = BillingManager.ProcessPriceForOrderClosing(order, LinqToEntity.DecorateAccount(account), ctx);
                }

                // посчитать результат
                // и обновить объект
                order.State     = PositionState.Closed;
                order.PriceExit = (float?)price;
                var deltaAbs = order.Side * (order.PriceExit.Value - order.PriceEnter);
                order.ResultPoints = DalSpot.Instance.GetPointsValue(order.Symbol, deltaAbs);
                var    deltaDepo = deltaAbs * order.Volume;
                var    quotes    = QuoteStorage.Instance.ReceiveAllData();
                string errorStr;
                var    resultedDepo = DalSpot.Instance.ConvertToTargetCurrency(order.Symbol, false, account.Currency,
                                                                               deltaDepo, quotes, out errorStr, false);

                if (!resultedDepo.HasValue)
                {
                    Logger.ErrorFormat("#{0} ({1} {2}{3}, {4:f1} пп): ошибка расчета прибыли в валюте депозита - {5}",
                                       order.ID,
                                       order.Side > 0 ? "B" : "S",
                                       order.Symbol,
                                       order.Volume,
                                       order.ResultPoints,
                                       errorStr);
                    return(false);
                }
                order.ResultDepo = (float)resultedDepo.Value;
                //order.Swap = (float)swap;
                order.ExitReason = exitReason;
                order.TimeExit   = DateTime.Now;
                var posClosed = LinqToEntity.UndecorateClosedPosition(order);

                POSITION pos = null;
                try
                {
                    // занести ордер в список закрытых позиций (создать новую запись "истории")
                    ctx.POSITION_CLOSED.Add(posClosed);

                    // удалить открытый ордер
                    pos = ctx.POSITION.FirstOrDefault(p => p.ID == order.ID);
                    if (pos == null)
                    {
                        Logger.ErrorFormat("CloseOrder - позиция {0} не найдена", order.ID);
                        ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(null, RequestStatus.ServerError, "crudsav");

                        return(false);
                    }
                    ctx.POSITION.Remove(pos);

                    // посчитать профиты
                    if (bill != null)
                    {
                        BillingManager.ProcessOrderClosing(order, account, bill, ctx, quotes, brokerRepository.BrokerCurrency);
                    }

                    // сохранить изменения
                    ctx.SaveChanges();

                    // обновить баланс
                    var resultAbs = Math.Abs(order.ResultDepo);
                    if (!UpdateAccountBalance(ctx,
                                              account, (decimal)resultAbs,
                                              order.ResultDepo >= 0
                                                  ? BalanceChangeType.Profit
                                                  : BalanceChangeType.Loss,
                                              string.Format("результат сделки #{0}", posClosed.ID), DateTime.Now, order.ID))
                    {
                        Logger.ErrorFormat("Не удалось применить обновление баланса #{0}", posClosed.ID);
                    }
                }
                catch (OptimisticConcurrencyException ex)
                {
                    Logger.Error("CloseOrder - OptimisticConcurrencyException", ex);
                    ctx.Entry(posClosed).State = EntityState.Modified;
                    ((IObjectContextAdapter)ctx).ObjectContext.Refresh(RefreshMode.ClientWins, posClosed);
                    if (pos != null)
                    {
                        ctx.Entry(pos).State = EntityState.Modified;
                        ((IObjectContextAdapter)ctx).ObjectContext.Refresh(RefreshMode.ClientWins, pos);
                    }
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("Ошибка закрытия позиции {0} (счет #{1}) (фиксация в БД): {2}",
                                       order.ID, order.AccountID, ex);
                    ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(null, RequestStatus.ServerError, "crudsave");
                    return(false);
                }
            }

            // уведомить клиента
            ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(order, RequestStatus.OK, "");

            // разослать торговый сигнал
            MakeOrderClosedSignal(order.AccountID, order.ID, (float)price);

            return(true);
        }
 public RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     throw new NotImplementedException();
 }
Пример #26
0
 public override RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId,
                                                        string ticker, PositionExitReason reason)
 {
     return(proxyTrade.proxy.SendCloseByTickerRequest(ctx, accountId, ticker, reason));
 }
Пример #27
0
 public abstract RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker, PositionExitReason reason);
Пример #28
0
 private static RequestStatus SendCloseByTickerRequestUnsafe(int accountId, string ticker, PositionExitReason reason)
 {
     try
     {
         var res = serverProxyTrade.proxy.SendCloseByTickerRequest(
             CurrentProtectedContext.Instance.MakeProtectedContext(),
             accountId, ticker, reason);
         if (res != RequestStatus.OK)
         {
             Instance.ShowMsgWindowSafe(new AccountEvent(
                                            Localizer.GetString("MessageErrorExecutingOrder"),
                                            EnumFriendlyName <RequestStatus> .GetString(res),
                                            AccountEventCode.ServerMessage));
         }
         return(res);
     }
     catch (Exception ex)
     {
         Logger.Error("SendCloseByTickerRequest", ex);
         return(RequestStatus.NoConnection);
     }
 }
Пример #29
0
 public override RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker, PositionExitReason reason)
 {
     if (IsDayOff())
     {
         return(RequestStatus.WrongTime);
     }
     return(base.SendCloseByTickerRequest(ctx, accountId, ticker, reason));
 }
Пример #30
0
 public RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker,
                                               PositionExitReason reason)
 {
     return(Channel.SendCloseByTickerRequest(ctx, accountId, ticker, reason));
 }
Пример #31
0
 public RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     return(Channel.SendCloseRequest(ctx, accountId, orderId, reason));
 }
Пример #32
0
 private int SendCloseRequestsInner(int[] orderId, PositionExitReason reason, out RequestStatus lastStatus)
 {
     var countOk = 0;
     lastStatus = RequestStatus.OK;
     try
     {
         using (var ctx = DatabaseContext.Instance.Make())
         {
             foreach (var posId in orderId)
             {
                 var pos = ctx.POSITION.FirstOrDefault(p => p.ID == posId);
                 lastStatus = pos == null ? RequestStatus.NotFound : managerTrade.SendCloseRequest(pos, reason);
                 if (lastStatus == RequestStatus.OK)
                     countOk++;
             }
         }
     }
     catch (Exception ex)
     {
         Logger.Error("Ошибка в PlatformManager.SendCloseRequest", ex);
         lastStatus = RequestStatus.ServerError;
     }
     return countOk;
 }
Пример #33
0
 public override RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     return proxyTrade.proxy.SendCloseRequest(ctx, accountId, orderId, reason);
 }
Пример #34
0
 public RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     throw new NotImplementedException();
 }
Пример #35
0
 public override RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId,
                                                        string ticker, PositionExitReason reason)
 {
     return proxyTrade.proxy.SendCloseByTickerRequest(ctx, accountId, ticker, reason);
 }
Пример #36
0
 public RequestStatus SendCloseRequest(int orderId, PositionExitReason reason)
 {
     RequestStatus status;
     SendCloseRequestsInner(new[] { orderId }, reason, out status);
     return status;
 }
Пример #37
0
 public override RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason)
 {
     return(proxyTrade.proxy.SendCloseRequest(ctx, accountId, orderId, reason));
 }
 public RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker,
                                               PositionExitReason reason)
 {
     throw new NotImplementedException();
 }
Пример #39
0
 public abstract RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason);
Пример #40
0
        /// <summary>
        /// Закрытие сделок
        /// </summary>
        /// <param name="strId">Уникальные идентификаторы закрываемых сделок, перечисленные через запятую</param>
        /// <param name="timeExit">Время выхода</param>
        /// <param name="exitReason">Symbol, Side (в виде Ask и Bid), Price</param>
        /// <param name="lstPrice">Причина закрытия сделки, указанная пользователем</param>
        public List <string> ClosingPositions(string strId, DateTime timeExit, PositionExitReason exitReason, List <Tuple <string, int, float> > lstPrice)
        {
            Logger.Info("Начинаем закрывать сделки " + strId);

            var result = new List <string>();
            var id     = strId.ToIntArrayUniform();

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    // Вытаскиваем все открытые сделки, которые нужно закрыть
                    var selOrders = new List <MarketOrder>();
                    // ReSharper disable LoopCanBeConvertedToQuery
                    foreach (var order in ctx.POSITION.Where(x => id.Contains(x.ID)))
                    {
                        selOrders.Add(LinqToEntity.DecorateOrder(order));
                    }
                    // ReSharper restore LoopCanBeConvertedToQuery

                    if (selOrders.Count != id.Length)
                    {
                        Logger.Error("ClosingPositions() - в таблице 'POSITION' не найдены некоторые или все сделки с идентификаторами " + strId);
                    }

                    // Группируем все сделки по счётам
                    var selOrderGroupByAccount = selOrders.GroupBy(x => x.AccountID);

                    // Перебираем все счета
                    foreach (var orderGroup in selOrderGroupByAccount)
                    {
                        // Список удачно закрытых сделок в текущем счёте
                        var successClosedPositions = new List <string>();

                        var acc = accountRepository.GetAccount(orderGroup.Key);
                        if (acc == null)
                        {
                            Logger.Error("ClosingPositions() - не удалось получить счёт " + orderGroup.Key);
                            continue;
                        }

                        Logger.Info("Начинаем закрывать сделки в счёте " + orderGroup.Key);
                        // Перебираем все сделки в текущем счёте
                        foreach (var order in orderGroup)
                        {
                            #region
                            //Ищем цену выхода, указанную пользователем, для сделок с таким тикером и направлением
                            var priceExitTuple = lstPrice.FirstOrDefault(x => x.Item1 == order.Symbol && x.Item2 == order.Side);

                            if (priceExitTuple == null)
                            {
                                Logger.Error(string.Format("ClosingPositions() - не найдена цена выхода, указанная пользователем, для сделок счёта {0} с тикером {1} и направлением {2}",
                                                           order.ID, order.Symbol, order.Side)); continue;
                            }

                            var closedOrder = order.MakeCopy();
                            closedOrder.State      = PositionState.Closed;
                            closedOrder.TimeExit   = timeExit;
                            closedOrder.PriceExit  = priceExitTuple.Item3;
                            closedOrder.ExitReason = exitReason;

                            // посчитать прибыль
                            string errorStr;
                            if (!DealProfitCalculator.CalculateOrderProfit(closedOrder, acc.Currency, priceExitTuple.Item3, out errorStr))
                            {
                                if (!string.IsNullOrEmpty(errorStr))
                                {
                                    Logger.Error("Сделка " + closedOrder.ID + " не будет закрыта - не удалось пересчитать прибыль : " + errorStr);
                                }
                                continue;
                            }

                            var balance = new BALANCE_CHANGE
                            {
                                AccountID   = order.AccountID,
                                ChangeType  = closedOrder.ResultBase > 0 ? (int)BalanceChangeType.Profit : (int)BalanceChangeType.Loss,
                                Description = string.Format("результат сделки #{0}", order.ID),
                                Amount      = (decimal)Math.Abs(closedOrder.ResultDepo),
                                ValueDate   = closedOrder.TimeExit.Value
                            };

                            // убрать сделку из числа открытых, добавить закрытую и добавить проводку по счету
                            try
                            {
                                // убрать
                                var pos = ctx.POSITION.FirstOrDefault(p => p.ID == order.ID);
                                ctx.POSITION.Remove(pos);
                                Logger.Info("запись о сделке " + order.ID + " удалена из таблици POSITION");

                                ctx.POSITION_CLOSED.Add(LinqToEntity.UndecorateClosedPosition(closedOrder));
                                Logger.Info("запись о сделке " + order.ID + " добавленав таблицу POSITION_CLOSED");

                                // добавить проводку по счету
                                ctx.BALANCE_CHANGE.Add(balance);
                                var acBase = ctx.ACCOUNT.FirstOrDefault(ac => ac.ID == order.AccountID);

                                if (acBase == null)
                                {
                                    Logger.Error("ClosingPositions() - не удалось найти счёт " + order.AccountID + " в таблице 'ACCOUNT', что бы добавить проводку");
                                    continue;
                                }

                                acBase.Balance += (decimal)closedOrder.ResultDepo;
                                Logger.Info("Баланс счёта " + order.AccountID + " изменён на величину " + (decimal)closedOrder.ResultDepo);
                            }
                            catch (Exception ex)
                            {
                                Logger.Error("ClosingPositions() - Ошибка при попытке убрать сделку из числа открытых, добавить закрытую и добавить проводку по счету", ex);
                                continue;
                            }
                            #endregion
                            successClosedPositions.Add(order.ID.ToString());
                            Logger.Error("Сделка " + order.ID + " отредактирована удачно");
                        }
                        ReCalculateAccountBalance(ctx, acc.ID);

                        Logger.Info("Начинаем сохранять в базу данных изменения по счёту " + orderGroup.Key);
                        ctx.SaveChanges();
                        result.AddRange(successClosedPositions);
                    }

                    if (result.Count == 0)
                    {
                        Logger.Info("Не удалось закрыть ни одной из указанных сделок");
                    }
                    else
                    {
                        Logger.Info("Изменения сохранены. Из указанных сделок " + strId + " закрыты следующие: " + string.Join(", ", result));
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("ClosingPositions() - возникла ошибка при попытке сохранить изменения в базу данных. Не удалось закрыть сделки " + strId, ex);
            }
            return(result);
        }
Пример #41
0
        private void TryCloseOrder(MarketOrder pos, PositionExitReason reason)
        {
            // проверка - не вызывается ли метод раз за разом для одной и той же позиции,
            // которую невозможно закрыть, например, из-за недостатка свободной маржи
            DateTime lastTime;
            if (orderFloodTimes.TryGetValue(pos.ID, out lastTime))
                if (DateTime.Now < lastTime) return;
            orderFloodTimes.Remove(pos.ID);

            // отправить запрос
            proxyTrade.SendCloseRequest(ProtectedOperationContext.MakeServerSideContext(), pos.AccountID, pos.ID, reason);

            // не допустить забивание потока попытками закрыть позу...
            orderFloodTimes.Add(pos.ID, DateTime.Now.AddMilliseconds(OrderFloodTimeoutMils));
        }
Пример #42
0
        /// <summary>
        /// Закрытие сделок
        /// </summary>
        /// <param name="strId">Уникальные идентификаторы закрываемых сделок, перечисленные через запятую</param>
        /// <param name="timeExit">Время выхода</param>
        /// <param name="exitReason">Symbol, Side (в виде Ask и Bid), Price</param>
        /// <param name="lstPrice">Причина закрытия сделки, указанная пользователем</param>
        public List<string> ClosingPositions(string strId, DateTime timeExit, PositionExitReason exitReason, List<Tuple<string, int, float>> lstPrice)
        {
            Logger.Info("Начинаем закрывать сделки " + strId);

            var result = new List<string>();
            var id = strId.ToIntArrayUniform();
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    // Вытаскиваем все открытые сделки, которые нужно закрыть
                    var selOrders = new List<MarketOrder>();
                    // ReSharper disable LoopCanBeConvertedToQuery
                    foreach (var order in ctx.POSITION.Where(x => id.Contains(x.ID))) selOrders.Add(LinqToEntity.DecorateOrder(order));
                    // ReSharper restore LoopCanBeConvertedToQuery

                    if (selOrders.Count != id.Length)
                        Logger.Error("ClosingPositions() - в таблице 'POSITION' не найдены некоторые или все сделки с идентификаторами " + strId);

                    // Группируем все сделки по счётам
                    var selOrderGroupByAccount = selOrders.GroupBy(x => x.AccountID);

                    // Перебираем все счета
                    foreach (var orderGroup in selOrderGroupByAccount)
                    {
                        // Список удачно закрытых сделок в текущем счёте
                        var successClosedPositions = new List<string>();

                        var acc = accountRepository.GetAccount(orderGroup.Key);
                        if (acc == null)
                        {
                            Logger.Error("ClosingPositions() - не удалось получить счёт " + orderGroup.Key);
                            continue;
                        }

                        Logger.Info("Начинаем закрывать сделки в счёте " + orderGroup.Key);
                        // Перебираем все сделки в текущем счёте
                        foreach (var order in orderGroup)
                        {
                            #region
                            //Ищем цену выхода, указанную пользователем, для сделок с таким тикером и направлением
                            var priceExitTuple = lstPrice.FirstOrDefault(x => x.Item1 == order.Symbol && x.Item2 == order.Side);

                            if (priceExitTuple == null)
                            {
                                Logger.Error(string.Format("ClosingPositions() - не найдена цена выхода, указанная пользователем, для сделок счёта {0} с тикером {1} и направлением {2}",
                                    order.ID, order.Symbol, order.Side)); continue;
                            }

                            var closedOrder = order.MakeCopy();
                            closedOrder.State = PositionState.Closed;
                            closedOrder.TimeExit = timeExit;
                            closedOrder.PriceExit = priceExitTuple.Item3;
                            closedOrder.ExitReason = exitReason;

                            // посчитать прибыль
                            string errorStr;
                            if (!DealProfitCalculator.CalculateOrderProfit(closedOrder, acc.Currency, priceExitTuple.Item3, out errorStr))
                            {
                                if (!string.IsNullOrEmpty(errorStr))
                                    Logger.Error("Сделка " + closedOrder.ID +  " не будет закрыта - не удалось пересчитать прибыль : " + errorStr);
                                continue;
                            }

                            var balance = new BALANCE_CHANGE
                                {
                                    AccountID = order.AccountID,
                                    ChangeType = closedOrder.ResultBase > 0 ? (int)BalanceChangeType.Profit : (int)BalanceChangeType.Loss,
                                    Description = string.Format("результат сделки #{0}", order.ID),
                                    Amount = (decimal)Math.Abs(closedOrder.ResultDepo),
                                    ValueDate = closedOrder.TimeExit.Value
                                };

                            // убрать сделку из числа открытых, добавить закрытую и добавить проводку по счету
                            try
                            {
                                // убрать
                                var pos = ctx.POSITION.FirstOrDefault(p => p.ID == order.ID);
                                ctx.POSITION.Remove(pos);
                                Logger.Info("запись о сделке " + order.ID + " удалена из таблици POSITION");

                                ctx.POSITION_CLOSED.Add(LinqToEntity.UndecorateClosedPosition(closedOrder));
                                Logger.Info("запись о сделке " + order.ID + " добавленав таблицу POSITION_CLOSED");

                                // добавить проводку по счету
                                ctx.BALANCE_CHANGE.Add(balance);
                                var acBase = ctx.ACCOUNT.FirstOrDefault(ac => ac.ID == order.AccountID);

                                if (acBase == null)
                                {
                                    Logger.Error("ClosingPositions() - не удалось найти счёт " + order.AccountID + " в таблице 'ACCOUNT', что бы добавить проводку");
                                    continue;
                                }

                                acBase.Balance += (decimal)closedOrder.ResultDepo;
                                Logger.Info("Баланс счёта " + order.AccountID + " изменён на величину " + (decimal)closedOrder.ResultDepo);
                            }
                            catch (Exception ex)
                            {
                                Logger.Error("ClosingPositions() - Ошибка при попытке убрать сделку из числа открытых, добавить закрытую и добавить проводку по счету", ex);
                                continue;
                            }
                            #endregion
                            successClosedPositions.Add(order.ID.ToString());
                            Logger.Error("Сделка " + order.ID + " отредактирована удачно");
                        }
                        ReCalculateAccountBalance(ctx, acc.ID);

                        Logger.Info("Начинаем сохранять в базу данных изменения по счёту " + orderGroup.Key);
                        ctx.SaveChanges();
                        result.AddRange(successClosedPositions);

                    }

                    if (result.Count == 0)
                        Logger.Info("Не удалось закрыть ни одной из указанных сделок");
                    else
                        Logger.Info("Изменения сохранены. Из указанных сделок " + strId + " закрыты следующие: " + string.Join(", ", result));
                }
            }
            catch (Exception ex)
            {
                Logger.Error("ClosingPositions() - возникла ошибка при попытке сохранить изменения в базу данных. Не удалось закрыть сделки " + strId, ex);
            }
            return result;
        }
Пример #43
0
 public RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker,
                                               PositionExitReason reason)
 {
     throw new NotImplementedException();
 }
Пример #44
0
        public bool CloseOrder(MarketOrder order, decimal price, PositionExitReason exitReason)
        {
            using (var ctx = DatabaseContext.Instance.Make())
            {
                var account = ctx.ACCOUNT.FirstOrDefault(ac => ac.ID == order.AccountID);
                if (account == null)
                {
                    Logger.ErrorFormat("Закрытие ордера #{0}: невозможно прочитать данные счета ({1})",
                                       order.ID, order.AccountID);
                    return false;
                }

                // провести ордер через биллинг
                ORDER_BILL bill = null;
                if (order.State == PositionState.Opened)
                    bill = BillingManager.ProcessPriceForOrderClosing(order, LinqToEntity.DecorateAccount(account), ctx);

                // посчитать результат
                // и обновить объект
                order.State = PositionState.Closed;
                order.PriceExit = (float?)price;
                var deltaAbs = order.Side * (order.PriceExit.Value - order.PriceEnter);
                order.ResultPoints = DalSpot.Instance.GetPointsValue(order.Symbol, deltaAbs);
                var deltaDepo = deltaAbs * order.Volume;
                var quotes = QuoteStorage.Instance.ReceiveAllData();
                string errorStr;
                var resultedDepo = DalSpot.Instance.ConvertToTargetCurrency(order.Symbol, false, account.Currency,
                                                                            deltaDepo, quotes, out errorStr, false);

                if (!resultedDepo.HasValue)
                {
                    Logger.ErrorFormat("#{0} ({1} {2}{3}, {4:f1} пп): ошибка расчета прибыли в валюте депозита - {5}",
                                       order.ID,
                                       order.Side > 0 ? "B" : "S",
                                       order.Symbol,
                                       order.Volume,
                                       order.ResultPoints,
                                       errorStr);
                    return false;
                }
                order.ResultDepo = (float)resultedDepo.Value;
                //order.Swap = (float)swap;
                order.ExitReason = exitReason;
                order.TimeExit = DateTime.Now;
                var posClosed = LinqToEntity.UndecorateClosedPosition(order);

                POSITION pos = null;
                try
                {
                    // занести ордер в список закрытых позиций (создать новую запись "истории")
                    ctx.POSITION_CLOSED.Add(posClosed);

                    // удалить открытый ордер
                    pos = ctx.POSITION.FirstOrDefault(p => p.ID == order.ID);
                    if (pos == null)
                    {
                        Logger.ErrorFormat("CloseOrder - позиция {0} не найдена", order.ID);
                        ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(null, RequestStatus.ServerError, "crudsav");

                        return false;
                    }
                    ctx.POSITION.Remove(pos);

                    // посчитать профиты
                    if (bill != null)
                        BillingManager.ProcessOrderClosing(order, account, bill, ctx, quotes, brokerRepository.BrokerCurrency);

                    // сохранить изменения
                    ctx.SaveChanges();

                    // обновить баланс
                    var resultAbs = Math.Abs(order.ResultDepo);
                    if (!UpdateAccountBalance(ctx,
                        account, (decimal)resultAbs,
                                              order.ResultDepo >= 0
                                                  ? BalanceChangeType.Profit
                                                  : BalanceChangeType.Loss,
                                              string.Format("результат сделки #{0}", posClosed.ID), DateTime.Now, order.ID))
                        Logger.ErrorFormat("Не удалось применить обновление баланса #{0}", posClosed.ID);
                }
                catch (OptimisticConcurrencyException ex)
                {
                    Logger.Error("CloseOrder - OptimisticConcurrencyException", ex);
                    ctx.Entry(posClosed).State = EntityState.Modified;
                    ((IObjectContextAdapter)ctx).ObjectContext.Refresh(RefreshMode.ClientWins, posClosed);
                    if (pos != null)
                    {
                        ctx.Entry(pos).State = EntityState.Modified;
                        ((IObjectContextAdapter)ctx).ObjectContext.Refresh(RefreshMode.ClientWins, pos);
                    }
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("Ошибка закрытия позиции {0} (счет #{1}) (фиксация в БД): {2}",
                        order.ID, order.AccountID, ex);
                    ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(null, RequestStatus.ServerError, "crudsave");
                    return false;
                }
            }

            // уведомить клиента
            ServiceManagerClientManagerProxy.Instance.CloseOrderResponse(order, RequestStatus.OK, "");

            // разослать торговый сигнал
            MakeOrderClosedSignal(order.AccountID, order.ID, (float)price);

            return true;
        }
Пример #45
0
        public RequestStatus SendCloseRequest(MarketOrder order, PositionExitReason reason)
        {
            // получить счет
            RequestStatus error;
            var acDecorated = ServerInterface.GetAccount(order.AccountID);
            if (acDecorated == null) return RequestStatus.ServerError;

            // подготовить запрос
            TradeSharp.ProviderProxyContract.Entity.MarketOrder request;
            if (!MakeMarketRequest(acDecorated, order.Symbol, order.Magic, order.Volume, -order.Side,
                OrderType.Market,
                0, 0,
                string.Format("close order #{0}", order.ID),
                order.ID, order.Comment, order.ExpertComment, order.TrailLevel1, order.TrailTarget1,
                out error, out request)) return error;
            exitReasonByOrderId.UpdateValues(order.ID, reason);

            // отправить запрос на вход в рынок (оно же - закрытие позиции) в соотв сессию
            if (!request.SendToQueue(false))
            {
                errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОшибкаОтправки,
                    "Невозможно отправить сообщение (CloseOrder) в очередь MQ", null));
                return RequestStatus.DealerError;
            }
            return RequestStatus.OK;
        }
Пример #46
0
 /// <summary>
 /// Close position request
 /// </summary>
 protected RequestStatus CloseMarketOrder(int orderId, PositionExitReason reason = PositionExitReason.ClosedByRobot)
 {
     return(robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
                                          robotContext.AccountInfo.ID, orderId, reason));
 }
Пример #47
0
        private void ClosePositionAndCalculateProfit(MarketOrder pos, QuoteData quote, PositionExitReason reason)
        {
            pos.PriceExit = pos.Side < 0 ? quote.ask : quote.bid;

            // убираем проскальзывания на истории
            if (pos.StopLoss != null && pos.StopLoss != 0)
            {
                if ((pos.StopLoss > pos.PriceExit && pos.Side == 1) || (pos.StopLoss < pos.PriceExit && pos.Side == -1))
                {
                    pos.PriceExit = pos.StopLoss;
                }
            }
            else
            if (pos.TakeProfit != null && pos.TakeProfit != 0)
            {
                if ((pos.TakeProfit < pos.PriceExit && pos.Side == 1) || (pos.TakeProfit > pos.PriceExit && pos.Side == -1))
                {
                    pos.PriceExit = pos.TakeProfit;
                }
            }
            pos.TimeExit = curModelTime; //quote.time;
            pos.State    = PositionState.Closed;
            var deltaAbs = pos.Side * (pos.PriceExit.Value - pos.PriceEnter);

            pos.ResultPoints = DalSpot.Instance.GetPointsValue(pos.Symbol, deltaAbs);
            pos.ResultDepo   = (float)profitCalculator.CalculatePositionProfit(pos, AccountInfo.Currency, quotesStorage.ReceiveAllData());
            pos.ResultDepo   = pos.ResultDepo;
            pos.ExitReason   = reason;
            // скорректировать баланс
            AccountInfo.Balance += (decimal)pos.ResultDepo;
            // обновить историю и убрать позицию из списка
            posHistory.Add(pos);
            Positions.Remove(pos);
        }
Пример #48
0
 public abstract RequestStatus SendCloseByTickerRequest(ProtectedOperationContext ctx, int accountId, string ticker, PositionExitReason reason);
Пример #49
0
 /// <summary>
 /// Close position request
 /// </summary>
 protected RequestStatus CloseMarketOrder(int orderId, PositionExitReason reason = PositionExitReason.ClosedByRobot)
 {
     return robotContext.SendCloseRequest(protectedContext.MakeProtectedContext(),
         robotContext.AccountInfo.ID, orderId, reason);
 }
Пример #50
0
 public abstract RequestStatus SendCloseRequest(ProtectedOperationContext ctx, int accountId, int orderId, PositionExitReason reason);