public bool UpdateAccountBalance(TradeSharpConnection ctx,
                                         ACCOUNT account, decimal amount, BalanceChangeType changeType,
                                         string description, DateTime valueDate, int?positionId)
        {
            var bc = new BALANCE_CHANGE
            {
                AccountID   = account.ID,
                Amount      = amount,
                ChangeType  = (int)changeType,
                Description = description,
                ValueDate   = valueDate,
                Position    = positionId
            };

            try
            {
                ctx.BALANCE_CHANGE.Add(bc);
                account.Balance += ((changeType == BalanceChangeType.Deposit ||
                                     changeType == BalanceChangeType.Profit) ? amount : -amount);
                ctx.SaveChanges();
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("Ошибка обновления баланса счета {0} на сумму {1}: {2}",
                                   account.ID, amount, ex);
                return(false);
            }
        }
Beispiel #2
0
        private static void CorrectBalance(int acId, decimal deltaAmount, TradeSharpConnection conn)
        {
            // поправить депозит
            var bc = new BALANCE_CHANGE
            {
                AccountID   = acId,
                ValueDate   = DateTime.Now,
                Amount      = deltaAmount,
                ChangeType  = (int)BalanceChangeType.Withdrawal,
                Description = "public offering"
            };

            conn.BALANCE_CHANGE.Add(bc);
            conn.SaveChanges();
            var userId = conn.PLATFORM_USER_ACCOUNT.First(a => a.Account == acId).PlatformUser;
            var tr     = new TRANSFER
            {
                ValueDate     = bc.ValueDate,
                BalanceChange = bc.ID,
                Amount        = -deltaAmount,
                Comment       = "public offering",
                User          = userId,
                TargetAmount  = -deltaAmount
            };

            conn.TRANSFER.Add(tr);
        }
Beispiel #3
0
        public RequestStatus ChangeBalance(int accountId, decimal summ, string comment, DateTime date, BalanceChangeType changeType)
        {
            if (summ == 0)
            {
                return(RequestStatus.BadRequest);
            }
            // корректировать знак
            summ = BalanceChange.CorrectSign(summ, changeType);

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    ACCOUNT acc;
                    try
                    {
                        acc = (from a in ctx.ACCOUNT
                               where a.ID == accountId
                               select a).First();
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Ошибка получения счета для редактирования {0}: {1}", accountId, ex);
                        return(RequestStatus.ServerError);
                    }

                    var bc = new BALANCE_CHANGE
                    {
                        AccountID   = accountId,
                        ValueDate   = date,
                        Amount      = summ,
                        ChangeType  = (int)changeType,
                        Description = comment
                    };
                    try
                    {
                        acc.Balance = acc.Balance + summ;
                        ctx.BALANCE_CHANGE.Add(bc);
                        ctx.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Ошибка изменения баланса счета {0}: {1}", accountId, ex);
                        return(RequestStatus.ServerError);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в ChangeBalance", ex);
                return(RequestStatus.ServerError);
            }
            return(RequestStatus.OK);
        }
        private BALANCE_CHANGE MakeSwapTransfer(decimal amountCounter, string ticker, string curxDepo,
                                                Dictionary <string, QuoteData> quotes,
                                                int posId, int accountId, DateTime nowTime)
        {
            var  amountDepo = amountCounter;
            bool inverse, equalPairs;
            var  symbol = DalSpot.Instance.FindSymbol(ticker, false, curxDepo, out inverse, out equalPairs);

            if (!equalPairs)
            {
                if (string.IsNullOrEmpty(symbol))
                {
                    Logger.Error("MakeSwapTransfer - не найден тикер пересчета " + ticker + " в " + curxDepo);
                    return(null);
                }

                QuoteData quote;
                if (!quotes.TryGetValue(symbol, out quote))
                {
                    Logger.ErrorFormat("Начисление свопа поз. {0} ({1}) - нет котировки {2}",
                                       posId, ticker, symbol);
                    return(null);
                }
                var price = inverse
                                    ? (amountDepo < 0 ? 1 / quote.bid : 1 / quote.ask)
                                    : (amountDepo < 0 ? quote.ask : quote.bid);
                amountDepo *= (decimal)price;
            }

            var transfer = new BALANCE_CHANGE
            {
                Amount      = amountDepo,
                AccountID   = accountId,
                ChangeType  = (int)BalanceChangeType.Swap,
                ValueDate   = nowTime,
                Description = "swap " + posId,
                Position    = posId
            };

            return(transfer);
        }
