/*
 * Copyright (c) 2006-2009 OrangeSignal.com All rights reserved.
 * 
 * これは Apache ライセンス Version 2.0 (以下、このライセンスと記述) に
 * 従っています。このライセンスに準拠する場合以外、このファイルを使用
 * してはなりません。このライセンスのコピーは以下から入手できます。
 * 
 * http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 * 適用可能な法律がある、あるいは文書によって明記されている場合を除き、
 * このライセンスの下で配布されているソフトウェアは、明示的であるか暗黙の
 * うちであるかを問わず、「保証やあらゆる種類の条件を含んでおらず」、
 * 「あるがまま」の状態で提供されるものとします。
 * このライセンスが適用される特定の許諾と制限については、このライセンス
 * を参照してください。
 */

package jp.sf.orangesignal.chart.data;

import java.util.List;
import java.util.Map;

import jp.sf.orangesignal.chart.ChartSettings;
import jp.sf.orangesignal.chart.ChartSettings.TimeSeriesSettings;
import jp.sf.orangesignal.chart.ui.BandType;
import jp.sf.orangesignal.chart.ui.ChartScreenType;
import jp.sf.orangesignal.chart.ui.DatasetType;
import jp.sf.orangesignal.chart.ui.PeriodType;
import jp.sf.orangesignal.chart.ui.PriceChartType;
import jp.sf.orangesignal.chart.ui.VolumeType;
import jp.sf.orangesignal.chart.unit.BidAndOfferPriceUnits;
import jp.sf.orangesignal.ta.Aroon;
import jp.sf.orangesignal.ta.Bands2;
import jp.sf.orangesignal.ta.Bands5;
import jp.sf.orangesignal.ta.Bands7;
import jp.sf.orangesignal.ta.DMI;
import jp.sf.orangesignal.ta.FourPrice;
import jp.sf.orangesignal.ta.Histogram;
import jp.sf.orangesignal.ta.Ichimoku;
import jp.sf.orangesignal.ta.MESA;
import jp.sf.orangesignal.ta.PercentageScale;
import jp.sf.orangesignal.ta.Shinohara;
import jp.sf.orangesignal.ta.Step;
import jp.sf.orangesignal.ta.Stochastics;
import jp.sf.orangesignal.ta.TechnicalAnalysis;
import jp.sf.orangesignal.ta.candle.Candlestick;
import jp.sf.orangesignal.ta.candle.CandlestickPatterns;
import jp.sf.orangesignal.ta.candle.generator.CandlestickGenerator;
import jp.sf.orangesignal.ta.candle.generator.KagiTrendProcessor;
import jp.sf.orangesignal.ta.candle.generator.PointFigureTrendProcessor;
import jp.sf.orangesignal.ta.candle.generator.RenkohTrendProcessor;
import jp.sf.orangesignal.ta.candle.generator.ShinneTrendProcessor;
import jp.sf.orangesignal.ta.candle.generator.TrendProcessor;
import jp.sf.orangesignal.ta.util.DateArrayUtils;

/**
 * 時系列データセットを返します。
 * 
 * @author 杉澤 浩二
 */
public class TimeSeriesChartDataset extends BasicChartDataset {

