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; }
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; }