Beispiel #5
0
        /// <summary>
        /// Метод пересчитывает баланс во всех операциях, кроме закрытия или отмены сделок
        /// </summary>
        public void UpdateBalanceChange(TradeSharpConnection ctx, MarketOrder closedPos, bool deleteTransferOnly)
        {
            // поправить трансфер по счету и баланс
            var dealDescr = string.Format("{1} #{0}", closedPos.ID, Resource.TitleMarketOrderResult);
            var trans     = ctx.BALANCE_CHANGE.FirstOrDefault(c => c.AccountID == closedPos.AccountID &&
                                                              (c.ChangeType ==
                                                               (int)BalanceChangeType.Profit ||
                                                               c.ChangeType ==
                                                               (int)BalanceChangeType.Loss) && c.Description.Equals(dealDescr, StringComparison.OrdinalIgnoreCase));

            if (deleteTransferOnly)
            {
                if (trans == null)
                {
                    return;
                }
                ctx.BALANCE_CHANGE.Remove(trans);
            }
            else
            {
                // изменить или добавить перевод
                if (trans == null)
                {
                    trans = new BALANCE_CHANGE {
                        Description = dealDescr, AccountID = closedPos.AccountID
                    };
                    ctx.BALANCE_CHANGE.Add(trans);
                }
                trans.Amount     = (decimal)Math.Abs(closedPos.ResultDepo);
                trans.ChangeType = closedPos.ResultDepo > 0
                                       ? (int)BalanceChangeType.Profit
                                       : (int)BalanceChangeType.Loss;
                if (closedPos.TimeExit != null)
                {
                    trans.ValueDate = closedPos.TimeExit.Value;
                }
            }

            //ctx.BALANCE_CHANGE.ApplyCurrentValues(trans);
            ctx.SaveChanges();
        }
Beispiel #6
0
        private void ZeroBalance(ACCOUNT ac, TradeSharpConnection ctx)
        {
            if (ac.Balance == 0)
            {
                return;
            }

            var valueDate = DateTime.Now;
            var amount    = ac.Balance;

            ac.Balance = 0;

            var bc = new BALANCE_CHANGE
            {
                AccountID   = ac.ID,
                Amount      = amount,
                ChangeType  = (int)BalanceChangeType.Withdrawal,
                Description = "closing account",
                ValueDate   = valueDate
            };

            ctx.BALANCE_CHANGE.Add(bc);
            ctx.SaveChanges();
        }
        public ActionResult ChangeBalance(BalanceChangeRequest bc)
        {
            Logger.InfoFormat("Начинаем пополнять счёт {0}", bc.AccountId);
            var errors = new List <string>();

            if (bc.Amount <= 0)
            {
                errors.Add(Resource.ErrorMessageAmountMustBePositive);
            }
            var date = bc.ValueDate.ToDateTimeUniformSafe();

            if (!date.HasValue)
            {
                errors.Add(string.Format("{0} {1}", Resource.ErrorMessageUnableParseDateTime, Resource.TextExampleCorrectFillDateTime));
            }

            if (!string.IsNullOrEmpty(bc.Description) && bc.Description.Length > 60)
            {
                bc.Description = bc.Description.Substring(0, 60);
            }

            if (errors.Count > 0)
            {
                Logger.Error(string.Format("Не удалось пополнить счет {0}", bc.AccountId) + string.Join(", ", errors));
                return(Json(new
                {
                    status = false,
                    errorString = Resource.ErrorMessage + ": " + string.Join(", ", errors)
                }, JsonRequestBehavior.AllowGet));
            }

            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var bal = new BALANCE_CHANGE
                    {
                        AccountID = bc.AccountId,
                        Amount    = (decimal)bc.Amount,
                        // ReSharper disable PossibleInvalidOperationException
                        ChangeType = (int)bc.ChangeType,
                        // ReSharper restore PossibleInvalidOperationException
                        ValueDate   = date.Value,
                        Description = bc.Description
                    };
                    ctx.BALANCE_CHANGE.Add(bal);
                    var account = ctx.ACCOUNT.First(a => a.ID == bc.AccountId);
                    account.Balance +=
                        new BalanceChange
                    {
                        ChangeType         = bc.ChangeType,
                        Amount             = (decimal)bc.Amount,
                        CurrencyToDepoRate = 1
                    }.SignedAmountDepo;
                    ctx.SaveChanges();
                }

                Logger.InfoFormat("Счёт {0} пополнен", bc.AccountId);
                return(Json(new
                {
                    status = true,
                    errorString = ""
                }, JsonRequestBehavior.AllowGet));
            }
            catch (Exception ex)
            {
                Logger.Error(string.Format("Не удалось пополнить счет {0}", bc.AccountId) + string.Join(", ", errors));
                return(Json(new
                {
                    status = false,
                    errorString = Resource.ErrorMessage + ": " + ex.Message
                }, JsonRequestBehavior.AllowGet));
            }
        }
