コード例 #1
0
        /// <summary>
        /// Пересчёт баланса для указанного счёта. Применяется, например, после отмены уже закрытых сделок
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="accountId">уникаьлный идентификатор счёта, для которого пересчитываем баланс</param>
        public bool ReCalculateAccountBalance(TradeSharpConnection ctx, int accountId)
        {
            try
            {
                Logger.Info(string.Format("Пытыемся пересчитать баланс для счёта {0}", accountId));
                var bal = ctx.BALANCE_CHANGE.Where(b => b.AccountID == accountId).Sum(c =>
                                                                                      (c.ChangeType == (int)BalanceChangeType.Deposit ||
                                                                                       c.ChangeType == (int)BalanceChangeType.Profit ||
                                                                                       c.ChangeType == (int)BalanceChangeType.Swap ? 1: -1) * c.Amount);

                var acc = ctx.ACCOUNT.Single(a => a.ID == accountId);
                acc.Balance = bal;
                ctx.SaveChanges();

                return(true);
            }
            catch (InvalidOperationException ex)
            {
                Logger.Error(string.Format(
                                 "ReCalculateAccountBalance(). Не удалось пересчитать балланс {0}. Возможно нет ни одной проводки по счёту.", accountId), ex);
            }
            catch (Exception ex)
            {
                Logger.Error(string.Format("ReCalculateAccountBalance(). Не удалось пересчитать балланс счёта {0}.", accountId), ex);
            }
            return(false);
        }