	/**
	 * コンストラクタです。
	 * 
	 * @param dataset データセット
	 * @param type 足単位
	 * @param periodType 期間の種類
	 * @param settings 設定情報
	 */
	public TimeSeriesChartDataset(
		final BasicChartDataset dataset,
		final DatasetType type,
		final PeriodType periodType,
		final ChartSettings settings) {

		super(dataset);

		final TimeSeriesSettings s = settings.timeSeries;

		// ------------------------------ 価格

		if (s.avgprice) avgprice = TechnicalAnalysis.avgprice(techOpen, techHigh, techLow, techClose);
		if (s.mp) mp = TechnicalAnalysis.mp(techHigh, techLow);
		// ティピカル・プライス
		if (s.tp) tp = TechnicalAnalysis.tp(techHigh, techLow, techClose);
		// 加重終値
		if (s.wc) wc = TechnicalAnalysis.wtcl(techHigh, techLow, techClose);

		// ------------------------------ トレンド系

		// 線形回帰トレンド
		if (s.lr) {
			Map<Bands5, Number[]> map;
			map = TechnicalAnalysis.lr(techClose, s.lr1Period, 0);
			lr1_upper2 = map.get(Bands5.UPPER_BAND2);
			lr1_upper1 = map.get(Bands5.UPPER_BAND1);
			lr1 = map.get(Bands5.MIDDLE_BAND);
			lr1_lower1 = map.get(Bands5.LOWER_BAND1);
			lr1_lower2 = map.get(Bands5.LOWER_BAND2);
			map = TechnicalAnalysis.lr(techClose, s.lr2Period, 0);
			lr2_upper2 = map.get(Bands5.UPPER_BAND2);
			lr2_upper1 = map.get(Bands5.UPPER_BAND1);
			lr2 = map.get(Bands5.MIDDLE_BAND);
			lr2_lower1 = map.get(Bands5.LOWER_BAND1);
			lr2_lower2 = map.get(Bands5.LOWER_BAND2);
		}
		// 移動平均線
		if (s.ma) {
			ma1 = TechnicalAnalysis.ma(techClose, s.ma1Period, s.maType.getMovingAverage());
			ma2 = TechnicalAnalysis.ma(techClose, s.ma2Period, s.maType.getMovingAverage());
			if (s.ma1Period > s.ma2Period)
				ma_bias = TechnicalAnalysis.kairi(ma2, ma1);
			else if (s.ma1Period < s.ma2Period)
				ma_bias = TechnicalAnalysis.kairi(ma1, ma2);
		}

		// ZigZag
		if (s.zigzag) zigzag = TechnicalAnalysis.zigzag(close, s.zigzag_rate);

		// ------------------------------ バンド系

		// エンベロープ
		if (s.bandType == BandType.ENVELOPE) {
			final Map<Bands5, Number[]> map = TechnicalAnalysis.envelope(this.techClose, s.envelopePeriod, s.envelopeMaType.getMovingAverage(), s.envelopeRate);
			envelope_upper2 = map.get(Bands5.UPPER_BAND2);
			envelope_upper1 = map.get(Bands5.UPPER_BAND1);
			envelope = map.get(Bands5.MIDDLE_BAND);
			envelope_lower1 = map.get(Bands5.LOWER_BAND1);
			envelope_lower2 = map.get(Bands5.LOWER_BAND2);
		// チャネルシステム(高値安値移動平均)
		} else if (s.bandType == BandType.HIGH_LOW_MOVING_AVERAGE) {
			hma = TechnicalAnalysis.ma(techHigh, s.hmaPeriod, s.hlmaMaType.getMovingAverage());
			lma = TechnicalAnalysis.ma(techLow, s.lmaPeriod, s.hlmaMaType.getMovingAverage());
		// ドンチャンズ
		} else if (s.bandType == BandType.DONCHIAN) {
			donchian_upper = TechnicalAnalysis.highest(techHigh, s.donchianPeriod);
			donchian_lower = TechnicalAnalysis.lowest(techLow, s.donchianPeriod);
		// ボリンジャーバンド
		} else if (s.bandType == BandType.BOLLINGER_BANDS) {
			final Map<Bands5, Number[]> map = TechnicalAnalysis.bbands(techHigh, techLow, techClose, s.bbPeriod, s.bbRate);
			bb_upper2 = map.get(Bands5.UPPER_BAND2);
			bb_upper1 = map.get(Bands5.UPPER_BAND1);
			bb_tpma = map.get(Bands5.MIDDLE_BAND);
			bb_lower1 = map.get(Bands5.LOWER_BAND1);
			bb_lower2 = map.get(Bands5.LOWER_BAND2);
		// パラボリック
		} else if (s.bandType == BandType.PARABOLIC_TIME_PRICE) {
			sar = TechnicalAnalysis.sar(techHigh, techLow, techClose, s.af);
		} else if (s.bandType == BandType.PIVOT) {
			final Map<Bands7, Number[]> map = TechnicalAnalysis.pivot(techHigh, techLow, techClose);
			pivot_hbop = map.get(Bands7.UPPER_BAND3);
			pivot_s2 = map.get(Bands7.UPPER_BAND2);
			pivot_s1 = map.get(Bands7.UPPER_BAND1);
			pivot = map.get(Bands7.MIDDLE_BAND);
			pivot_b1 = map.get(Bands7.LOWER_BAND1);
			pivot_b2 = map.get(Bands7.LOWER_BAND2);
			pivot_lbop = map.get(Bands7.LOWER_BAND3);
		// ボラティリティ・システム(ATR)
		} else if (s.bandType == BandType.VIX) {
			final Map<Bands2, Number[]> map = TechnicalAnalysis.volatility(techHigh, techLow, techClose, s.atrPeriod, s.atrWeight);
			vi_upper = map.get(Bands2.UPPER_BAND);
			vi_lower = map.get(Bands2.LOWER_BAND);
		// 一目均衡表
		} else if (s.bandType == BandType.ICHIMOKU) {
			final Map<Ichimoku, Number[]> map = TechnicalAnalysis.ichimoku(techHigh, techLow, techClose, s.kijunPeriod, s.tenkanPeriod, s.spanPeriod);
			kijun = map.get(Ichimoku.KIJUN);
			tenkan = map.get(Ichimoku.TENKAN);
			senkou1 = map.get(Ichimoku.SENKOU1);
			senkou2 = map.get(Ichimoku.SENKOU2);
			chikou = map.get(Ichimoku.CHIKOU);
		// MESA 適応移動平均
		} else if (s.bandType == BandType.MESA) {
			final Map<MESA, Number[]> map = TechnicalAnalysis.mama(techClose);
			mama = map.get(MESA.MAMA);
			fama = map.get(MESA.FAMA);
		// VIDYA
		} else if (s.bandType == BandType.VIDYA) {
			vidya = TechnicalAnalysis.vidya(techClose, s.vidya_period, s.vidya_cmo_period);
		}

		// ------------------------------ オシレータ系

		// アルーン
		if (s.aroon) {
			final Map<Aroon, Number[]> map = TechnicalAnalysis.aroon(techClose, s.aroonPeriod);
			aroonUp = map.get(Aroon.AROON_UP);
			aroonDown = map.get(Aroon.AROON_DOWN);
			aroon = map.get(Aroon.AROON);
		}
		// ATR
		if (s.atr) atr = TechnicalAnalysis.atr(techHigh, techLow, techClose, s.atr_period);
		if (s.natr) natr = TechnicalAnalysis.natr(techHigh, techLow, techClose, s.natr_period);
		// BMP
		if (s.bop) bop = TechnicalAnalysis.bop(techOpen, techHigh, techLow, techClose);
		// CCI
		if (s.cci) cci = TechnicalAnalysis.cci(techHigh, techLow, techClose, s.cciPeriod);
		// チャイキンズ・ボラティリティ
		if (s.chv) chv = TechnicalAnalysis.chv(techHigh, techLow, s.chv_period1, s.chv_period2);
		// チャイキンズ・マネー・フロー
		if (s.cmf) cmf = TechnicalAnalysis.cmf(techHigh, techLow, techClose, techVolume, s.cmf_period);
		// CMO
		if (s.cmo) cmo = TechnicalAnalysis.cmo(techChange, s.cmo_period);
		// コポック
		if (s.coppock) coppock = TechnicalAnalysis.coppock(techClose, s.coppockRocPeriod, s.coppockPeriod, s.coppockMaType.getMovingAverage());
		// C-RSI
//		if (s.crsi) crsi = TechnicalAnalysis.crsi(techHigh, techLow, techClose, s.natr_period);
		// DPO
		if (s.dpo) dpo = TechnicalAnalysis.dpo(techClose, s.dpoPeriod, s.dpoMaType.getMovingAverage());
		// DMI
		if (s.dmi) {
			final Map<DMI, Number[]> map = TechnicalAnalysis.dmi(techHigh, techLow, techClose, s.diPeriod, s.adxPeriod);
			pdi = map.get(DMI.PLUS_DI);
			mdi = map.get(DMI.MINUS_DI);
			adx = map.get(DMI.ADX);
		}
		// EMV
		if (s.emv) emv = TechnicalAnalysis.emv(techHigh, techLow, techVolume, s.emv_period);
		// ヒストリカル・ボラティリティ
		if (s.hv) {
			final int days;
			if (type == DatasetType.DAILY)
				days = 250;
			else if (type == DatasetType.WEEKLY)
				days = 52;
			else if (type == DatasetType.MONTHLY)
				days = 12;
			else
				throw new RuntimeException();

			hv = TechnicalAnalysis.hv(techClose, s.hvPeriod, days);
		}
		// 移動平均乖離率
		if (s.kairi) kairi = TechnicalAnalysis.kairi(techClose, TechnicalAnalysis.ma(techClose, s.biasPeriod, s.biasMaType.getMovingAverage()));
		// マス・インデックス(MI)
		if (s.mi) mi = TechnicalAnalysis.mi(techHigh, techLow, s.miSumPeriod, s.miMaPeriod, s.miMaType.getMovingAverage());
		// モメンタム
		if (s.mom) mom = TechnicalAnalysis.mom(techClose, s.mom_period);
		// MFI
		if (s.mfi) mfi = TechnicalAnalysis.mfi(techHigh, techLow, techClose, techVolume, s.mfiPeriod);
		// MACD
		if (s.macd) {
			final Map<Histogram, Number[]> map = TechnicalAnalysis.macd(techClose, s.macdMa1Period, s.macdMa2Period, s.macdSignalPeriod, s.macdSignalMaType.getMovingAverage());
			macd = map.get(Histogram.INDICATOR);
			macdSignal = map.get(Histogram.SIGNAL);
			macdHistogram = map.get(Histogram.HISTOGRAM);
		}
		// PAIN
		if (s.pain) pain = TechnicalAnalysis.pain(techOpen, techHigh, techLow, techClose);
		// PCR
		if (s.pcr) pcr = TechnicalAnalysis.pcr(techClose, s.pcr_period);
		// プライス・オシレータ(APO)
		if (s.apo) apo = TechnicalAnalysis.apo(techClose, s.apoMa1Period, s.apoMa2Period);
		// プライス・オシレータ(PPO)
		if (s.ppo) ppo = TechnicalAnalysis.ppo(techClose, s.ppoMa1Period, s.ppoMa2Period);
		// サイコロジカルライン
		if (s.psy) psy = TechnicalAnalysis.psy(techChange, s.psy_period);
		// Qstick
		if (s.qstick) qstick = TechnicalAnalysis.qstick(techOpen, techClose, s.qstick_period, s.qstick_matype.getMovingAverage());
		// RCI
		if (s.rci) rci = TechnicalAnalysis.rci(techClose, s.rciPeriod);
		// ROC
		if (s.roc) roc = TechnicalAnalysis.roc(techClose, s.rocPeriod);
		// RSI
		if (s.rsi) rsi = TechnicalAnalysis.rsi(techChange, s.rsiPeriod);
		// RVI
		if (s.rvi) rvi = TechnicalAnalysis.rvi(techChange, s.rsiPeriod);
		// 強弱レシオ
		if (s.shinohara) {
			final Map<Shinohara, Number[]> map = TechnicalAnalysis.shinohara(techOpen, techHigh, techLow, techClose, s.shinoharaPeriod);
			shinohara_a = map.get(Shinohara.A_RATIO);
			shinohara_b = map.get(Shinohara.B_RATIO);
		}
		// ストキャスティクス
		if (s.srv) {
			final Map<Stochastics, Number[]> map = TechnicalAnalysis.srv(techHigh, techLow, techClose, s.srvKPeriod, s.srvDPeriod);
			srvK = map.get(Stochastics.K);
			srvD = map.get(Stochastics.D);
			srvSD = map.get(Stochastics.SD);
		}
		// TII
		if (s.tii) tii = TechnicalAnalysis.tii(techClose, s.tii_period, s.tii_matype.getMovingAverage());
		// トリックス(Trix)
		if (s.trix) {
			final Map<Histogram, Number[]> map = TechnicalAnalysis.trix(techClose, s.trixPeriod, s.trixSignalPeriod, s.trixSignalMaType.getMovingAverage());
			trix = map.get(Histogram.INDICATOR);
			trixSignal = map.get(Histogram.SIGNAL);
		}
		// TSI
		if (s.tsi) {
			final Map<Histogram, Number[]> map = TechnicalAnalysis.tsi(techChange, s.tsi_period1, s.tsi_period2, s.tsi_signal_period, s.tsi_signal_matype.getMovingAverage());
			tsi = map.get(Histogram.INDICATOR);
			tsi_signal = map.get(Histogram.SIGNAL);
			tsi_histogram = map.get(Histogram.HISTOGRAM);
		}
		// 究極のオシレーター
		if (s.ultimate) ultimate = TechnicalAnalysis.ultimate(techHigh, techLow, techClose, s.ultimatePeriod);
		// ウィリアムズAD
		if (s.wad) wad = TechnicalAnalysis.wad(techHigh, techLow, techClose);
		// ウィリアムズ%R
		if (s.williamsR) williamsR = TechnicalAnalysis.wr(techHigh, techLow, techClose, s.williamsRPeriod);

		// A/Dライン
		if (s.ad) ad = TechnicalAnalysis.ad(techHigh, techLow, techClose, techVolume);
		// チャイキンズA/Dオシレーター
		if (s.cho) cho = TechnicalAnalysis.cho(techHigh, techLow, techClose, techVolume, s.cho_fast, s.cho_matype.getMovingAverage(), s.cho_slow, s.cho_matype.getMovingAverage());

		// 出来高移動平均
		if (s.volumeType == VolumeType.MOVING_AVERAGE) {
			vma1 = TechnicalAnalysis.ma(techVolume, s.vma1Period, s.vmaMaType.getMovingAverage());
			vma2 = TechnicalAnalysis.ma(techVolume, s.vma2Period, s.vmaMaType.getMovingAverage());
		}
		// ボリューム・オシレータ(AVO)
		if (s.avo) avo = TechnicalAnalysis.avo(techVolume, s.avoMa1Period, s.avoMa2Period);
		// ボリューム・オシレータ(PVO)
		if (s.pvo) pvo = TechnicalAnalysis.pvo(techVolume, s.pvoMa1Period, s.pvoMa2Period);
		// 出来高乖離率
		if (s.vkairi) vkairi = TechnicalAnalysis.kairi(techVolume, TechnicalAnalysis.ma(techVolume, s.vbiasPeriod, s.vbiasMaType.getMovingAverage()));
		// ボリュームレシオ1
		if (s.vr1) vr1 = TechnicalAnalysis.vr1(techChange, techVolume, s.vr1Period);
		// ボリュームレシオ2
		if (s.vr2) vr2 = TechnicalAnalysis.vr2(techChange, techVolume, s.vr2Period);
		// 出来高ROC
		if (s.vroc) vroc = TechnicalAnalysis.roc(techVolume, s.vrocPeriod);
		// V-RSI
		if (s.vrsi) vrsi = TechnicalAnalysis.rsi(TechnicalAnalysis.chg(techVolume), s.vrsiPeriod);
		// 和光ボリュームレシオ
		if (s.wvr) wvr = TechnicalAnalysis.wvr(techChange, techVolume, s.wvrPeriod);
		// PVI
		if (s.pvi) {
			pvi = TechnicalAnalysis.pvi(techClose, techVolume);
			pvi_ma1 = TechnicalAnalysis.ma(pvi, s.pvi_fast, s.pvi_matype.getMovingAverage());
			pvi_ma2 = TechnicalAnalysis.ma(pvi, s.pvi_slow, s.pvi_matype.getMovingAverage());
		}
		// NVI
		if (s.nvi) {
			nvi = TechnicalAnalysis.nvi(techClose, techVolume);
			nvi_ma1 = TechnicalAnalysis.ma(nvi, s.nvi_fast, s.nvi_matype.getMovingAverage());
			nvi_ma2 = TechnicalAnalysis.ma(nvi, s.nvi_slow, s.nvi_matype.getMovingAverage());
		}
		// OBV
		if (s.obv) obv = TechnicalAnalysis.obv(techChange, techVolume, s.obvPeriod);
		// PVT
		if (s.pvt) pvt = TechnicalAnalysis.pvt(techClose, techVolume);

		// ------------------------------ 騰落指標

		// 騰落価格
		if (s.price_performance) price_performance = TechnicalAnalysis.performance(techClose, DateArrayUtils.lastIndexOf(date, s.priceFluctuationsPeriodType.getPreviousDate(date[date.length - 1])));
		// 騰落率
		if (s.percent_performance) percent_performance = TechnicalAnalysis.performance(techClose, DateArrayUtils.lastIndexOf(date, s.performancePeriodType.getPreviousDate(date[date.length - 1])), PercentageScale.PERCENT);

		// ------------------------------ ローソク足

		final TrendProcessor processor;
		if (s.candleTrend == ChartScreenType.POINT_AND_FIGURE) {
			processor = new PointFigureTrendProcessor(TechnicalAnalysis.pf(date, close,  settings.pf.point, settings.pf.reversal));
		} else if (s.candleTrend == ChartScreenType.KAGI || s.kagi) {
			kagi = TechnicalAnalysis.kagi(date, techClose, s.kagi_rate);
			processor = new KagiTrendProcessor(kagi);
		} else if (s.candleTrend == ChartScreenType.RENKOH) {
			final double avg = dataset.getMaxHighLowAverage();
			processor = new RenkohTrendProcessor(TechnicalAnalysis.renkoh(date, close, new BidAndOfferPriceUnits().getCeilingPriceUnit((int)avg).getPoint() * settings.renkoh.rate));
		} else if (s.candleTrend == ChartScreenType.SHINNE) {
			processor = new ShinneTrendProcessor(TechnicalAnalysis.shinne(date, close, settings.shinne.reversal));
		} else {
			processor = null;
		}
		final Candlestick[] c = new CandlestickGenerator().generate(date, open, high, low, close, processor);

		if (s.bullishLongWhiteDay) bullishLongWhiteDay = CandlestickPatterns.bullishLongWhiteDay(c);
		if (s.bullishBeltHold) bullishBeltHold = CandlestickPatterns.bullishBeltHold(c);
		if (s.bullishHammer) bullishHammer = CandlestickPatterns.bullishHammer(c);
		if (s.bullishDragonflyDoji) bullishDragonflyDoji = CandlestickPatterns.bullishDragonflyDoji(c);
		if (s.bullishLongLeggedDoji) bullishLongLeggedDoji = CandlestickPatterns.bullishLongLeggedDoji(c);
		if (s.bullishInvertedHammer) bullishInvertedHammer = CandlestickPatterns.bullishInvertedHammer(c);
		if (s.bullishHarami) bullishHarami = CandlestickPatterns.bullishHarami(c);
		if (s.bullishHaramiCross) bullishHaramiCross = CandlestickPatterns.bullishHaramiCross(c);
		if (s.bullishEngulfing) bullishEngulfing = CandlestickPatterns.bullishEngulfing(c);
		if (s.bullishGravestoneDoji) bullishGravestoneDoji = CandlestickPatterns.bullishGravestoneDoji(c);
		if (s.bullishMeetingLines) bullishMeetingLines = CandlestickPatterns.bullishMeetingLines(c);
		if (s.bullishDojiStar) bullishDojiStar = CandlestickPatterns.bullishDojiStar(c);
		if (s.bullishHomingPigeon) bullishHomingPigeon = CandlestickPatterns.bullishHomingPigeon(c);
		if (s.bullishMatchingLow) bullishMatchingLow = CandlestickPatterns.bullishMatchingLow(c);
		if (s.bullishTweezerBottom) bullishTweezerBottom = CandlestickPatterns.bullishTweezerBottom(c);
		if (s.bullishKicking) bullishKicking = CandlestickPatterns.bullishKicking(c);
		if (s.bullishPiercingLine) bullishPiercingLine = CandlestickPatterns.bullishPiercingLine(c);
		if (s.bullishSeparatingLines) bullishSeparatingLines = CandlestickPatterns.bullishSeparatingLines(c);
		if (s.bullishTriStar) bullishTriStar = CandlestickPatterns.bullishTriStar(c);
		if (s.bullishThreeStarsInTheSouth) bullishThreeStarsInTheSouth = CandlestickPatterns.bullishThreeStarsInTheSouth(c);
		if (s.bullishUniqueThreeRiverBottom) bullishUniqueThreeRiverBottom = CandlestickPatterns.bullishUniqueThreeRiverBottom(c);
		if (s.bullishStickSandwich) bullishStickSandwich = CandlestickPatterns.bullishStickSandwich(c);
		if (s.bullishAbandonedBaby) bullishAbandonedBaby = CandlestickPatterns.bullishAbandonedBaby(c);
		if (s.bullishMorningDojiStar) bullishMorningDojiStar = CandlestickPatterns.bullishMorningDojiStar(c);
		if (s.bullishMorningStar) bullishMorningStar = CandlestickPatterns.bullishMorningStar(c);
		if (s.bullishThreeOutsideUp) bullishThreeOutsideUp = CandlestickPatterns.bullishThreeOutsideUp(c);
		if (s.bullishThreeInsideUp) bullishThreeInsideUp = CandlestickPatterns.bullishThreeInsideUp(c);
		if (s.bullishThreeWhiteSoldiers) bullishThreeWhiteSoldiers = CandlestickPatterns.bullishThreeWhiteSoldiers(c);
		if (s.bullishUpsideTasukiGap) bullishUpsideTasukiGap = CandlestickPatterns.bullishUpsideTasukiGap(c);
		if (s.bullishUpsideGapThreeMethods) bullishUpsideGapThreeMethods = CandlestickPatterns.bullishUpsideGapThreeMethods(c);
		if (s.bullishSideBySideWhiteLines) bullishSideBySideWhiteLines = CandlestickPatterns.bullishSideBySideWhiteLines(c);
		if (s.bullishConcealingBabySwallow) bullishConcealingBabySwallow = CandlestickPatterns.bullishConcealingBabySwallow(c);
		if (s.bullishThreeLineStrike) bullishThreeLineStrike = CandlestickPatterns.bullishThreeLineStrike(c);
		if (s.bullishThreeGaps) bullishThreeGaps = CandlestickPatterns.bullishThreeGaps(c);
		if (s.bullishBreakaway) bullishBreakaway = CandlestickPatterns.bullishBreakaway(c);
		if (s.bullishLadderBottom) bullishLadderBottom = CandlestickPatterns.bullishLadderBottom(c);
		if (s.bullishRisingThreeMethods) bullishRisingThreeMethods = CandlestickPatterns.bullishRisingThreeMethods(c);
		if (s.bullishMatHold) bullishMatHold = CandlestickPatterns.bullishMatHold(c);

		if (s.bearishLongBlackDay) bearishLongBlackDay = CandlestickPatterns.bearishLongBlackDay(c);
		if (s.bearishBeltHold) bearishBeltHold = CandlestickPatterns.bearishBeltHold(c);
		if (s.bearishHangingMan) bearishHangingMan = CandlestickPatterns.bearishHangingMan(c);
		if (s.bearishDragonflyDoji) bearishDragonflyDoji = CandlestickPatterns.bearishDragonflyDoji(c);
		if (s.bearishLongLeggedDoji) bearishLongLeggedDoji = CandlestickPatterns.bearishLongLeggedDoji(c);
		if (s.bearishShootingStar) bearishShootingStar = CandlestickPatterns.bearishShootingStar(c);
		if (s.bearishHarami) bearishHarami = CandlestickPatterns.bearishHarami(c);
		if (s.bearishHaramiCross) bearishHaramiCross = CandlestickPatterns.bearishHaramiCross(c);
		if (s.bearishEngulfing) bearishEngulfing = CandlestickPatterns.bearishEngulfing(c);
		if (s.bearishGravestoneDoji) bearishGravestoneDoji = CandlestickPatterns.bearishGravestoneDoji(c);
		if (s.bearishMeetingLines) bearishMeetingLines = CandlestickPatterns.bearishMeetingLines(c);
		if (s.bearishDojiStar) bearishDojiStar = CandlestickPatterns.bearishDojiStar(c);
		if (s.bearishDescendingHawk) bearishDescendingHawk = CandlestickPatterns.bearishDescendingHawk(c);
		if (s.bearishMatchingHigh) bearishMatchingHigh = CandlestickPatterns.bearishMatchingHigh(c);
		if (s.bearishTweezerTop) bearishTweezerTop = CandlestickPatterns.bearishTweezerTop(c);
		if (s.bearishKicking) bearishKicking = CandlestickPatterns.bearishKicking(c);
		if (s.bearishDarkCloudCover) bearishDarkCloudCover = CandlestickPatterns.bearishDarkCloudCover(c);
		if (s.bearishSeparatingLines) bearishSeparatingLines = CandlestickPatterns.bearishSeparatingLines(c);
		if (s.bearishThrusting) bearishThrusting = CandlestickPatterns.bearishThrusting(c);
		if (s.bearishOnNeck) bearishOnNeck = CandlestickPatterns.bearishOnNeck(c);
		if (s.bearishInNeck) bearishInNeck = CandlestickPatterns.bearishInNeck(c);
		if (s.bearishTriStar) bearishTriStar = CandlestickPatterns.bearishTriStar(c);
		if (s.bearishTwoCrows) bearishTwoCrows = CandlestickPatterns.bearishTwoCrows(c);
		if (s.bearishAdvanceBlock) bearishAdvanceBlock = CandlestickPatterns.bearishAdvanceBlock(c);
		if (s.bearishDeliberation) bearishDeliberation = CandlestickPatterns.bearishDeliberation(c);
		if (s.bearishAbandonedBaby) bearishAbandonedBaby = CandlestickPatterns.bearishAbandonedBaby(c);
		if (s.bearishEveningDojiStar) bearishEveningDojiStar = CandlestickPatterns.bearishEveningDojiStar(c);
		if (s.bearishEveningStar) bearishEveningStar = CandlestickPatterns.bearishEveningStar(c);
		if (s.bearishThreeOutsideDown) bearishThreeOutsideDown = CandlestickPatterns.bearishThreeOutsideDown(c);
		if (s.bearishThreeInsideDown) bearishThreeInsideDown = CandlestickPatterns.bearishThreeInsideDown(c);
		if (s.bearishUpsideGapTwoCrows) bearishUpsideGapTwoCrows = CandlestickPatterns.bearishUpsideGapTwoCrows(c);
		if (s.bearishThreeBlackCrows) bearishThreeBlackCrows = CandlestickPatterns.bearishThreeBlackCrows(c);
		if (s.bearishIdenticalThreeCrows) bearishIdenticalThreeCrows = CandlestickPatterns.bearishIdenticalThreeCrows(c);
		if (s.bearishDownsideTasukiGap) bearishDownsideTasukiGap = CandlestickPatterns.bearishDownsideTasukiGap(c);
		if (s.bearishDownsideGapThreeMethods) bearishDownsideGapThreeMethods = CandlestickPatterns.bearishDownsideGapThreeMethods(c);
		if (s.bearishSideBySideWhiteLines) bearishSideBySideWhiteLines = CandlestickPatterns.bearishSideBySideWhiteLines(c);
		if (s.bearishThreeLineStrike) bearishThreeLineStrike = CandlestickPatterns.bearishThreeLineStrike(c);
		if (s.bearishThreeGaps) bearishThreeGaps = CandlestickPatterns.bearishThreeGaps(c);
		if (s.bearishBreakaway) bearishBreakaway = CandlestickPatterns.bearishBreakaway(c);
		if (s.bearishFallingThreeMethods) bearishFallingThreeMethods = CandlestickPatterns.bearishFallingThreeMethods(c);

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

		// 平均コマ足
		if (s.chartType == PriceChartType.HEIKIN) {
			final Map<FourPrice, Number[]> map = TechnicalAnalysis.heikin(techOpen, techHigh, techLow, techClose);
			this.open = map.get(FourPrice.OPEN);
			this.close = map.get(FourPrice.CLOSE);
		}
	}

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