Beispiel #8
0
        private string CreateAccount(out int accountId)
        {
            accountId = -1;
            if (string.IsNullOrEmpty(tbLogin.Text) ||
                string.IsNullOrEmpty(tbEmail.Text) ||
                string.IsNullOrEmpty(tbPassword.Text) ||
                cbAccountGroup.SelectedIndex < 0)
            {
                return("Поля не заполнены");
            }

            var login      = tbLogin.Text;
            var password   = tbPassword.Text;
            var email      = tbEmail.Text;
            var group      = cbAccountGroup.SelectedItem.ToString();
            var depo       = tbStartDepo.Text.ToDecimalUniformSafe() ?? 0;
            var createTime = dpCreateTime.Value;

            using (var conn = DatabaseContext.Instance.Make())
            {
                if (conn.PLATFORM_USER.Any(u => u.Login == login))
                {
                    return("Логин занят");
                }
                if (conn.PLATFORM_USER.Any(u => u.Email == email))
                {
                    return("Email занят");
                }

                try
                {
                    var usr = new PLATFORM_USER
                    {
                        Login            = login,
                        Password         = password,
                        Email            = email,
                        Name             = tbName.Text,
                        Surname          = tbSurname.Text,
                        RegistrationDate = createTime,
                        RoleMask         = 0,
                        Patronym         = "Н",
                        Title            = "-"
                    };
                    conn.PLATFORM_USER.Add(usr);
                    var account = new ACCOUNT
                    {
                        Currency     = "USD",
                        Balance      = depo,
                        MaxLeverage  = tbMaxLeverage.Text.ToDecimalUniformSafe() ?? 100,
                        AccountGroup = group,
                        TimeCreated  = createTime,
                        Status       = (int)Account.AccountStatus.Created
                    };
                    conn.ACCOUNT.Add(account);
                    conn.SaveChanges();
                    var pa = new PLATFORM_USER_ACCOUNT
                    {
                        PlatformUser = usr.ID,
                        Account      = account.ID,
                        RightsMask   = 0
                    };
                    conn.PLATFORM_USER_ACCOUNT.Add(pa);

                    var bc = new BALANCE_CHANGE
                    {
                        AccountID   = account.ID,
                        Amount      = depo,
                        ChangeType  = (int)BalanceChangeType.Deposit,
                        Description = "Initial deposit",
                        ValueDate   = createTime
                    };
                    conn.BALANCE_CHANGE.Add(bc);
                    conn.SaveChanges();
                    accountId = account.ID;
                    return(string.Empty);
                }
                catch (Exception ex)
                {
                    return(ex.GetType().Name + ": " + ex.Message);
                }
            }
        }