コード例 #2
0
        public string DeleteSpotItem(TradeSharpConnection context, string title)
        {
            var result     = string.Empty;
            var newContext = EnsureContext(ref context);

            try
            {
                var itemToDel = context.SPOT.Single(x => x.Title == title);
                context.SPOT.Remove(itemToDel);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("DeleteSpotItem()", ex);
                result = ex.Message;
            }
            finally
            {
                if (newContext != null)
                {
                    newContext.Dispose();
                }
            }
            return(result);
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
ファイル: MainForm.cs プロジェクト: suspended/TradeSharp
        private void DoFixtransactions(BackgroundWorkerTask taskParam)
        {
            var accountList   = (List <int>)taskParam.DataParam;
            int accountNumber = 0;

            foreach (var id in accountList)
            {
                if (workerQuote.CancellationPending)
                {
                    break;
                }
                var accountId = id;
                using (var db = new TradeSharpConnection())
                {
                    foreach (var order in db.POSITION_CLOSED.Where(p => p.AccountID == accountId))
                    {
                        if (workerQuote.CancellationPending)
                        {
                            break;
                        }
                        var orderId = order.ID;
                        if (db.BALANCE_CHANGE.Any(bc => bc.Position == orderId))
                        {
                            continue;
                        }

                        var changeType  = (int)(order.ResultDepo > 0 ? BalanceChangeType.Profit : BalanceChangeType.Loss);
                        var closeTime   = order.TimeExit;
                        var orderResult = Math.Abs(order.ResultDepo);
                        var missIdBc    = db.BALANCE_CHANGE.FirstOrDefault(b => b.AccountID == accountId &&
                                                                           b.ValueDate == closeTime &&
                                                                           b.Amount == orderResult);
                        if (missIdBc != null)
                        {
                            missIdBc.Position   = orderId;
                            missIdBc.ChangeType = changeType;
                        }
                        else
                        {
                            db.BALANCE_CHANGE.Add(new BALANCE_CHANGE
                            {
                                AccountID  = order.AccountID,
                                Position   = order.ID,
                                Amount     = order.ResultDepo,
                                ChangeType = changeType,
                                ValueDate  = order.TimeExit
                            });
                        }
                    }
                    db.SaveChanges();
                }
                workerQuote.ReportProgress(100 * (accountNumber++) / accountList.Count);
            }
        }
コード例 #5
0
 private bool ModifyClosedPosition(MarketOrder order, TradeSharpConnection ctx, POSITION_CLOSED pos,
                                   out string errorString)
 {
     errorString = string.Empty;
     if (order.IsClosed)
     {
         var opened = new POSITION
         {
             AccountID      = pos.AccountID,
             ID             = pos.ID,
             Comment        = order.Comment,
             Magic          = order.Magic,
             ExpertComment  = order.ExpertComment,
             PendingOrderID = order.PendingOrderID,
             PriceBest      = (decimal?)order.PriceBest,
             PriceEnter     = (decimal)order.PriceEnter,
             PriceWorst     = (decimal?)order.PriceWorst,
             Side           = order.Side,
             Stoploss       = (decimal?)order.StopLoss,
             Symbol         = order.Symbol,
             Takeprofit     = (decimal?)order.TakeProfit,
             TimeEnter      = order.TimeEnter,
             Volume         = order.Volume,
             State          = (int)order.State,
             MasterOrder    = order.MasterOrder
         };
         ctx.POSITION_CLOSED.Remove(pos);
         ctx.POSITION.Add(opened);
         return(true);
     }
     pos.Comment        = order.Comment;
     pos.Magic          = order.Magic;
     pos.ExpertComment  = order.ExpertComment;
     pos.PendingOrderID = order.PendingOrderID;
     pos.PriceBest      = (decimal?)order.PriceBest;
     pos.PriceEnter     = (decimal)order.PriceEnter;
     pos.PriceWorst     = (decimal?)order.PriceWorst;
     pos.Side           = order.Side;
     pos.Stoploss       = (decimal?)order.StopLoss;
     pos.Symbol         = order.Symbol;
     pos.Takeprofit     = (decimal?)order.TakeProfit;
     pos.TimeEnter      = order.TimeEnter;
     pos.Volume         = order.Volume;
     pos.ExitReason     = (int)order.ExitReason;
     pos.PriceExit      = (decimal)(order.PriceExit ?? 0);
     pos.PriceWorst     = (decimal?)order.PriceWorst;
     pos.ResultBase     = (decimal)order.ResultBase;
     pos.ResultDepo     = (decimal)order.ResultDepo;
     pos.ResultPoints   = (decimal)order.ResultPoints;
     pos.TimeExit       = order.TimeExit ?? default(DateTime);
     pos.Swap           = (decimal)(order.Swap ?? 0);
     ctx.SaveChanges();
     return(true);
 }
コード例 #6
0
        public bool DeletePendingOrder(PENDING_ORDER order,
                                       TradeSharpConnection ctx,
                                       PendingOrderStatus status,
                                       int?positionID,
                                       string closeReason)
        {
            // получить текущую цену
            var pair        = QuoteStorage.Instance.ReceiveValue(order.Symbol);
            var priceClosed = pair == null ? 0 : order.Side > 0 ? pair.bid : pair.ask;

            var hist = new PENDING_ORDER_CLOSED
            {
                OrderID       = order.ID,
                AccountID     = order.AccountID,
                Comment       = order.Comment,
                ExpertComment = order.ExpertComment,
                Magic         = order.Magic,
                PairOCO       = order.PairOCO,
                PriceFrom     = order.PriceFrom,
                PriceTo       = order.PriceTo,
                Side          = order.Side,
                Status        = (int)status,
                Stoploss      = order.Stoploss,
                Takeprofit    = order.Takeprofit,
                Symbol        = order.Symbol,
                TimeClosed    = DateTime.Now,
                Volume        = order.Volume,
                PriceClosed   = (decimal)priceClosed,
                Position      = positionID,
                CloseReason   = closeReason
            };

            try
            {
                ctx.PENDING_ORDER_CLOSED.Add(hist);
                var ord = ctx.PENDING_ORDER.FirstOrDefault(p => p.ID == order.ID);
                if (ord == null)
                {
                    Logger.ErrorFormat("DeletePendingOrder - ордер {0} не найден", order.ID);
                    ServiceManagerClientManagerProxy.Instance.NewOrderResponse(null,
                                                                               RequestStatus.ServerError, "crudsav");
                    return(false);
                }
                ctx.PENDING_ORDER.Remove(ord);
                ctx.SaveChanges();
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("Ошибка в DeletePendingOrder (#{0}): {1}", order.ID, ex);
            }
            return(false);
        }
コード例 #7
0
        public RequestStatus UnsubscribeUserFromPortfolio(TradeSharpConnection ctx, string subscriberLogin,
                                                          bool deletePortfolio, bool deleteSubscriptions)
        {
            try
            {
                var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == subscriberLogin);
                if (user == null)
                {
                    return(RequestStatus.Unauthorized);
                }

                var subscriptions = ctx.USER_TOP_PORTFOLIO.Where(u => u.User == user.ID).ToList();
                foreach (var portfolioSub in subscriptions)
                {
                    // удалить подписку
                    ctx.USER_TOP_PORTFOLIO.Remove(portfolioSub);
                    Logger.InfoFormat("UnsubscribeUserFromPortfolio({0}) - отписан от портфеля", subscriberLogin);

                    // если подписка была на пользовательский портфель - удалить пользовательский портфель
                    if (deletePortfolio)
                    {
                        var portfolio = ctx.TOP_PORTFOLIO.Single(p => p.Id == portfolioSub.Portfolio);
                        if (portfolio.OwnerUser == user.ID)
                        {
                            ctx.TOP_PORTFOLIO.Remove(portfolio);
                        }
                    }

                    if (!deleteSubscriptions)
                    {
                        continue;
                    }

                    // удалить подписки на сервисы
                    var subs = ctx.SUBSCRIPTION.Where(s => s.User == user.ID).ToList();
                    foreach (var sub in subs)
                    {
                        ctx.SUBSCRIPTION.Remove(sub);
                    }
                }
                ctx.SaveChanges();

                return(RequestStatus.OK);
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в UnsubscribePortfolio()", ex);
                return(RequestStatus.ServerError);
            }
        }
