public static void OrderCalcWorkerOnDoWork(object senderWorker, DoWorkEventArgs argsWithTicker)
        {
            var worker = (BackgroundWorker) senderWorker;

            var ticker = (string) argsWithTicker.Argument;
            var account = AccountStatus.Instance.AccountData;
            if (account == null) return;

            var orders = new List<MarketOrder>();
            try
            {
                // получить закрытые ордера порциями
                while (true)
                {
                    if (worker.CancellationPending) return;
                    var startId = orders.Count == 0 ? 0 : orders.Max(o => o.ID);
                    var ordersPart = TradeSharpAccount.Instance.proxy.GetClosedOrders(AccountStatus.Instance.accountID,
                        ticker, startId, 200) ?? new List<MarketOrder>();
                    if (ordersPart.Count == 0) break;
                    orders.AddRange(ordersPart);
                }

                // получить открытые ордера
                if (worker.CancellationPending) return;
                List<MarketOrder> openedOrders;
                TradeSharpAccount.Instance.proxy.GetMarketOrders(AccountStatus.Instance.accountID, out openedOrders);
                if (openedOrders != null && openedOrders.Count > 0)
                {
                    openedOrders = openedOrders.Where(o => o.Symbol == ticker).ToList();
                    if (openedOrders.Count > 0)
                    {
                        CalculateOpenedOrdersResult(openedOrders, account.Currency);
                        orders.AddRange(openedOrders);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка получения ордеров", ex);
                MessageBox.Show(Localizer.GetString("MessageErrorGettingOrders"),
                    Localizer.GetString("TitleError"),
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (orders.Count == 0) return;

            var balanceOnDate = new BalanceAndEquitySeriesData();
            var startDate = orders.Min(o => o.TimeEnter).Date;
            var endDate = DateTime.Now;
            orders.ForEach(o =>
                {
                    o.TimeExit = o.TimeExit ?? endDate;
                    o.State = PositionState.Opened;
                });
            orders = orders.Where(o => o.TimeExit.HasValue).OrderBy(o => o.TimeExit).ToList();

            var balance = 0f;
            // установить "курсор" котировок на начало наблюдаемого отрезка
            var cursor = new BacktestTickerCursor();
            var tickers = new List<string> {ticker};
            // нужна еще валюта пересчета?
            bool inverse, pairsEqual;
            var tickerCounterDepo = DalSpot.Instance.FindSymbol(ticker, false, account.Currency,
                out inverse, out pairsEqual);
            if (!string.IsNullOrEmpty(tickerCounterDepo) && tickerCounterDepo != ticker)
                tickers.Add(tickerCounterDepo);
            cursor.SetupCursor(TerminalEnvironment.QuoteCacheFolder, tickers, startDate);
            try
            {
                for (var date = startDate; ; )
                {
                    if (date != endDate && DaysOff.Instance.IsDayOff(date))
                    {
                        date = date.AddDays(1);
                        continue;
                    }

                    for (var i = 0; i < orders.Count; i++)
                    {
                        if (orders[i].TimeExit > date) break;
                        balance += orders[i].ResultDepo;
                        orders.RemoveAt(i);
                        i--;
                    }

                    // получить текущий результат по открытым на момент ордерам
                    var equity = balance;
                    var curDate = date;
                    var curOrders = orders.Where(o => o.TimeEnter <= curDate).ToList();
                    if (curOrders.Count > 0)
                    {
                        cursor.MoveToTime(date);
                        var curProfit = DalSpot.Instance.CalculateOpenedPositionsCurrentResult(curOrders,
                            cursor.GetCurrentQuotes().ToDictionary(c => c.a,
                                c => new QuoteData(c.b.close, c.b.close, curDate)), account.Currency);
                        equity += curProfit;
                    }

                    balanceOnDate.lstBalance.Add(new TimeBalans(date, balance));
                    balanceOnDate.lstEquity.Add(new TimeBalans(date, equity));

                    if (date == endDate) break;
                    date = date.AddDays(1);
                    if (date > endDate) date = endDate;
                }
            }
            finally
            {
                cursor.Close();
            }
            // сместить последнюю дату кривой баланса
            balanceOnDate.ShiftLastDate();
            argsWithTicker.Result = balanceOnDate;
        }
Example #2
0
        public static void OrderCalcWorkerOnDoWork(object senderWorker, DoWorkEventArgs argsWithTicker)
        {
            var worker = (BackgroundWorker)senderWorker;

            var ticker  = (string)argsWithTicker.Argument;
            var account = AccountStatus.Instance.AccountData;

            if (account == null)
            {
                return;
            }

            var orders = new List <MarketOrder>();

            try
            {
                // получить закрытые ордера порциями
                while (true)
                {
                    if (worker.CancellationPending)
                    {
                        return;
                    }
                    var startId    = orders.Count == 0 ? 0 : orders.Max(o => o.ID);
                    var ordersPart = TradeSharpAccount.Instance.proxy.GetClosedOrders(AccountStatus.Instance.accountID,
                                                                                      ticker, startId, 200) ?? new List <MarketOrder>();
                    if (ordersPart.Count == 0)
                    {
                        break;
                    }
                    orders.AddRange(ordersPart);
                }

                // получить открытые ордера
                if (worker.CancellationPending)
                {
                    return;
                }
                List <MarketOrder> openedOrders;
                TradeSharpAccount.Instance.proxy.GetMarketOrders(AccountStatus.Instance.accountID, out openedOrders);
                if (openedOrders != null && openedOrders.Count > 0)
                {
                    openedOrders = openedOrders.Where(o => o.Symbol == ticker).ToList();
                    if (openedOrders.Count > 0)
                    {
                        CalculateOpenedOrdersResult(openedOrders, account.Currency);
                        orders.AddRange(openedOrders);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка получения ордеров", ex);
                MessageBox.Show(Localizer.GetString("MessageErrorGettingOrders"),
                                Localizer.GetString("TitleError"),
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (orders.Count == 0)
            {
                return;
            }

            var balanceOnDate = new BalanceAndEquitySeriesData();
            var startDate     = orders.Min(o => o.TimeEnter).Date;
            var endDate       = DateTime.Now;

            orders.ForEach(o =>
            {
                o.TimeExit = o.TimeExit ?? endDate;
                o.State    = PositionState.Opened;
            });
            orders = orders.Where(o => o.TimeExit.HasValue).OrderBy(o => o.TimeExit).ToList();

            //==============================================
            // получить изменения баланса
            if (worker.CancellationPending)
            {
                return;
            }
            List <BalanceChange> balanceChanges;
            var status = TradeSharpAccount.Instance.proxy.GetBalanceChanges(account.ID, null, out balanceChanges);

            if (status != RequestStatus.OK || balanceChanges == null)
            {
                MessageBox.Show(string.Format(Localizer.GetString("MessageUnableToGetTransfersHistory") + ": {0}",
                                              EnumFriendlyName <RequestStatus> .GetString(status)));
                return;
            }
            var dueBalances = balanceChanges.Where(bc =>
                                                   bc.ChangeType == BalanceChangeType.Deposit || bc.ChangeType == BalanceChangeType.Withdrawal)
                              .OrderBy(x => x.ValueDate)
                              .ToList();
            //==============================================

            var balance = 0f;
            // установить "курсор" котировок на начало наблюдаемого отрезка
            var cursor  = new BacktestTickerCursor();
            var tickers = new List <string> {
                ticker
            };
            // нужна еще валюта пересчета?
            bool inverse, pairsEqual;
            var  tickerCounterDepo = DalSpot.Instance.FindSymbol(ticker, false, account.Currency,
                                                                 out inverse, out pairsEqual);

            if (!string.IsNullOrEmpty(tickerCounterDepo) && tickerCounterDepo != ticker)
            {
                tickers.Add(tickerCounterDepo);
            }
            cursor.SetupCursor(ExecutablePath.ExecPath + TerminalEnvironment.QuoteCacheFolder, tickers, startDate);
            try
            {
                for (var date = startDate; ;)
                {
                    if (date != endDate && DaysOff.Instance.IsDayOff(date))
                    {
                        date = date.AddDays(1);
                        continue;
                    }

                    for (var i = 0; i < dueBalances.Count; i++)
                    {
                        if (dueBalances[i].ValueDate > date)
                        {
                            break;
                        }
                        balance += (float)dueBalances[i].SignedAmountDepo;
                        dueBalances.RemoveAt(i);
                        i--;
                    }

                    for (var i = 0; i < orders.Count; i++)
                    {
                        if (orders[i].TimeExit > date)
                        {
                            break;
                        }
                        balance += orders[i].ResultDepo;
                        orders.RemoveAt(i);
                        i--;
                    }

                    // получить текущий результат по открытым на момент ордерам
                    var equity    = balance;
                    var curDate   = date;
                    var curOrders = orders.Where(o => o.TimeEnter <= curDate).ToList();
                    var curProfit = 0f;

                    if (curOrders.Count > 0)
                    {
                        cursor.MoveToTime(date);

                        var quotes = cursor.GetCurrentQuotes().ToDictionary(c => c.a,
                                                                            c => new QuoteData(c.b.close, c.b.close, curDate));

                        curProfit = DalSpot.Instance.CalculateOpenedPositionsCurrentResult(curOrders,
                                                                                           quotes, account.Currency);
                        equity += curProfit;


                        var errors = new List <string>();
                        var exp    = DalSpot.Instance.CalculateExposure(curOrders,
                                                                        quotes, account.Currency, errors);

                        if (errors.Count == 0)
                        {
                            var leverage = (float)Math.Abs(exp) / equity;
                            balanceOnDate.lstLeverage.Add(new TimeBalans(date, leverage));
                        }
                    }

                    balanceOnDate.lstBalance.Add(new TimeBalans(date, balance));
                    balanceOnDate.lstEquity.Add(new TimeBalans(date, equity));
                    balanceOnDate.lstDrawDown.Add(new TimeBalans(date, curProfit < 0 ? curProfit : 0));

                    if (date == endDate)
                    {
                        break;
                    }
                    date = date.AddDays(1);
                    if (date > endDate)
                    {
                        date = endDate;
                    }
                }
            }
            finally
            {
                cursor.Close();
            }
            // сместить последнюю дату кривой баланса
            balanceOnDate.ShiftLastDate();
            argsWithTicker.Result = balanceOnDate;
        }