	public Number[] avgprice;
	public Number[] mp;
	public Number[] tp;
	public Number[] wc;


	public Number[] zigzag;

	// ------------------------------ ローソク足

	public List<Step> kagi;

	public boolean[] bullishLongWhiteDay;
	public boolean[] bullishBeltHold;
	public boolean[] bullishHammer;
	public boolean[] bullishDragonflyDoji;
	public boolean[] bullishLongLeggedDoji;
	public boolean[] bullishInvertedHammer;
	public boolean[] bullishHarami;
	public boolean[] bullishHaramiCross;
	public boolean[] bullishEngulfing;
	public boolean[] bullishGravestoneDoji;
	public boolean[] bullishMeetingLines;
	public boolean[] bullishDojiStar;
	public boolean[] bullishHomingPigeon;
	public boolean[] bullishMatchingLow;
	public boolean[] bullishTweezerBottom;
	public boolean[] bullishKicking;
	public boolean[] bullishPiercingLine;
	public boolean[] bullishSeparatingLines;
	public boolean[] bullishTriStar;
	public boolean[] bullishThreeStarsInTheSouth;
	public boolean[] bullishUniqueThreeRiverBottom;
	public boolean[] bullishStickSandwich;
	public boolean[] bullishAbandonedBaby;
	public boolean[] bullishMorningDojiStar;
	public boolean[] bullishMorningStar;
	public boolean[] bullishThreeOutsideUp;
	public boolean[] bullishThreeInsideUp;
	public boolean[] bullishThreeWhiteSoldiers;
	public boolean[] bullishUpsideTasukiGap;
	public boolean[] bullishUpsideGapThreeMethods;
	public boolean[] bullishSideBySideWhiteLines;
	public boolean[] bullishConcealingBabySwallow;
	public boolean[] bullishThreeLineStrike;
	public boolean[] bullishThreeGaps;
	public boolean[] bullishBreakaway;
	public boolean[] bullishLadderBottom;
	public boolean[] bullishRisingThreeMethods;
	public boolean[] bullishMatHold;