コード例 #8
0
        private void CloseOrders(ACCOUNT ac, TradeSharpConnection ctx)
        {
            var ordersToClose = ctx.POSITION.Where(p => p.AccountID == ac.ID).ToList();

            foreach (var order in ordersToClose)
            {
                ctx.POSITION.Remove(order);
            }

            var pendingsToClose = ctx.PENDING_ORDER.Where(p => p.AccountID == ac.ID).ToList();

            foreach (var order in pendingsToClose)
            {
                ctx.PENDING_ORDER.Remove(order);
            }

            ctx.SaveChanges();
        }
コード例 #9
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();
        }
コード例 #10
0
        public string AddNewSpotItem(TradeSharpConnection context, SpotModel model)
        {
            var result     = string.Empty;
            var newContext = EnsureContext(ref context);

            try
            {
                var spot = new SPOT
                {
                    ComBase       = model.ComBase,
                    ComCounter    = model.ComCounter,
                    Title         = model.Title,
                    CodeFXI       = model.CodeFXI,
                    MinVolume     = model.MinVolume,
                    MinStepVolume = model.MinStepVolume,
                    Precise       = model.Precise,
                    SwapBuy       = model.SwapBuy,
                    SwapSell      = model.SwapSell,
                    Description   = model.Description
                };

                context.SPOT.Add(spot);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("AddNewSpotItem()", ex);
                result = ex.Message;
            }
            finally
            {
                if (newContext != null)
                {
                    newContext.Dispose();
                }
            }
            return(result);
        }
コード例 #11
0
        public string EditSpotItem(TradeSharpConnection context, SpotModel model)
        {
            var result     = string.Empty;
            var newContext = EnsureContext(ref context);

            try
            {
                var itemToEdit = context.SPOT.Single(x => x.Title == model.Title);

                itemToEdit.ComBase       = model.ComBase;
                itemToEdit.ComCounter    = model.ComCounter;
                itemToEdit.Title         = model.Title;
                itemToEdit.CodeFXI       = model.CodeFXI;
                itemToEdit.MinVolume     = model.MinVolume;
                itemToEdit.MinStepVolume = model.MinStepVolume;
                itemToEdit.Precise       = model.Precise;
                itemToEdit.SwapBuy       = model.SwapBuy;
                itemToEdit.SwapSell      = model.SwapSell;
                itemToEdit.Description   = model.Description;

                context.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("EditSpotItem()", ex);
                result = ex.Message;
            }
            finally
            {
                if (newContext != null)
                {
                    newContext.Dispose();
                }
            }
            return(result);
        }
コード例 #12
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();
        }