Beispiel #9
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);
        }
        public static List <string> CorrectBalance(List <int> actIds, int minAmount, int maxAmount, int maxDelta)
        {
            var rand     = new Random();
            var messages = new List <string>();

            foreach (var acId in actIds)
            {
                var accountId    = acId;
                var targetAmount = rand.Next(minAmount, maxAmount);
                using (var conn = DatabaseContext.Instance.Make())
                {
                    var sumDeltaBalance = conn.BALANCE_CHANGE.Where(b => b.AccountID == accountId).Sum(b =>
                                                                                                       (b.ChangeType == (int)BalanceChangeType.Loss ||
                                                                                                        b.ChangeType == (int)BalanceChangeType.Withdrawal)
                            ? -b.Amount
                            : b.Amount);
                    var accountBalance = conn.ACCOUNT.Where(a => a.ID == accountId).Select(a => a.Balance).First();
                    if (accountBalance != sumDeltaBalance)
                    {
                        var acc = conn.ACCOUNT.First(a => a.ID == accountId);
                        acc.Balance = sumDeltaBalance;
                    }

                    var delta = Math.Abs(targetAmount - sumDeltaBalance);
                    if (delta > maxDelta)
                    {
                        // пополнить - вывести
                        var amount = targetAmount - sumDeltaBalance;
                        var bc     = new BALANCE_CHANGE
                        {
                            AccountID  = accountId,
                            ChangeType =
                                amount > 0 ? (int)BalanceChangeType.Deposit : (int)BalanceChangeType.Withdrawal,
                            Description = amount > 0 ? "rebalance (depo)" : "rebalance (wdth)",
                            ValueDate   = DateTime.Now,
                            Amount      = delta
                        };
                        conn.BALANCE_CHANGE.Add(bc);
                        conn.SaveChanges();

                        var ownerId = (from pa in conn.PLATFORM_USER_ACCOUNT
                                       join a in conn.ACCOUNT on pa.Account equals a.ID
                                       select pa.PlatformUser).First();

                        // проводка
                        var trans = new TRANSFER
                        {
                            Amount        = delta,
                            ValueDate     = DateTime.Now,
                            TargetAmount  = delta,
                            BalanceChange = bc.ID,
                            Comment       = bc.Description,
                            User          = ownerId
                        };
                        conn.TRANSFER.Add(trans);

                        messages.Add(string.Format("#{0}: {1} -> {2} USD",
                                                   accountId, sumDeltaBalance.ToStringUniformMoneyFormat(),
                                                   targetAmount.ToStringUniformMoneyFormat()));
                    }
                    else
                    {
                        messages.Add(string.Format("#{0}: {1} USD",
                                                   accountId, sumDeltaBalance.ToStringUniformMoneyFormat()));
                    }
                    conn.SaveChanges();
                }
            }

            return(messages);
        }
Beispiel #11
0
        private static void SaveTrackInDatabase(RobotContextBacktest context, int accountId,
                                                List <BalanceChange> transfers,
                                                int transfersInDbCount)
        {
            try
            {
                Logger.InfoFormat("Сохранение изменений в БД для счета {0}", accountId);

                int nextPosId;
                using (var conn = DatabaseContext.Instance.Make())
                {
                    nextPosId = Math.Max(conn.POSITION.Max(p => p.ID), conn.POSITION_CLOSED.Max(p => p.ID)) + 1;
                }

                Logger.InfoFormat("Запись {0} позиций для счета {1}",
                                  context.PosHistory.Count, accountId);

                // закрытые ордера
                var listPos = new List <POSITION_CLOSED>();
                foreach (var pos in context.PosHistory)
                {
                    var orderClosed = LinqToEntity.UndecorateClosedPosition(pos);
                    orderClosed.ID = ++nextPosId;
                    listPos.Add(orderClosed);
                }

                using (var conn = DatabaseContext.Instance.Make())
                {
                    conn.BulkInsert(listPos);
                    conn.SaveChanges();
                }

                // трансферы...
                var listTrans =
                    transfers.Skip(transfersInDbCount).Select(t =>
                                                              new BALANCE_CHANGE
                {
                    AccountID  = accountId,
                    Amount     = t.Amount,
                    ChangeType = (int)t.ChangeType,
                    ValueDate  = t.ValueDate,
                }).ToList();
                // + трансферы по закрытым ордерам
                foreach (var pos in listPos)
                {
                    var transfer = new BALANCE_CHANGE
                    {
                        AccountID  = accountId,
                        Amount     = Math.Abs(pos.ResultDepo),
                        ChangeType = (int)(pos.ResultDepo >= 0
                            ? BalanceChangeType.Profit
                            : BalanceChangeType.Loss),
                        ValueDate = pos.TimeExit,
                        Position  = pos.ID,
                    };
                    listTrans.Add(transfer);
                }

                using (var conn = DatabaseContext.Instance.Make())
                {
                    conn.BulkInsert(listTrans);
                    conn.SaveChanges();
                }

                // открытые сделки - как есть
                using (var conn = DatabaseContext.Instance.Make())
                {
                    foreach (var pos in context.Positions)
                    {
                        var orderOpened = LinqToEntity.UndecorateOpenedPosition(pos);
                        orderOpened.ID = ++nextPosId;
                        conn.POSITION.Add(orderOpened);
                    }

                    conn.SaveChanges();
                }
                Logger.InfoFormat("Сохранение успешно для счета {0}: {1} сделок сохранено",
                                  accountId, context.PosHistory.Count + context.Positions.Count);
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка сохранения трека пользователя в БД", ex);
            }
        }
