Esempio n. 1
0
        /// <summary>
        /// добавить маркапы и прочее шкурилово
        /// </summary>
        public static void ProcessOrderClosing(MarketOrder order,
                                               ACCOUNT account,
                                               ORDER_BILL bill,
                                               TradeSharpConnection ctx,
                                               Dictionary <string, QuoteData> quotes, string brokerCurrency)
        {
            //Logger.Info("BillingManager.ProcessOrderClosing()");
            try
            {
                // перевести маркапы в валюту брокера
                var markupSum = bill.MarkupExit + bill.MarkupEnter;
                // в контрвалюте...
                if (markupSum != 0)
                {
                    markupSum = order.Volume * markupSum;
                }
                Logger.Info("BillingManager: markupSum is " + markupSum);

                // перевести в валюту брокера
                var resultCounter   = order.Side * order.Volume * (order.PriceExit.Value - order.PriceEnter);
                var rateCounterDepo = resultCounter == 0 ? 1 : order.ResultDepo / resultCounter;
                // валюта брокера к контрвалюте
                var rateCounterBroker = rateCounterDepo;
                Logger.Info("BillingManager: rateCounterDepo is " + rateCounterDepo);

                if (account.Currency != brokerCurrency)
                {
                    // пример: позиция EURCAD, валюта брокера USD
                    // надо получить курс CADUSD
                    var    markupBroker = (float)markupSum;
                    string errorStr;
                    var    resultedMarkup = DalSpot.Instance.ConvertToTargetCurrency(order.Symbol, false, brokerCurrency,
                                                                                     markupBroker, quotes, out errorStr, true);

                    if (!resultedMarkup.HasValue)
                    {
                        Logger.ErrorFormat("BillingManager.ProcessOrderClosing - невозможно перевести профит по {0} в {1}: {2}",
                                           order.Symbol, brokerCurrency, errorStr);
                        return;
                    }
                    markupBroker      = (float)resultedMarkup.Value;
                    rateCounterBroker = (float)(markupBroker / markupSum);
                    markupSum         = markupBroker;
                }
                else
                {
                    markupSum *= rateCounterBroker;
                }
                bill.MarkupBroker = markupSum;
                bill.ProfitBroker = resultCounter * rateCounterBroker;
                Logger.InfoFormat("BillingManager: MarkupBroker: {0}, ProfitBroker: {1}",
                                  bill.MarkupBroker, bill.ProfitBroker);

                // сохранить билль
                ctx.Entry(bill).State = EntityState.Modified;
                Logger.InfoFormat("BillingManager:OK");
            }
            catch (Exception ex)
            {
                Logger.Error("BillingManager.ProcessOrderClosing() - ошибка редактирования счета", ex);
            }
        }
Esempio n. 2
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);
        }