コード例 #13
0
        private bool CreateOrUpdateServiceFeeRecords(PaidService service, TradeSharpConnection ctx, bool existedService)
        {
            if (service.serviceRates == null)
            {
                service.serviceRates = new List <PaidServiceRate>();
            }
            try
            {
                if ((service.serviceRates == null || service.serviceRates.Count == 0) && !existedService)
                {
                    return(true);
                }

                // сервис уже был зарегистрирован?
                if (existedService)
                {
                    var rates = ctx.SERVICE_RATE.Where(r => r.Service == service.Id).ToList();
                    if (rates.Count == 0 && service.serviceRates.Count == 0)
                    {
                        return(true);
                    }
                    // рейты не изменились?
                    if (rates.Count == service.serviceRates.Count)
                    {
                        if (rates.All(r => service.serviceRates.Any(sr =>
                                                                    sr.Amount == r.Amount &&
                                                                    sr.UserBalance == r.UserBalance &&
                                                                    (int)sr.RateType == r.RateType)))
                        {
                            return(true);
                        }
                    }
                    // удалить имеющиеся рейты
                    foreach (var rate in rates)
                    {
                        ctx.SERVICE_RATE.Remove(rate);
                    }
                }

                // добавить рейты
                foreach (var rate in service.serviceRates)
                {
                    ctx.SERVICE_RATE.Add(new SERVICE_RATE
                    {
                        Amount      = rate.Amount,
                        Service     = service.Id,
                        UserBalance = rate.UserBalance,
                        RateType    = (int)rate.RateType
                    });
                }

                ctx.SaveChanges();

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error("CreateOrUpdateServiceFeeRecords() error", ex);
                return(false);
            }
        }
コード例 #14
0
        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));
        }
コード例 #15
0
        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));
        }
コード例 #16
0
        public RequestStatus InvestOrWithdrawFromPamm(decimal sumInWalletCurrency, bool withdrawNotInvest,
                                                      bool withdrawAll,
                                                      TradeSharpConnection databaseConnection)
        {
            this.sumInWalletCurrency = sumInWalletCurrency;
            this.withdrawNotInvest   = withdrawNotInvest;
            this.withdrawAll         = withdrawAll;

            var checkStatus = CheckAmount();

            if (checkStatus != RequestStatus.OK)
            {
                return(checkStatus);
            }

            ctx = databaseConnection ?? DatabaseContext.Instance.Make();
            try
            {
                // найти подписанта
                var subscriber = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == login);
                if (subscriber == null)
                {
                    Logger.ErrorFormat("InvestOrWithdrawFromPamm(login={0}) - подписант не найден", login);
                    return(RequestStatus.IncorrectData);
                }

                // владелец целевого ПАММ-счета
                var stat = FindPAMMServiceWithOwner();
                if (stat != RequestStatus.OK)
                {
                    return(stat);
                }

                // посчитать средства по счету
                var  account = ctx.ACCOUNT.First(a => a.ID == accountId);
                var  quotes  = QuoteStorage.Instance.ReceiveAllData();
                bool noQuoteError;

                List <AccountShare> shares;
                var equity = WalletManager.CalculateAccountEquityWithShares(ctx, account, owner.ID, quotes, out shares,
                                                                            out noQuoteError);
                if (noQuoteError)
                {
                    Logger.ErrorFormat(
                        "InvestOrWithdrawFromPamm(acc={0}) - невозможно произвести расчет текущей прибыли - нет котировок",
                        accountId);
                    return(RequestStatus.ServerError);
                }
                decimal amountInAccountCurx;
                // пересчитать сумму в валюту ПАММа
                // проверить не выводит ли / не заводит ли слишком много?
                var status = CheckShareAndUpdateSubscriberWallet(shares, subscriber, account, quotes,
                                                                 out amountInAccountCurx);
                if (status != RequestStatus.OK)
                {
                    return(status);
                }

                // добавить денег и пересчитать дольки
                var newEquity    = equity + (withdrawNotInvest ? -1 : 1) * amountInAccountCurx;
                var sharePercent = amountInAccountCurx * 100 / newEquity;
                var sharesNew    = shares.Select(s => new AccountShare
                {
                    UserId       = s.UserId,
                    ShareMoney   = s.ShareMoney,
                    SharePercent = s.ShareMoney * 100 / newEquity,
                    HWM          = s.HWM
                }).ToList();

                // доля нового совладельца - пополнить или создать запись
                if (!withdrawNotInvest)
                {
                    var newOwnerShare = sharesNew.FirstOrDefault(s => s.UserId == subscriber.ID);
                    if (newOwnerShare != null)
                    {
                        newOwnerShare.SharePercent += sharePercent;
                        newOwnerShare.ShareMoney   += amountInAccountCurx;
                    }
                    else
                    {
                        sharesNew.Add(new AccountShare
                        {
                            ShareMoney   = amountInAccountCurx,
                            SharePercent = sharePercent,
                            UserId       = subscriber.ID,
                            HWM          = amountInAccountCurx
                        });
                    }
                }

                // найти существующую подписку и либо добавить денег,
                // либо создать новую подписку
                var subscriptExists = ctx.SUBSCRIPTION.Any(s => s.Service == service.ID && s.User == subscriber.ID);
                if (!subscriptExists && !withdrawNotInvest)
                {
                    // добавить подписку
                    ctx.SUBSCRIPTION.Add(new SUBSCRIPTION
                    {
                        User        = subscriber.ID,
                        RenewAuto   = false,
                        Service     = service.ID,
                        TimeStarted = DateTime.Now,
                        TimeEnd     = DateTime.Now
                    });
                }
                else if (subscriptExists && withdrawNotInvest && withdrawAll)
                {
                    // удалить подписку
                    ctx.SUBSCRIPTION.Remove(
                        ctx.SUBSCRIPTION.First(s => s.Service == service.ID && s.User == subscriber.ID));
                }

                // модифицировать записи ACCOUNT_SHARE
                UpdateShares(sharesNew, subscriber.ID);

                // пополнить баланс счета
                account.Balance += amountInAccountCurx;

                // сохранить изменения
                ctx.SaveChanges();
                return(RequestStatus.OK);
            } // using ...
            catch (Exception ex)
            {
                Logger.Error("Ошибка в InvestOrWithdrawFromPamm", ex);
                return(RequestStatus.ServerError);
            }
            finally
            {
                if (databaseConnection == null)
                {
                    ctx.Dispose();
                }
            }
        }