Beispiel #12
0
        private ACCOUNT GetAccountData(int accountId, out List <BalanceChange> transfers)
        {
            if (testOnly)
            {
                transfers = new List <BalanceChange>
                {
                    new BalanceChange
                    {
                        AccountID  = accountId,
                        Amount     = startDepo,
                        ChangeType = BalanceChangeType.Deposit,
                        Currency   = "USD",
                        ValueDate  = startTime
                    }
                };

                return(new ACCOUNT
                {
                    ID = accountId,
                    Balance = startDepo,
                    Currency = "USD",
                    AccountGroup = "Demo",
                    TimeCreated = startTime
                });
            }

            ACCOUNT accountData;

            try
            {
                using (var conn = DatabaseContext.Instance.Make())
                {
                    accountData = conn.ACCOUNT.First(a => a.ID == accountId);
                    transfers   = conn.BALANCE_CHANGE.Where(bc =>
                                                            bc.AccountID == accountId).ToList().Select(LinqToEntity.DecorateBalanceChange).ToList();
                    if (transfers.Count == 0)
                    {
                        // добавить начальное пополнение счета
                        var firstBc = new BALANCE_CHANGE
                        {
                            AccountID   = accountId,
                            ValueDate   = accountData.TimeCreated,
                            ChangeType  = (int)BalanceChangeType.Deposit,
                            Description = "initial depo",
                            Amount      = startDepo
                        };
                        conn.BALANCE_CHANGE.Add(firstBc);
                        conn.SaveChanges();

                        var pa = conn.PLATFORM_USER_ACCOUNT.First(p => p.Account == accountId);

                        var trans = new TRANSFER
                        {
                            Amount        = firstBc.Amount,
                            ValueDate     = firstBc.ValueDate,
                            BalanceChange = firstBc.ID,
                            Comment       = "initial depo",
                            TargetAmount  = firstBc.Amount,
                            User          = pa.PlatformUser
                        };
                        conn.TRANSFER.Add(trans);
                        conn.SaveChanges();
                        transfers.Add(LinqToEntity.DecorateBalanceChange(firstBc));
                    }
                }
                return(accountData);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("Error in GetAccountData({0}): {1}", accountId, ex);
                throw;
            }
        }
        public bool SetBalance(string hash, string userLogin, long localTime,
                               int accountId, decimal newBalance, string comment, out string errorString)
        {
            errorString = string.Empty;
            try
            {
                using (var ctx = DatabaseContext.Instance.Make())
                {
                    var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == userLogin);
                    if (user == null)
                    {
                        errorString = "Unauthorised (not found)";
                        return(false);
                    }

                    var userHash = CredentialsHash.MakeCredentialsHash(userLogin, user.Password, localTime);
                    if (userHash != hash)
                    {
                        errorString = "Unauthorised (wrong credentials)";
                        return(false);
                    }

                    if (!PlatformUser.IsAdmin(user.RoleMask) &&
                        !PlatformUser.IsManager(user.RoleMask))
                    {
                        errorString = "Unauthorised (insufficient rights)";
                        return(false);
                    }

                    var account = ctx.ACCOUNT.FirstOrDefault(a => a.ID == accountId);
                    if (account == null)
                    {
                        errorString = "Account " + accountId + " was not found";
                        return(false);
                    }

                    var delta = newBalance - account.Balance;
                    if (delta == 0)
                    {
                        return(true);
                    }

                    // сформировать транзакцию и поправить баланс
                    var sign   = Math.Sign(delta);
                    var amount = Math.Abs(delta);
                    var trans  = new BALANCE_CHANGE
                    {
                        AccountID   = accountId,
                        ChangeType  = sign > 0 ? (int)BalanceChangeType.Deposit : (int)BalanceChangeType.Withdrawal,
                        Amount      = amount,
                        ValueDate   = DateTime.Now,
                        Description = comment
                    };
                    account.Balance = newBalance;
                    ctx.BALANCE_CHANGE.Add(trans);
                    ctx.SaveChanges();
                    return(true);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в SetBalance()", ex);
            }
            return(false);
        }