	public boolean[] bearishLongBlackDay;
	public boolean[] bearishBeltHold;
	public boolean[] bearishHangingMan;
	public boolean[] bearishDragonflyDoji;
	public boolean[] bearishLongLeggedDoji;
	public boolean[] bearishShootingStar;
	public boolean[] bearishHarami;
	public boolean[] bearishHaramiCross;
	public boolean[] bearishEngulfing;
	public boolean[] bearishGravestoneDoji;
	public boolean[] bearishMeetingLines;
	public boolean[] bearishDojiStar;
	public boolean[] bearishDescendingHawk;
	public boolean[] bearishMatchingHigh;
	public boolean[] bearishTweezerTop;
	public boolean[] bearishKicking;
	public boolean[] bearishDarkCloudCover;
	public boolean[] bearishSeparatingLines;
	public boolean[] bearishThrusting;
	public boolean[] bearishOnNeck;
	public boolean[] bearishInNeck;
	public boolean[] bearishTriStar;
	public boolean[] bearishTwoCrows;
	public boolean[] bearishAdvanceBlock;
	public boolean[] bearishDeliberation;
	public boolean[] bearishAbandonedBaby;
	public boolean[] bearishEveningDojiStar;
	public boolean[] bearishEveningStar;
	public boolean[] bearishThreeOutsideDown;
	public boolean[] bearishThreeInsideDown;
	public boolean[] bearishUpsideGapTwoCrows;
	public boolean[] bearishThreeBlackCrows;
	public boolean[] bearishIdenticalThreeCrows;
	public boolean[] bearishDownsideTasukiGap;
	public boolean[] bearishDownsideGapThreeMethods;
	public boolean[] bearishSideBySideWhiteLines;
	public boolean[] bearishThreeLineStrike;
	public boolean[] bearishThreeGaps;
	public boolean[] bearishBreakaway;
	public boolean[] bearishFallingThreeMethods;

