Example #1
0
 private bool GetAccountEquityAndUsedMargin(ACCOUNT account, out decimal equity, out decimal usedMargin)
 {
     try
     {
         decimal exposure;
         profitCalculator.CalculateAccountExposure(account.ID, out equity, out usedMargin, out exposure,
                                                   QuoteStorage.Instance.ReceiveAllData(),
                                                   ManagerAccount.Instance, accountRepository.GetAccountGroup);
         return(true);
     }
     catch (Exception ex)
     {
         equity     = 0;
         usedMargin = 0;
         Logger.ErrorFormat("GetAccountEquityAndUsedMargin({0}) error: {1}", account.ID, ex);
         return(false);
     }
 }
Example #2
0
        public bool IsEnterEnabled(int accountId, string symbol, int side, int volume, out decimal equity)
        {
            Account account;

            equity = 0;

            var status = proxyAccount.GetAccountInfo(accountId, false, out account);

            if (status != RequestStatus.OK || account == null)
            {
                Logger.ErrorFormat("IsEnterEnabled - не удалось получить счет ({0})", accountId);
                return(false);
            }

            var     curPrices = quoteStorage.ReceiveAllData();
            decimal reservedMargin, exposure;
            var     accountExposure = profitCalculator.CalculateAccountExposure(
                accountId, out equity, out reservedMargin,
                out exposure, curPrices, proxyAccount, getAccountGroup);

            account.Equity = equity;
            // посчитать маржу с учетом новой позы
            var smbExp    = accountExposure.ContainsKey(symbol) ? accountExposure[symbol] : 0;
            var smbExpNew = Math.Abs(smbExp + side * volume);

            smbExp = Math.Abs(smbExp);
            if (smbExpNew <= smbExp) // новая поза не увеличивает экспозицию
            {
                return(true);
            }
            // посчитать новую экспозицию
            var deltaExp = (smbExpNew - smbExp);
            // перевести в валюту депо
            string errorStr;
            var    deltaExpDepo = DalSpot.Instance.ConvertToTargetCurrency(symbol, true, account.Currency,
                                                                           (double)deltaExp, curPrices, out errorStr, false);

            if (!deltaExpDepo.HasValue)
            {
                Logger.ErrorFormat("IsEnterEnabled - не удалось конвертировать базовую {0} в депо {1}",
                                   symbol, account.Currency);
                return(false);
            }

            var newExp = deltaExpDepo.Value + exposure;
            // проверить маржинальные требования
            var group       = getAccountGroup(account.ID);
            var deltaMargin = deltaExp / (decimal)group.BrokerLeverage;
            var newMargin   = deltaMargin + reservedMargin;
            var margPercent = equity == 0 ? 100 : 100 * newMargin / equity;

            if (margPercent >= (decimal)group.MarginCallPercentLevel)
            {
                Logger.InfoFormat("Счет {0}: запрос на {1} {2} {3} превышает марж. требования ({4:f2} из {5:f2})",
                                  accountId, side > 0 ? "BUY" : "SELL", volume, symbol, margPercent, group.MarginCallPercentLevel);
                Logger.InfoFormat("{0:f1} {1:f1} {2:f1} {3:f1} {4:f1} {5} {6:f1} {7:f1}",
                                  smbExp, smbExpNew, deltaExp, exposure,
                                  equity, accountExposure.Count, deltaMargin, account.Balance);
                return(false);
            }
            // окончательно - проверить макс. плечо
            if (equity == 0 || account.MaxLeverage == 0)
            {
                return(true);
            }
            var newLeverage = newExp / equity;

            if (newLeverage < (decimal)account.MaxLeverage)
            {
                return(true);
            }
            Logger.InfoFormat("Превышение плеча ({0} при допустимом {1})", newLeverage, account.MaxLeverage);
            return(false);
        }
        /// <summary>
        /// проверить маржин колл - стопаут
        /// </summary>
        private void CheckMargin()
        {
            if (!WorkingDay.Instance.IsWorkingDay(DateTime.Now))
            {
                return;
            }
            var curPrices = QuoteStorage.Instance.ReceiveAllData();

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    foreach (var group in ctx.ACCOUNT_GROUP)
                    {
                        // проверка каждого счета
                        foreach (var account in group.ACCOUNT)
                        {
                            decimal reservedMargin, equity;
                            try
                            {
                                decimal exposure;
                                profitCalculator.CalculateAccountExposure(account.ID,
                                                                          out equity, out reservedMargin, out exposure, curPrices,
                                                                          ManagerAccount.Instance, accountRepository.GetAccountGroup);
                            }
                            catch (Exception ex)
                            {
                                loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Error,
                                                                         LogMagicExposureCheck, 60 * 1000,
                                                                         "Ошибка при расчете маржи/средств счета {0}: {1}",
                                                                         account.ID, ex);
                                break;
                            }
                            // посчитать отношение reservedMargin / equity, %
                            var expLevel = equity == 0 ? 0 :
                                           (equity < 0 && reservedMargin != 0) ? 100
                                : 100 * reservedMargin / equity;
                            var isMc = expLevel >= group.MarginCallPercentLevel;
                            var isSo = expLevel >= group.StopoutPercentLevel;
                            // стопаут!
                            if (isSo)
                            {
                                if (ShouldLogStopout(account.ID))
                                {
                                    Logger.InfoFormat("Стопаут для счета {0}: нач. маржа={1:f0}, средства={2:f0}, предел={3:f1}%",
                                                      account.ID, reservedMargin, equity, group.StopoutPercentLevel);
                                }
                                PerformStopout(account, curPrices, ctx);
                                continue;
                            }
                            if (!isMc)
                            {
                                continue;
                            }
                            loggerNoFlood.LogMessageFormatCheckFlood(LogEntryType.Error,
                                                                     LogMagicMarginCall,
                                                                     30 * 60 * 1000,
                                                                     "МК для счета {0}: нач. маржа={1:f0}, средства={2:f0}, предел={3:f1}%",
                                                                     account.ID, reservedMargin, equity, group.MarginCallPercentLevel);
                            PerformMarginCall(account);
                            //continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в CheckMargin", ex);
            }
        }