/*
 * Copyright (c) 2006-2009 OrangeSignal.com All rights reserved.
 */

package jp.sourceforge.orangesignal.trading.stats;

import java.util.Date;
import java.util.Map;

import jp.sourceforge.orangesignal.trading.backtest.Backtester;

/**
 * <p>パフォーマンス概要情報を提供します。</p>
 * 
 * @author 杉澤 浩二
 */
public class Summary extends WinLossSummary {

	private static final long serialVersionUID = 1L;

	/**
	 * シンボルとパフォーマンス統計情報のマップを指定してこのクラクを構築するコンストラクタです。
	 * 
	 * @param statsMap シンボルとパフォーマンス統計情報のマップ
	 * @param backtester バックテスト実行オブジェクト
	 */
	public Summary(final Map<String, Stats> statsMap, final Backtester backtester) {
		statistics(statsMap, backtester);
	}

	/**
	 * <p>指定されたシンボルとパフォーマンス統計情報のマップを解析して、このクラスの統計情報を設定します。</p>
	 * 
	 * @param statsMap シンボルとパフォーマンス統計情報のマップ
	 * @param backtester バックテスト実行オブジェクト
	 */
	protected void statistics(final Map<String, Stats> statsMap, final Backtester backtester) {
		super.statistics(statsMap, backtester.getInitialCapital());

		this.statsMap = statsMap;

		winSummary = new WinLossSummary(statsMap, initialCapital) {
			private static final long serialVersionUID = 1L;
			@Override protected boolean isStatistics(final Stats stats) {
				return stats.getTrades() > 0 && stats.getNetProfit() > 0.0;
			}
		};
		lossSummary = new WinLossSummary(statsMap, initialCapital) {
			private static final long serialVersionUID = 1L;
			@Override protected boolean isStatistics(final Stats stats) {
				return stats.getTrades() > 0 && stats.getNetProfit() <= 0.0;
			}
		};

		this.startDate = backtester.getStartDate();
		this.endDate = backtester.getEndDate();
	}

	@Override protected boolean isStatistics(final Stats stats) { return true/*stats.getTrades() > 0*/; }

	// ----------------------------------------------------------------------

	/**
	 * 有効なシンボルとパフォーマンス統計情報のマップを保持します。
	 */
	protected Map<String, Stats> statsMap;

	/**
	 * 有効なシンボルとパフォーマンス統計情報のマップを返します。
	 * 
	 * @return 有効なシンボルとパフォーマンス統計情報のマップ
	 */
	public Map<String, Stats> getStatsMap() { return statsMap; }

	// ----------------------------------------------------------------------

	/**
	 * 勝ちパフォーマンス概要情報を保持します。
	 */
	protected WinLossSummary winSummary;

	/**
	 * 勝ちパフォーマンス概要情報を返します。
	 * 
	 * @return 勝ちパフォーマンス概要情報
	 */
	public WinLossSummary getWinSummary() { return winSummary; }

	/**
	 * 負けパフォーマンス概要情報を保持します。
	 */
	protected WinLossSummary lossSummary;

	/**
	 * 負けパフォーマンス概要情報を返します。
	 * 
	 * @return 負けパフォーマンス概要情報
	 */
	public WinLossSummary getLossSummary() { return lossSummary; }

	// ----------------------------------------------------------------------

	/**
	 * 有効アイテム数を返します。
	 * 
	 * @return 有効アイテム数
	 */
	public int getValidCount() { return winSummary.getCount() + lossSummary.getCount(); }

	/**
	 * 有効アイテム率を返します。
	 * 
	 * @return 有効アイテム率
	 */
	public double getPercentValidCount() { return (double) getValidCount() / (double) getCount(); }

	/**
	 * 勝ちアイテム数を返します。
	 * 
	 * @return 勝ちアイテム数
	 */
	public int getWinCount() { return winSummary.getCount(); }

	/**
	 * 勝ちアイテム率を返します。
	 * 
	 * @return 勝ちアイテム率
	 */
	public double getPercentWinCount() { return getAverage(getWinCount()); }

	/**
	 * 負けアイテム数を返します。
	 * 
	 * @return 負けアイテム数
	 */
	public int getLossCount() { return lossSummary.getCount(); }

	/**
	 * 負けアイテム率を返します。
	 * 
	 * @return 負けアイテム率
	 */
	public double getPercentLossCount() { return getAverage(getLossCount()); }

	/**
	 * 有効平均損益を返します。
	 * 
	 * @return 有効平均損益
	 */
	public double getAverageNetProfitByValidCount() { return getNetProfit() / getValidCount(); }

	/**
	 * トレード平均損益を返します。
	 * 
	 * @return トレード平均損益
	 */
	public double getAverageNetProfitByTrades() { return getNetProfit() / getTrades(); }

	// ----------------------------------------------------------------------
	// バックテスト設定

	/**
	 * 開始日時を保持します。
	 */
	protected Date startDate;

	/**
	 * 開始日時を返します。
	 * 
	 * @return 開始日時。又は <code>null</code>
	 */
	public Date getStartDate() { return startDate; }

	/**
	 * 終了日時を保持します。
	 */
	protected Date endDate;

	/**
	 * 終了日時を返します。
	 * 
	 * @return 終了日時。又は <code>null</code>
	 */
	public Date getEndDate() { return endDate; }

}