	// ------------------------------ 移動平均

	/**
	 * 移動平均1を保持します。
	 */
	public Number[] ma1;

	/**
	 * 移動平均2を保持します。
	 */
	public Number[] ma2;

	/**
	 * 移動平均間の乖離率を保持します。
	 */
	public Number[] ma_bias;

	// ------------------------------ 線形回帰トレンド

	public Number[] lr1_upper2;
	public Number[] lr1_upper1;
	public Number[] lr1;
	public Number[] lr1_lower1;
	public Number[] lr1_lower2;

	public Number[] lr2_upper2;
	public Number[] lr2_upper1;
	public Number[] lr2;
	public Number[] lr2_lower1;
	public Number[] lr2_lower2;

	// ------------------------------ ボリンジャーバンド

	public Number[] bb_upper2;
	public Number[] bb_upper1;
	public Number[] bb_tpma;
	public Number[] bb_lower1;
	public Number[] bb_lower2;

	// ------------------------------ ドンチャンズ

	public Number[] donchian_upper;
	public Number[] donchian_lower;

	// ------------------------------ エンベロープ(Envelope)

	public Number[] envelope_upper2;
	public Number[] envelope_upper1;
	public Number[] envelope;
	public Number[] envelope_lower1;
	public Number[] envelope_lower2;

