public static Wallet DecorateWallet(WALLET walInf) { var wallet = new Wallet { Balance = walInf.Balance, Currency = walInf.Currency, User = walInf.User, Password = walInf.Password }; return(wallet); }
private void btnCreate_Click(object sender, EventArgs e) { var users = MakeUsersWithNames(); if (users.Count == 0) { MessageBox.Show("Пользователи не созданы (нет записей)"); return; } accountIds.Clear(); var depoPercentiles = tbStartDepo.Text.ToIntArrayUniform(); // каждого занести в БД // для каждого завести кошелек, положить немного денег // завести каждому счет // опционально - завести каждому сигнальный сервис var group = (string) cbGroup.SelectedItem; const int moneyOnWallet = 1250; var currency = tbCurrency.Text; var signalPrice = tbSignalCost.Text.ToDecimalUniformSafe() ?? 1; var timeParts = tbNewAccountOpenTime.Text.Split(new[] {'-'}, StringSplitOptions.RemoveEmptyEntries); var timeStartMin = timeParts[0].Trim(' ').ToDateTimeUniform(); var timeStartMax = timeParts[1].Trim(' ').ToDateTimeUniform(); var minutesBackMax = (int)(timeStartMax - timeStartMin).TotalMinutes; using (var ctx = DatabaseContext.Instance.Make()) foreach (var user in users) { // сам пользователь var usrUnd = LinqToEntity.UndecoratePlatformUser(user); ctx.PLATFORM_USER.Add(usrUnd); ctx.SaveChanges(); var userId = usrUnd.ID; var modelTime = timeStartMax.AddMinutes(-rand.Next(minutesBackMax)); // кошелек var wallet = new WALLET { Balance = moneyOnWallet, Currency = currency, Password = user.Password, User = userId }; ctx.WALLET.Add(wallet); // счет var money = GetRandomDepositSize(depoPercentiles); var roughMoneyPercent = 0.0; if (rand.Next(100) < 20) roughMoneyPercent = rand.NextDouble() - 0.5; else if (rand.Next(100) < 30) roughMoneyPercent = rand.NextDouble() * 100 - 50; money += (int)(money * roughMoneyPercent / 100); var account = new ACCOUNT { AccountGroup = group, Balance = money, Currency = currency, Status = (int) Account.AccountStatus.Created, TimeCreated = modelTime, ReadonlyPassword = user.Password }; ctx.ACCOUNT.Add(account); ctx.SaveChanges(); accountIds.Add(account.ID); // денежный перевод на счет - начальный баланс ctx.BALANCE_CHANGE.Add(new BALANCE_CHANGE { AccountID = account.ID, Amount = money, ChangeType = (int) BalanceChangeType.Deposit, Description = "Initial deposit", ValueDate = account.TimeCreated }); // пользователь-счет ctx.PLATFORM_USER_ACCOUNT.Add(new PLATFORM_USER_ACCOUNT { Account = account.ID, PlatformUser = userId, RightsMask = (int) AccountRights.Управление }); // сервис торг. сигналов if (cbSignallers.Checked) { ctx.SERVICE.Add(new SERVICE { AccountId = account.ID, Currency = currency, FixedPrice = signalPrice, User = userId, ServiceType = (int) PaidServiceType.Signals, Comment = "Сигналы " + user.Login }); } ctx.SaveChanges(); } }
public void TestInvestInPAMM() { // PAMM-инвестор var pammInvestor = new PLATFORM_USER { Email = "*****@*****.**", Login = "******", Password = "******", RegistrationDate = DateTime.Now, RoleMask = (int) UserRole.Trader, Title = "trader" }; conn.PLATFORM_USER.Add(pammInvestor); conn.SaveChanges(); var wallet = new WALLET { User = pammInvestor.ID, Balance = 160000, Currency = "USD", Password = "******" }; conn.WALLET.Add(wallet); conn.SaveChanges(); // посчитать, что было ДО инвестирования в ПАММ List<AccountShare> shares; bool noQuoteError; WalletManager.CalculateAccountEquityWithShares(conn, accountShared, accountSharedOwner.ID, Contract.Util.BL.QuoteStorage.Instance.ReceiveAllData(), out shares, out noQuoteError); // инвестировать в ПАММ const decimal amountToInvest = 10000; var oldBalance = accountShared.Balance; var status = walletManager.InvestInPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, amountToInvest); Assert.AreEqual(RequestStatus.OK, status, "InvestInPAMM - должно быть ОК"); accountShared = conn.ACCOUNT.First(a => a.ID == accountShared.ID); var shouldBeBalance = oldBalance + amountToInvest; Assert.IsTrue(shouldBeBalance.RoughCompares(accountShared.Balance, 0.1M), "InvestInPAMM - баланс счета должен увеличиться на сумму вложения"); var newShares = conn.ACCOUNT_SHARE.Where(s => s.Account == accountShared.ID).ToList(); Assert.AreEqual(shares.Count + 1, newShares.Count, "InvestInPAMM - добавился один пай"); var sumSharesPercent = newShares.Sum(s => s.Share); Assert.IsTrue(100M.RoughCompares(sumSharesPercent, 0.000001M), "InvestInPAMM - сумма паев осталась 100%"); Assert.IsTrue(newShares.Any(s => s.ShareOwner == pammInvestor.ID), "InvestInPAMM - новый владелец должен быть в списке пайщиков"); Assert.IsTrue(conn.SUBSCRIPTION.Any(s => s.User == pammInvestor.ID), "InvestInPAMM - должна появиться подписка"); // инвестировать еще денег const decimal moreMoney = 145201.55M; status = walletManager.InvestInPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, moreMoney); Assert.AreEqual(RequestStatus.OK, status, "InvestInPAMM (повторно) - должно быть ОК"); var updatedNewShares = conn.ACCOUNT_SHARE.Where(s => s.Account == accountShared.ID).ToList(); Assert.AreEqual(newShares.Count, updatedNewShares.Count, "InvestInPAMM (повторно) - количество паев не должно меняться"); sumSharesPercent = updatedNewShares.Sum(s => s.Share); Assert.IsTrue(100M.RoughCompares(sumSharesPercent, 0.000001M), "InvestInPAMM (повторно) - сумма паев осталась 100%"); status = walletManager.InvestInPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, moreMoney); Assert.AreEqual(RequestStatus.MarginOrLeverageExceeded, status, "InvestInPAMM (превышение баланса) - должно быть MarginOrLeverageExceeded"); // вывести из ПАММа кусочек const decimal withdrawnMoney = 50.25M; var balanceBeforeWth = conn.WALLET.First(w => w.User == pammInvestor.ID).Balance; status = walletManager.WithdrawFromPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, withdrawnMoney, false); Assert.AreEqual(RequestStatus.OK, status, "InvestInPAMM (вывод средств) - должно быть OK"); var sharesAfterWithdraw = conn.ACCOUNT_SHARE.Where(s => s.Account == accountShared.ID).ToList(); var balanceAfterWth = conn.WALLET.First(w => w.User == pammInvestor.ID).Balance; Assert.IsTrue(balanceBeforeWth.RoughCompares(balanceAfterWth - withdrawnMoney, 0.005M), "баланс должен увеличиться на сумму вывода"); Assert.AreEqual(updatedNewShares.Count, sharesAfterWithdraw.Count, "InvestInPAMM (вывод средств) - количество паёв не должно измениться"); Assert.IsTrue(conn.SUBSCRIPTION.Any(s => s.User == pammInvestor.ID), "InvestInPAMM (вывод средств) - должна остаться подписка"); // попробовать вывести слишком много status = walletManager.WithdrawFromPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, 1000000, false); Assert.AreEqual(RequestStatus.BadRequest, status, "InvestInPAMM (вывод средств) - должно быть BadRequest"); // вывести остаток status = walletManager.WithdrawFromPAMM(ProtectedOperationContext.MakeServerSideContext(), pammInvestor.Login, accountShared.ID, 0, true); Assert.AreEqual(RequestStatus.OK, status, "InvestInPAMM (вывод всех средств) - должно быть OK"); Assert.IsFalse(conn.SUBSCRIPTION.Any(s => s.User == pammInvestor.ID), "InvestInPAMM (вывод всех средств) - должна удалиться подписка"); Assert.IsFalse(conn.ACCOUNT_SHARE.Any(s => s.ShareOwner == pammInvestor.ID), "InvestInPAMM (вывод всех средств) - должна удалиться долька нашего пайщика"); }
/// <summary> /// Зачисляем на T# кошелёк пользователя определённую сумму. /// </summary> /// <param name="wallet">T# кошелёк</param> /// <param name="additionalAmount">валюта кошелёка T#</param> /// <param name="data"></param> /// <param name="userPaymentSysId"></param> /// <returns></returns> public static bool DepositOnWallet(WALLET wallet, decimal additionalAmount, DateTime data, int userPaymentSysId) { try { using (var ctx = DatabaseContext.Instance.Make()) { var comment = string.Format("Зачисление на TradeSharp кошелёк {0} средств в размере {1} {2}.", wallet.User, additionalAmount.ToStringUniformMoneyFormat(), wallet.Currency); var formatComment = comment.Length < 250 ? comment : comment.Substring(0, 249); #region var transfer = new TRANSFER { User = wallet.User, Amount = additionalAmount, ValueDate = DateTime.Now, TargetAmount = additionalAmount, Comment = formatComment }; ctx.TRANSFER.Add(transfer); ctx.PAYMENT_SYSTEM_TRANSFER.Add(new PAYMENT_SYSTEM_TRANSFER { UserPaymentSys = userPaymentSysId, Ammount = additionalAmount, Currency = wallet.Currency, DateProcessed = DateTime.Now, DateValue = data, Transfer = transfer.ID, Comment = formatComment }); #endregion try { var wal = ctx.WALLET.SingleOrDefault(x => x.User == wallet.User); if (wal == null) { Logger.ErrorFormat("DepositOnWallet() - WALLET с id {0} не найден в БД", wallet.User); return false; } wal.Balance += additionalAmount; ctx.SaveChanges(); Logger.InfoFormat("Произведено зачисление средств на TradeSharp кошелёк {0} в размере {1} {2}.", wallet.User, additionalAmount, wallet.Currency); return true; } #region catch catch (Exception ex) { var message = string.Format( "Не удалось сохранить в базу данных запись о зачислении на TradeSharp кошелька {0} средств в размере {1} {2}. " + " Будет произведена попытка провести платёж как 'Неопознанный'. Администратор базы данных должен вручную зачислить " + "средства на этот кошелёк, внеся изменения в таблицы WALLET и PAYMENT_SYSTEM_TRANSFER.", wallet.User, additionalAmount.ToStringUniformMoneyFormat(), wallet.Currency); Logger.Error(message, ex); return false; } #endregion } } #region catch catch (Exception ex) { Logger.Error("DepositOnWallet()", ex); return false; } #endregion }
private Wallet GetMoneyFromUserOwnedAccount(int accountId, decimal amountInSrcCurrency, out WalletError error, ACCOUNT account, WALLET wallet, TradeSharpConnection ctx, PLATFORM_USER user) { var amountWallet = amountInSrcCurrency; if (account.Currency != wallet.Currency) { // найти котировку и перевести string errorString; var amountTarget = DalSpot.Instance.ConvertSourceCurrencyToTargetCurrency(wallet.Currency, account.Currency, (double) amountWallet, QuoteStorage.Instance.ReceiveAllData(), out errorString); if (!amountTarget.HasValue) { Logger.ErrorFormat("DepositOrWithdraw({0} {1}): {2} (withdraw)", amountInSrcCurrency, account.Currency + "/" + wallet.Currency, errorString); error = WalletError.CurrencyExchangeFailed; return null; } amountWallet = amountTarget.Value; } // достаточно ли средств на счете? // проверить средства / зарезервированное марж. обеспечение decimal equity, usedMargin; if (!GetAccountEquityAndUsedMargin(account, out equity, out usedMargin)) { error = WalletError.ServerError; return null; } if (equity - usedMargin < amountInSrcCurrency) { error = WalletError.ServerError; return null; } // списать со счета в пользу кошелька wallet.Balance += amountInSrcCurrency; account.Balance -= amountInSrcCurrency; var date = DateTime.Now; var bc = ctx.BALANCE_CHANGE.Add(new BALANCE_CHANGE { AccountID = accountId, Amount = amountInSrcCurrency, ChangeType = (int) BalanceChangeType.Withdrawal, ValueDate = date, Description = "Списание на кошелек №" + wallet.User }); ctx.SaveChanges(); ctx.TRANSFER.Add(new TRANSFER { Amount = amountWallet, TargetAmount = amountWallet, User = user.ID, Comment = "Вывод средств со счета №" + account.ID, ValueDate = date, BalanceChange = bc.ID, }); ctx.SaveChanges(); error = WalletError.OK; return LinqToEntity.DecorateWallet(wallet); }
private static Wallet PutMoneyOnUserOwnedAccount(int accountId, decimal amountInSrcCurrency, out WalletError error, WALLET wallet, ACCOUNT account, TradeSharpConnection ctx, PLATFORM_USER user) { // достаточно ли денег в кошельке? if (amountInSrcCurrency > wallet.Balance) { error = WalletError.InsufficientFunds; return null; } // перевести объем в валюту счета var amount = amountInSrcCurrency; if (account.Currency != wallet.Currency) { // найти котировку и перевести string errorString; var amountTarget = DalSpot.Instance.ConvertSourceCurrencyToTargetCurrency(account.Currency, wallet.Currency, (double) amount, QuoteStorage.Instance.ReceiveAllData(), out errorString); if (!amountTarget.HasValue) { Logger.ErrorFormat("DepositOrWithdraw({0} {1}): {2}", amountInSrcCurrency, account.Currency + "/" + wallet.Currency, errorString); error = WalletError.CurrencyExchangeFailed; return null; } amount = amountTarget.Value; } // списать с кошелька и пополнить счет wallet.Balance -= amountInSrcCurrency; account.Balance += amount; var dateOper = DateTime.Now; var balanceChange = ctx.BALANCE_CHANGE.Add(new BALANCE_CHANGE { AccountID = accountId, Amount = amount, ChangeType = (int) BalanceChangeType.Deposit, ValueDate = dateOper, Description = "Пополнение с кошелька №" + wallet.User }); try { ctx.SaveChanges(); } catch (Exception ex) { Logger.Error("DepositOrWithdraw() - error saving balance change", ex); error = WalletError.ServerError; return null; } var balanceChangeId = balanceChange.ID; ctx.TRANSFER.Add(new TRANSFER { Amount = -amountInSrcCurrency, TargetAmount = -amountInSrcCurrency, User = user.ID, Comment = "Т. счет №" + account.ID, ValueDate = dateOper, BalanceChange = balanceChangeId, }); try { ctx.SaveChanges(); } //catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException) //{ //} catch (Exception ex) { Logger.Error("DepositOrWithdraw() - error saving transfer for user " + user.ID + ", balance change Id: " + balanceChangeId + ", user: " + user.ID, ex); error = WalletError.ServerError; return null; } error = WalletError.OK; return LinqToEntity.DecorateWallet(wallet); }
public static Wallet DecorateWallet(WALLET walInf) { var wallet = new Wallet { Balance = walInf.Balance, Currency = walInf.Currency, User = walInf.User, Password = walInf.Password }; return wallet; }
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; }