コード例 #17
0
        public bool SubscribeOnService(TradeSharpConnection ctx,
                                       int userId, int serviceId, bool renewAuto, bool unsubscribe,
                                       AutoTradeSettings tradeSets, out WalletError error)
        {
            // имеющаяся подписка
            var subs = ctx.SUBSCRIPTION.FirstOrDefault(s => s.Service == serviceId && s.User == userId);

            // просто отписаться от сервиса
            if (unsubscribe)
            {
                error = WalletError.OK;
                if (subs == null)
                {
                    return(true);
                }
                ctx.SUBSCRIPTION.Remove(subs);
                try
                {
                    ctx.SaveChanges();
                }
                catch (Exception ex)
                {
                    Logger.Error("Ошибка удаления подписки (SubscribeOnService)", ex);
                    error = WalletError.ServerError;
                    return(false);
                }

                return(true);
            }

            var paidService = ctx.SERVICE.FirstOrDefault(s => s.ID == serviceId);

            if (paidService == null)
            {
                error = WalletError.InvalidData;
                return(false);
            }

            // проверить - не подписывается ли пользователь сам на себя?
            if (paidService.User == userId)
            {
                error = WalletError.InvalidData;
                return(false);
            }

            // провести списание денежных средств
            // содрать денежку
            var feeError = ChargeFeeOnSubscription(ctx, serviceId, userId, false);

            if (feeError != WalletError.OK)
            {
                error = feeError;
                return(false);
            }

            // продлить или обновить подписку
            var subExists = subs != null;

            if (subs == null)
            {
                subs = new SUBSCRIPTION();
            }
            subs.RenewAuto   = renewAuto;
            subs.TimeEnd     = DateTime.Now.Date.AddDays(1);
            subs.TimeStarted = DateTime.Now.Date;
            subs.User        = userId;
            subs.Service     = serviceId;
            if (!subExists)
            {
                ctx.SUBSCRIPTION.Add(subs);
            }

            // обновить или создать настройки торговли
            var signalTradeSets = ctx.SUBSCRIPTION_SIGNAL.FirstOrDefault(s => s.Service == serviceId && s.User == userId);
            var setsExists      = signalTradeSets != null;

            if (signalTradeSets == null)
            {
                signalTradeSets = new SUBSCRIPTION_SIGNAL();
            }
            signalTradeSets.AutoTrade            = tradeSets.TradeAuto;
            signalTradeSets.FixedVolume          = tradeSets.FixedVolume;
            signalTradeSets.HedgingOrdersEnabled = tradeSets.HedgingOrdersEnabled;
            signalTradeSets.MaxLeverage          = tradeSets.MaxLeverage;
            signalTradeSets.MaxVolume            = tradeSets.MaxVolume;
            signalTradeSets.MinVolume            = tradeSets.MinVolume;
            signalTradeSets.PercentLeverage      = tradeSets.PercentLeverage;
            signalTradeSets.Service       = serviceId;
            signalTradeSets.StepVolume    = tradeSets.StepVolume;
            signalTradeSets.User          = userId;
            signalTradeSets.TargetAccount = tradeSets.TargetAccount;
            signalTradeSets.VolumeRound   = (int?)tradeSets.VolumeRound;
            if (!setsExists)
            {
                ctx.SUBSCRIPTION_SIGNAL.Add(signalTradeSets);
            }

            try
            {
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка сохранения подписки (SubscribeOnService)", ex);
                error = WalletError.ServerError;
                return(false);
            }

            error = WalletError.OK;
            return(true);
        }