	// ------------------------------ 高値安値移動平均(チャネルシステム)

	/**
	 * 高値移動平均を保持します。
	 */
	public Number[] hma;

	/**
	 * 安値移動平均を保持します。
	 */
	public Number[] lma;

	// ------------------------------ パラボリック

	public Number[] sar;

	// ------------------------------ ピボット

	public Number[] pivot_hbop;
	public Number[] pivot_s2;
	public Number[] pivot_s1;
	public Number[] pivot;
	public Number[] pivot_b1;
	public Number[] pivot_b2;
	public Number[] pivot_lbop;

	// ------------------------------ ボラティリティ・システム

	public Number[] vi_upper;
	public Number[] vi_lower;

	// ------------------------------ 一目均衡表

	/**
	 * 一目均衡表の基準値のリストを保持します。
	 */
	public Number[] kijun;

	/**
	 * 一目均衡表の転換値のリストを保持します。
	 */
	public Number[] tenkan;

	/**
	 * 一目均衡表の先行スパン1のリストを保持します。
	 */
	public Number[] senkou1;

	/**
	 * 一目均衡表の先行スパン2のリストを保持します。
	 */
	public Number[] senkou2;

	/**
	 * 一目均衡表の遅行スパンのリストを保持します。
	 */
	public Number[] chikou;

