private void CalcBudget(PricePairList profits, PricePairList positionValues) { foreach (var date in profits.Dates) { _budget = Math.Max(_budget, positionValues[date].Book - profits[date].Book); } }
private void CalcMaxPosition(PricePairList positionValues) { var max = new PricePair(); foreach (var value in positionValues) { max = PricePair.Max(max, value); } _marketMaxPosition = max.Market; _bookMaxPosition = max.Book; }
// ReSharper disable ParameterTypeCanBeEnumerable.Local private void CalcDrowdown(PricePairList profits) // ReSharper restore ParameterTypeCanBeEnumerable.Local { var maxProfit = new PricePair(); var maxDrowdown = new PricePair(); foreach (var profit in profits) { maxProfit = PricePair.Max(maxProfit, profit); maxDrowdown = PricePair.Min(maxDrowdown, profit - maxProfit); } _marketMaxDrowDown = maxDrowdown.Market; _bookMaxDrowDown = maxDrowdown.Book; }
private PricePairList AnalyzeLogs(BackgroundWorker worker) { var profits = new PricePairList(); var positionValues = new PricePairList(); var count = 0; if (PriceData.MaxDate == DateTime.MinValue) { throw new Exception("株価データがありません。"); } using (var logData = new LogData(_name, _timeFrame)) { foreach (var code in _brandList.List) { if (worker.CancellationPending) { return(null); } var prices = PriceData.GetPrices(code, _timeFrame); if (prices == null) { continue; } var logs = logData.GetLog(code); var logIndex = 0; var prevClose = 0; var prevHigh = 0; var position = 0; var totalBuy = 0f; var totalSell = 0f; var startDate = DateTime.MinValue; var averagePrice = 0f; foreach (var price in prices) { if (worker.CancellationPending) { return(null); } var dailyProfit = profits[price.Date]; var dailyValue = positionValues[price.Date]; var close = price.Close; // if (position != 0 && close > 0 && prevClose > 0) // dailyProfit.AddMarket(position, close - prevClose); // 時価の前日比を加算する。 if (position != 0 && close > 0 && prevClose > 0) { dailyProfit.AddMarket(position, close - prevClose); // 時価の前日比を加算する。 } if (close > 0) { prevClose = close; } if (price.High > 0) { prevHigh = price.High; } dailyValue.AddMarket(Math.Abs(position), prevHigh); // dailyValue.AddMarket(Math.Abs(position), prevHigh); Log log; if (logIndex == logs.Count || logs[logIndex].Date != price.Date || // 売買が発生しない。 (log = logs[logIndex++]).Quantity == 0) // 0株の売買は無視する。 { continue; } var prevPosition = position; var consideration = (float)log.Quantity * log.Price; if (log.Order == Order.Buy) { position += log.Quantity; totalBuy += consideration; if (close > 0) { dailyProfit.AddMarket(log.Quantity, close - log.Price); } // if (close > 0) // dailyProfit.AddMarket(log.Quantity, close - log.Price); } else { position -= log.Quantity; totalSell += consideration; // if (close > 0) // dailyProfit.AddMarket(log.Quantity, log.Price - close); if (close > 0) { dailyProfit.AddMarket(log.Quantity, log.Price - close); } } var abs = Math.Abs(position); var prevAbs = Math.Abs(prevPosition); if ((float)position * prevPosition > 0) // トレード継続 { if (abs < prevAbs) { dailyValue.AddBook(log.Quantity, -averagePrice); dailyProfit.AddBook(log.Quantity, Math.Sign(position) * (log.Price - averagePrice)); } else { averagePrice = (prevAbs * averagePrice + consideration) / abs; dailyValue.AddBook(consideration); } continue; } dailyValue.AddBook(prevAbs, -averagePrice); dailyProfit.AddBook(prevPosition, log.Price - averagePrice); if (position == 0) // トレード終了 { averagePrice = 0; } else // ドテンかトレード開始 { dailyValue.AddBook(abs, log.Price); averagePrice = log.Price; startDate = log.Date; if (prevPosition == 0) // トレード開始 { continue; } } // ドテンの補正 var realTotalBuy = totalBuy; var realTotalSell = totalSell; totalBuy = totalSell = 0; if (position > 0) { realTotalBuy -= (totalBuy = (float)position * log.Price); } else if (position < 0) { realTotalSell -= (totalSell = (float)-position * log.Price); } EvaluateTrade(log.Order == Order.Sell, (log.Date - startDate).Days, realTotalBuy, realTotalSell, log.Date, dailyProfit); } if (position != 0) { _runningTrades++; } worker.ReportProgress(100 * ++count / _brandList.List.Count); } } var realPositionValues = positionValues.BookAccumulatedList; CalcMaxPosition(realPositionValues); var realProfits = profits.AccumulatedList; CalcBudget(realProfits, realPositionValues); CalcDrowdown(realProfits); return(realProfits); }