コード例 #18
0
        public RequestStatus SubscribeUserOnPortfolio(
            TradeSharpConnection ctx,
            string subscriberLogin,
            TopPortfolio portfolio,
            decimal?maxFee,
            AutoTradeSettings tradeAutoSettings)
        {
            var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == subscriberLogin);

            if (user == null)
            {
                return(RequestStatus.Unauthorized);
            }

            TOP_PORTFOLIO targetPortfolio = null;

            if (portfolio.Id > 0)
            {
                targetPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.Id == portfolio.Id);
            }
            if (targetPortfolio != null)
            {
                portfolio.ManagedAccount = targetPortfolio.ManagedAccount;
            }

            // если портфель - пользовательский - сохранить его
            // для пользователя или обновить его имеющийся портфель
            if (!portfolio.IsCompanyPortfolio)
            {
                Logger.Info("SubscribeOnPortfolio() - user portfolio");
                try
                {
                    var existPortfolio = ctx.TOP_PORTFOLIO.FirstOrDefault(p => p.OwnerUser == user.ID);
                    if (existPortfolio != null)
                    {
                        if (!LinqToEntity.DecoratePortfolio(existPortfolio).AreSame(portfolio))
                        {
                            // удалить старый портфель пользователя
                            ctx.TOP_PORTFOLIO.Remove(existPortfolio);
                            existPortfolio = null;
                        }
                        else
                        {
                            targetPortfolio = existPortfolio;
                        }
                    }
                    // создать портфель пользователя
                    if (existPortfolio == null)
                    {
                        targetPortfolio                = LinqToEntity.UndecoratePortfolio(portfolio);
                        targetPortfolio.OwnerUser      = user.ID;
                        targetPortfolio.ManagedAccount = null;
                        ctx.TOP_PORTFOLIO.Add(targetPortfolio);
                        ctx.SaveChanges();
                    }
                }
                catch (DbEntityValidationException dbEx)
                {
                    Logger.Error("SubscribeUserOnPortfolio - ошибка сохранения портфеля");
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            Logger.ErrorFormat("Свойство: {0}, ошибка: {1}",
                                               validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error("Ошибка в SubscribeOnPortfolio() - обновление портфеля", ex);
                    return(RequestStatus.ServerError);
                }
            }
            else
            {// портфель компании
                Logger.Info("SubscribeOnPortfolio() - company portfolio");
                if (targetPortfolio == null)
                {
                    Logger.Error("Пользователь запросил несуществующий портфель компании " + portfolio.Id);
                    return(RequestStatus.ServerError);
                }
            }

            // очистить подписки пользователя на портфели
            // и привязать его к целевому портфелю
            //Logger.Info("SubscribeOnPortfolio() - removing bindings");
            var oldBinding = ctx.USER_TOP_PORTFOLIO.FirstOrDefault(u => u.User == user.ID);

            // "посмотреть" настройки портфельной торговли в имеющейся подписке
            if (tradeAutoSettings == null)
            {
                if (oldBinding == null)
                {
                    Logger.ErrorFormat("Подписка пользователя {0} на портфель {1} - нет данных по автоматической торговле",
                                       user.Login, portfolio.Id > 0 ? portfolio.Id.ToString() : portfolio.Name);
                    return(RequestStatus.BadRequest);
                }
                tradeAutoSettings = new AutoTradeSettings
                {
                    FixedVolume          = oldBinding.FixedVolume,
                    HedgingOrdersEnabled = oldBinding.HedgingOrdersEnabled,
                    MaxLeverage          = oldBinding.MaxLeverage,
                    MaxVolume            = oldBinding.MaxVolume,
                    MinVolume            = oldBinding.MinVolume,
                    PercentLeverage      = oldBinding.PercentLeverage ?? 100,
                    StepVolume           = oldBinding.StepVolume,
                    TargetAccount        = oldBinding.TargetAccount,
                    TradeAuto            = oldBinding.AutoTrade ?? false,
                    VolumeRound          = (VolumeRoundType?)oldBinding.VolumeRound
                };
            }

            if (oldBinding != null)
            {
                ctx.USER_TOP_PORTFOLIO.Remove(oldBinding);
            }

            //Logger.Info("SubscribeOnPortfolio() - adding binding");
            ctx.USER_TOP_PORTFOLIO.Add(new USER_TOP_PORTFOLIO
            {
                User                 = user.ID,
                Portfolio            = targetPortfolio.Id,
                MaxFee               = maxFee,
                AutoTrade            = tradeAutoSettings.TradeAuto,
                MaxLeverage          = tradeAutoSettings.MaxLeverage,
                PercentLeverage      = tradeAutoSettings.PercentLeverage,
                HedgingOrdersEnabled = tradeAutoSettings.HedgingOrdersEnabled,
                FixedVolume          = tradeAutoSettings.FixedVolume,
                MinVolume            = tradeAutoSettings.MinVolume,
                MaxVolume            = tradeAutoSettings.MaxVolume,
                VolumeRound          = (int?)tradeAutoSettings.VolumeRound,
                StepVolume           = tradeAutoSettings.StepVolume,
                TargetAccount        = tradeAutoSettings.TargetAccount
            });
            ctx.SaveChanges();
            //Logger.Info("SubscribeOnPortfolio() - changes are saved");

            // найти трейдеров, удовлетворяющих критерию
            List <PerformerStat> performers;

            try
            {
                try
                {
                    performers = TradeSharpAccountStatistics.Instance.proxy.GetAllPerformersWithCriteria(true,
                                                                                                         targetPortfolio.Criteria, targetPortfolio.ParticipantCount,
                                                                                                         !targetPortfolio.DescendingOrder, (float?)targetPortfolio.MarginValue, 0);
                }
                catch (Exception ex)
                {
                    Logger.Error(
                        "Ошибка в SubscribeOnPortfolio() - получение перформеров (" + targetPortfolio.Criteria + ")",
                        ex);
                    return(RequestStatus.ServerError);
                }

                if (performers == null)
                {
                    Logger.Error("Ошибка в SubscribeOnPortfolio() - список перформеров не получен (" + targetPortfolio.Criteria + ")");
                    return(RequestStatus.ServerError);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в SubscribeOnPortfolio() - подписка", ex);
                return(RequestStatus.ServerError);
            }

            // сравнить полученный список с текущими подписками заказчика ("инвестора")
            // сформировать список для "отписки" и список для подписки
            var performerAcs = performers.Select(p => p.Account).ToList();
            var subsToRemove = ctx.SUBSCRIPTION.Where(s => s.User == user.ID &&
                                                      s.SERVICE1.ServiceType == (int)PaidServiceType.Signals &&
                                                      !performerAcs.Contains(s.SERVICE1.AccountId ?? 0)).ToList();

            foreach (var sub in subsToRemove)
            {
                WalletError error;
                SubscribeOnService(ctx, user.ID, sub.Service, false, true, tradeAutoSettings, out error);
                if (error != WalletError.OK)
                {
                    Logger.ErrorFormat("Portfolio - unsubscribe user {0} from srv {1}: error {2}",
                                       user.ID, sub.Service, error);
                }
            }

            // новоподписавшиеся
            foreach (var pf in performers)
            {
                WalletError error;
                SubscribeOnService(ctx, user.ID, pf.Service, true, false, tradeAutoSettings, out error);
                if (error != WalletError.OK)
                {
                    Logger.DebugFormat("Подписка SubscribeOnPortfolio({0}), сигн. {1}: {2}",
                                       subscriberLogin, pf.Service, error);
                }
            }
            return(RequestStatus.OK);
        }
コード例 #19
0
        public WalletError ChargeFeeOnSubscription(TradeSharpConnection ctx, SERVICE service, int usr, bool renewSubscription)
        {
            try
            {
                // создать платеж с кошелька usr на кошелек владельца сервиса (service)
                if (service.FixedPrice == 0)
                {
                    return(WalletError.OK); // все на шарку!
                }
                var price = service.FixedPrice > 0
                                ? service.FixedPrice
                                : GetFeeByUserBalance(ctx, service);
                if (price == 0)
                {
                    return(WalletError.OK);
                }

                var usrWallet = ctx.WALLET.FirstOrDefault(w => w.User == usr);
                if (usrWallet == null)
                {
                    Logger.Error("ChargeFeeOnSubscription(usrId=" + usr + ") - wallet is not found");
                    return(WalletError.ServerError);
                }

                if (HasUserPaidTheService(ctx, service, usr))
                {
                    return(WalletError.OK);
                }

                // посчитать в валюте пользователя
                var usrAmount = price;
                if (usrWallet.Currency != service.Currency)
                {
                    string strError;
                    var    targetAmount = DalSpot.Instance.ConvertSourceCurrencyToTargetCurrency(usrWallet.Currency, service.Currency,
                                                                                                 (double)usrAmount,
                                                                                                 QuoteStorage.Instance.ReceiveAllData(),
                                                                                                 out strError);
                    if (!targetAmount.HasValue)
                    {
                        Logger.ErrorFormat("ChargeFeeOnSubscription(usrId={0}) - currency rate is not found ({1}/{2})",
                                           usr, usrWallet.Currency, service.Currency);
                        return(WalletError.CurrencyExchangeFailed);
                    }
                    usrAmount = targetAmount.Value;
                }

                // если объем превышает возможности пользователя...
                if (usrWallet.Balance < usrAmount)
                {
                    Logger.InfoFormat("ChargeFeeOnSubscription(usrId={0}) - not enough money ({1}, needed {2})",
                                      usr, usrAmount, usrWallet.Balance);
                    return(WalletError.InsufficientFunds);
                }

                usrWallet.Balance -= usrAmount;
                var trans = ctx.TRANSFER.Add(new TRANSFER
                {
                    Amount       = usrAmount,
                    TargetAmount = price,
                    Comment      = "Fee on srv " + service.ID,
                    RefWallet    = service.User,
                    User         = usr,
                    ValueDate    = DateTime.Now,
                    Subscription = service.ID
                });
                Logger.InfoFormat("Добавляется трансфер: usr={0}, comment={1}",
                                  usr, trans.Comment);

                // добавить денег владельцу
                ctx.TRANSFER.Add(new TRANSFER
                {
                    Amount       = price,
                    TargetAmount = usrAmount,
                    Comment      = "Paid for srv " + service.ID,
                    RefWallet    = usr,
                    User         = service.User,
                    ValueDate    = DateTime.Now,
                    Subscription = service.ID
                });
                var ownerWallet = ctx.WALLET.First(w => w.User == service.User);
                ownerWallet.Balance += price;

                // обновить подписку
                if (renewSubscription)
                {
                    var sub = ctx.SUBSCRIPTION.FirstOrDefault(s => s.Service == service.ID);
                    if (sub != null && sub.RenewAuto)
                    {
                        sub.TimeStarted = DateTime.Now.Date;
                        sub.TimeEnd     = sub.TimeStarted.AddDays(1);
                    }
                }

                Logger.InfoFormat("ChargeFeeOnSubscription() - сохранение");
                ctx.SaveChanges();
            }
            catch (Exception ex)
            {
                Logger.Error("Error in ChargeFeeOnSubscription()", ex);
                return(WalletError.ServerError);
            }
            return(WalletError.OK);
        }