	// ------------------------------ MESA

	public Number[] mama;
	public Number[] fama;

	// ------------------------------ VIDYA

	public Number[] vidya;

	// ------------------------------ アルーン

	/**
	 * アルーンアップを保持します。
	 */
	public Number[] aroonUp;

	/**
	 * アルーンダウンを保持します。
	 */
	public Number[] aroonDown;

	/**
	 * アルーンを保持します。
	 */
	public Number[] aroon;

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

	public Number[] atr;
	public Number[] natr;
	public Number[] bop;

	// ------------------------------ チャイキンズ・ボラティリティ

	/**
	 * チャイキンズ・ボラティリティのリストを保持します。
	 */
	public Number[] chv;

	// ------------------------------ CCI

	/**
	 * CCIのリストを保持します。
	 */
	public Number[] cci;

	// ------------------------------ チャイキンズマネーフロー

	public Number[] cmf;

	// ------------------------------ CMO

	public Number[] cmo;

	// ------------------------------ コポック買い指標

	/**
	 * コポック買い指標のリストを保持します。
	 */
	public Number[] coppock;

	// ------------------------------ C-RSI

	public Number[] crsi;

	// ------------------------------ DPO

	public Number[] dpo;

	// ------------------------------ DMI

	public Number[] pdi;
	public Number[] mdi;
	public Number[] adx;