Beispiel #14
0
        public AccountRegistrationStatus RegisterAccount(PlatformUser user,
                                                         string accountCurrency, int startBalance, decimal maxLeverage, string completedPassword, bool autoSignIn)
        {
            // проверить заполнение логина-почты-баланса-плеча
            if (user.Login.Length < PlatformUser.LoginLenMin ||
                user.Login.Length > PlatformUser.LoginLenMax)
            {
                return(AccountRegistrationStatus.IncorrectLogin);
            }
            if (user.Email.Length < PlatformUser.EmailLenMin ||
                user.Email.Length > PlatformUser.EmailLenMax)
            {
                return(AccountRegistrationStatus.IncorrectEmail);
            }
            if (!PlatformUser.CheckLoginSpelling(user.Login))
            {
                return(AccountRegistrationStatus.IncorrectLogin);
            }
            if (startBalance < Account.MinimumStartDepo || startBalance > Account.MaximumStartDepo)
            {
                return(AccountRegistrationStatus.IncorrectBalance);
            }
            if (maxLeverage < 0)
            {
                maxLeverage = 0;
            }
            else if (maxLeverage > Account.MaximumDepoLeverage)
            {
                maxLeverage = Account.MaximumDepoLeverage;
            }
            long hash;

            if (!TradingContractDictionary.Instance.GetTickers(out hash).Any(c => c.ActiveBase == accountCurrency ||
                                                                             c.ActiveCounter == accountCurrency))
            {
                return(AccountRegistrationStatus.WrongCurrency);
            }

            // сгенерировать пароль
            if (string.IsNullOrEmpty(completedPassword))
            {
                string pwrd;
                while (true)
                {
                    pwrd = RandomWordGenerator.Password(new Random().Next(2) + 2);
                    if (pwrd.Length < PlatformUser.PasswordLenMin || pwrd.Length > PlatformUser.PasswordLenMax)
                    {
                        continue;
                    }
                    break;
                }
                user.Password = pwrd;
            }
            else
            {
                user.Password = completedPassword;
            }
            user.RegistrationDate = DateTime.Now;
            Logger.InfoFormat("RegisterAccount (email={0}, login={1}, pwrd={2}{3})",
                              user.Email, user.Login, user.Password, string.IsNullOrEmpty(completedPassword) ? " (auto)" : "");
            if (string.IsNullOrEmpty(user.Title))
            {
                user.Title = string.IsNullOrEmpty(user.Name) ? user.Login : user.Name;
            }
            user.RoleMask = UserRole.Trader;

            // попытка создать пользователя и открыть счет
            using (var ctx = DatabaseContext.Instance.Make())
            {
                try
                {
                    // проверка дублирования
                    var existUser = ctx.PLATFORM_USER.FirstOrDefault(u => u.Email.Equals(user.Email, StringComparison.OrdinalIgnoreCase));
                    Logger.InfoFormat("Регистрация пользователя: email {0} занят", user.Email);
                    if (existUser != null)
                    {
                        return(AccountRegistrationStatus.DuplicateEmail);
                    }
                    existUser = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == user.Login);
                    if (existUser != null)
                    {
                        return(AccountRegistrationStatus.DuplicateLogin);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error("Ошибка в RegisterAccount(checks)", ex);
                    return(AccountRegistrationStatus.ServerError);
                }

                // в рамках одной транзакции создать логин и счет
                //using (var transaction = ctx.Connection.BeginTransaction())
                {
                    DbTransaction transaction;
                    try
                    {
                        if (((IObjectContextAdapter)ctx).ObjectContext.Connection.State != ConnectionState.Open)
                        {
                            ((IObjectContextAdapter)ctx).ObjectContext.Connection.Open();
                        }
                        Logger.Info("Connection's opened");
                        transaction = ((IObjectContextAdapter)ctx).ObjectContext.Connection.BeginTransaction();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("RegisterAccount - ошибка в ctx.Connection.BeginTransaction", ex);
                        return(AccountRegistrationStatus.ServerError);
                    }

                    try
                    {
                        // добавить пользователя
                        var userBase = LinqToEntity.UndecoratePlatformUser(user);
                        ctx.PLATFORM_USER.Add(userBase);

                        // добавить счет
                        var account = new ACCOUNT
                        {
                            AccountGroup = defaultDemoAccountGroupCode,
                            MaxLeverage  = maxLeverage,
                            Balance      = startBalance,
                            UsedMargin   = 0,
                            Currency     = accountCurrency,
                            Description  = string.Format("demo account for {0}", user.Login),
                            Status       = (int)Account.AccountStatus.Created,
                            TimeCreated  = DateTime.Now,
                        };
                        try
                        {
                            ctx.ACCOUNT.Add(account);
                            // сохранить изменения (добавление пользователя и счета, нужны ID)
                            ctx.SaveChanges();
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("RegisterAccount - ACCOUNT adding error", ex);
                            return(AccountRegistrationStatus.ServerError);
                        }


                        // добавить кошелек
                        try
                        {
                            var wallet = new WALLET
                            {
                                Balance  = 0,
                                Currency = accountCurrency,
                                Password = user.Password,
                                User     = userBase.ID
                            };
                            ctx.WALLET.Add(wallet);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("RegisterAccount - WALLET adding error", ex);
                            return(AccountRegistrationStatus.ServerError);
                        }

                        // пользователь-счет
                        var userAccount = new PLATFORM_USER_ACCOUNT
                        {
                            PlatformUser = userBase.ID,
                            Account      = account.ID,
                            RightsMask   = (int)AccountRights.Управление
                        };
                        ctx.PLATFORM_USER_ACCOUNT.Add(userAccount);

                        // перевод на счет
                        var trans = new BALANCE_CHANGE
                        {
                            ValueDate   = DateTime.Now,
                            AccountID   = account.ID,
                            Amount      = startBalance,
                            ChangeType  = (int)BalanceChangeType.Deposit,
                            Description = "initial deposit"
                        };
                        ctx.BALANCE_CHANGE.Add(trans);

                        // сделать сигнальщиком
                        if (makeNewlyAddedUsersSignallers)
                        {
                            MakeNewlyRegisteredAccountSignaller(ctx, userBase, account);
                        }

                        // сохранить все изменения
                        ctx.SaveChanges();
                        if (string.IsNullOrEmpty(completedPassword))
                        {
                            if (!SendEmailOnNewAccount(user, true))
                            {
                                transaction.Rollback();
                                return(AccountRegistrationStatus.EmailDeliveryError);
                            }
                        }

                        transaction.Commit();
                        ((IObjectContextAdapter)ctx).ObjectContext.Connection.Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Ошибка в RegisterAccount (login={0}, email={1}) : {2}",
                                           user.Login, user.Email, ex);
                        transaction.Rollback();
                        ((IObjectContextAdapter)ctx).ObjectContext.Connection.Close();
                        return(AccountRegistrationStatus.ServerError);
                    }
                } // using (transaction ...
            }
            return(AccountRegistrationStatus.OK);
        }