	public Number[] emv;

	// ------------------------------ ヒストリカル・ボラティリティ

	public Number[] hv;

	// ------------------------------ 移動平均乖離率

	/**
	 * 移動平均乖離率を保持します。
	 */
	public Number[] kairi;

	// ------------------------------ マス・インデックス(MI)

	public Number[] mi;

	// ------------------------------ モメンタム(Momentum)

	public Number[] mom;

	// ------------------------------ MFI

	/**
	 * MFI(Money Flow Index)のリストを保持します。
	 */
	public Number[] mfi;

	// ------------------------------ MACD

	public Number[] macd;
	public Number[] macdSignal;
	public Number[] macdHistogram;

	// ------------------------------ PAIN

	public Number[] pain;

	// ------------------------------ PCR

	public Number[] pcr;
	
	// ------------------------------ プライス・オシレータ(APO)

	/**
	 * プライス・オシレータ(APO)を保持します。
	 */
	public Number[] apo;

	// ------------------------------ プライス・オシレータ(PPO)

	/**
	 * プライス・オシレータ(PPO)を保持します。
	 */
	public Number[] ppo;

	// ------------------------------ サイコロジカルライン(Psychological line)

	public Number[] psy;

	// ------------------------------ Qstick

	public Number[] qstick;

	// ------------------------------ RSI

	/**
	 * RSI(Relative Strength Index/相対力指数)のリストを保持します。
	 */
	public Number[] rsi;

	public Number[] rvi;

	// ------------------------------ RCI

	/**
	 * RCI(Rank Correlation Index/順位相関数)のリストを保持します。
	 */
	public Number[] rci;

	// ------------------------------ ROC (Rate of Change)

	public Number[] roc;

	// ------------------------------ 強弱レシオ(篠原レシオ)

	public Number[] shinohara_a;
	public Number[] shinohara_b;

	// ------------------------------ ストキャスティクス(Stochastics)

	public Number[] srvK;
	public Number[] srvD;
	public Number[] srvSD;

	// ------------------------------ TII

	public Number[] tii;

	// ------------------------------ トリックス(Trix)

	/**
	 * トリックス(Trix)のリストを保持します。
	 */
	public Number[] trix;

	/**
	 * トリックス(Trix)シグナルのリストを保持します。
	 */
	public Number[] trixSignal;

	// ------------------------------ TSI

	public Number[] tsi;
	public Number[] tsi_signal;
	public Number[] tsi_histogram;

	// ------------------------------ 究極のオシレーター(Ultimate OSI)

	/**
	 * 究極のオシレーター(Ultimate OSI)のリストを保持します。
	 */
	public Number[] ultimate;

	// ------------------------------ ウィリアムズAD

	/**
	 * ウィリアムズADのリストを保持します。
	 */
	public Number[] wad;

	// ------------------------------ ウィリアムズ%R

	/**
	 * ウィリアムズ%Rのリストを保持します。
	 */
	public Number[] williamsR;

	// ------------------------------ A/Dライン

	/**
	 * A/Dラインを保持します。
	 */
	public Number[] ad;

	// ------------------------------ チャイキンズA/Dオシレーター

	public Number[] cho;

	// ------------------------------ 出来高移動平均

	/**
	 * 出来高移動平均1のリストを保持します。
	 */
	public Number[] vma1;

	/**
	 * 出来高移動平均2のリストを保持します。
	 */
	public Number[] vma2;

	// ------------------------------ 出来高乖離率

	/**
	 * 出来高乖離率を保持します。
	 */
	public Number[] vkairi;

	// ------------------------------ ボリューム・オシレータ

	/**
	 * ボリューム・オシレータ(AVO)のリストを保持します。
	 */
	public Number[] avo;

	/**
	 * ボリューム・オシレータ(PVO)のリストを保持します。
	 */
	public Number[] pvo;

	// ------------------------------ ボリュームレシオ

	/**
	 * ボリュームレシオ1(Volume Ratio 1)のリストを保持します。
	 */
	public Number[] vr1;

	/**
	 * ボリュームレシオ2(Volume Ratio 2)のリストを保持します。
	 */
	public Number[] vr2;

	// ------------------------------ 出来高ROC

	/**
	 * 出来高ROCのリストを保持します。
	 */
	public Number[] vroc;

	// ------------------------------ V-RSI

	/**
	 * V-RSI(Volume Relative Strength Index/出来高株価相対力指数)のリストを保持します。
	 */
	public Number[] vrsi;

	/**
	 * ワコーボリュームレシオ(Wako Volume Ratio)のリストを保持します。(100 ～ -100)
	 */
	public Number[] wvr;

	// ------------------------------ PVI

	public Number[] pvi;
	public Number[] pvi_ma1;
	public Number[] pvi_ma2;

	// ------------------------------ NVI

	public Number[] nvi;
	public Number[] nvi_ma1;
	public Number[] nvi_ma2;

	// ------------------------------ OBV

	/**
	 * OBV (On Balance Volume) の配列を保持します。
	 */
	public Number[] obv;

	// ------------------------------ PVT

	public Number[] pvt;

	// ------------------------------ 騰落価格

	/**
	 * 騰落価格のリストを保持します。
	 */
	public Number[] price_performance;

	// ------------------------------ 騰落率

	/**
	 * 騰落率のリストを保持します。
	 */
	public Number[] percent_performance;

	// ------------------------------ レシオケーター

	/**
	 * レシオケーターのリストを保持します。
	 */
	public Number[] ratiocater;

}
