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

package jp.sf.orangesignal.ta.candle.generator;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import jp.sf.orangesignal.ta.TechnicalAnalysis;
import jp.sf.orangesignal.ta.candle.Candlestick;

import org.junit.Test;

/**
 * {@link CandlestickGenerator} クラスの単体テストです。
 * 
 * @author 杉澤 浩二
 */
public class CandlestickGeneratorTest {

	@Test
	public void デフォルトコンストラクタ() {
		final CandlestickGenerator generator = new CandlestickGenerator();
		assertNotNull(generator.settings);
	}

	@Test
	public void コンストラクタ() {
		final CandlestickGeneratorSettings settings = new DefaultCandlestickGeneratorSettings();
		final CandlestickGenerator generator = new CandlestickGenerator(settings);
		assertEquals(generator.settings, settings);
	}

	@Test
	public void settings() {
		final CandlestickGeneratorSettings settings = new DefaultCandlestickGeneratorSettings();
		final CandlestickGenerator generator = new CandlestickGenerator();
		generator.setSettings(settings);
		assertEquals(generator.getSettings(), settings);
	}

	@Test
	public void generate_4本値() {
		final Number[] o = new Number[]{};
		final Number[] h = new Number[]{};
		final Number[] l = new Number[]{};
		final Number[] c = new Number[]{};
		final CandlestickGenerator generator = new CandlestickGenerator();
		assertNotNull(generator.generate(o, h, l, c));
	}

	@Test
	public void generate_日時・4本値() {
		final Date[] d = new Date[]{};
		final Number[] o = new Number[]{};
		final Number[] h = new Number[]{};
		final Number[] l = new Number[]{};
		final Number[] c = new Number[]{};
		final CandlestickGenerator generator = new CandlestickGenerator();
		assertNotNull(generator.generate(d, o, h, l, c));
	}

	@Test
	public void generate_日時・4本値・トレンド() {
		final Date[] d = new Date[]{};
		final Number[] o = new Number[]{};
		final Number[] h = new Number[]{};
		final Number[] l = new Number[]{};
		final Number[] c = new Number[]{};
		final CandlestickGenerator generator = new CandlestickGenerator();
		assertNotNull(generator.generate(d, o, h, l, c, null));
	}

	@Test
	public void generate() {
		final int n = 100;
		final Date[] date = new Date[n * 2];
		final Number[] open = new Number[n * 2];
		final Number[] high = new Number[n * 2];
		final Number[] low = new Number[n * 2];
		final Number[] close = new Number[n * 2];

		final Calendar calendar = Calendar.getInstance(Locale.JAPANESE);
		calendar.set(2000, 1, 1);
		for (int i = 0; i < 50; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 2 + i;
			close[i] = 4 + i;
			calendar.add(Calendar.DATE, 1);
		}
		for (int i = 50; i < 100; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 1 + i;
			close[i] = 2 + i;
			calendar.add(Calendar.DATE, 1);
		}
		for (int i = 100; i < 200; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + 100 - i;
			high[i] = 5 + 100 - i;
			low[i] = 2 + 100 - i;
			close[i] = 4 + 100 - i;
			calendar.add(Calendar.DATE, 1);
		}

		open[0] = high[0] = low[0] = close[0] = null;
		open[100] = high[100] = low[100] = close[100] = 5;

		final CandlestickGeneratorSettings settings = new DefaultCandlestickGeneratorSettings();
		Candlestick[] candlestick;
		candlestick = CandlestickGenerator.generate(date, open, high, low, close, new PointFigureTrendProcessor(TechnicalAnalysis.pf(date, close, 0.05D, 3)), settings);
		assertNotNull(candlestick);
		candlestick = CandlestickGenerator.generate(date, open, high, low, close, new KagiTrendProcessor(TechnicalAnalysis.kagi(date, close, 0.05D)), settings);
		assertNotNull(candlestick);
		candlestick = CandlestickGenerator.generate(date, open, high, low, close, new RenkohTrendProcessor(TechnicalAnalysis.renkoh(date, close, 0.05D)), settings);
		assertNotNull(candlestick);
		candlestick = CandlestickGenerator.generate(date, open, high, low, close, new ShinneTrendProcessor(TechnicalAnalysis.shinne(date, close, 10)), settings);
		assertNotNull(candlestick);
		candlestick = CandlestickGenerator.generate(date, open, high, low, close, new ParabolicSarTrendProcessor(TechnicalAnalysis.sar(high, low, close, 0.05D)), settings);
		assertNotNull(candlestick);
	}

	@Test(expected = TrendProcessorException.class)
	public void generate_PointFigureTrendProcessor_TrendProcessorException() {
		final int n = 100;
		final Date[] date = new Date[n * 2];
		final Number[] open = new Number[n * 2];
		final Number[] high = new Number[n * 2];
		final Number[] low = new Number[n * 2];
		final Number[] close = new Number[n * 2];

		final Calendar calendar = Calendar.getInstance(Locale.JAPANESE);
		calendar.set(2000, 1, 1);
		for (int i = 0; i < 50; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 2 + i;
			close[i] = 4 + i;
			calendar.add(Calendar.DATE, 1);
		}
		date[0] = null;

		new CandlestickGenerator().generate(date, open, high, low, close, new PointFigureTrendProcessor(TechnicalAnalysis.pf(date, close, 0.05D, 3)));
	}

	@Test(expected = TrendProcessorException.class)
	public void generate_KagiTrendProcessor_TrendProcessorException() {
		final int n = 100;
		final Date[] date = new Date[n * 2];
		final Number[] open = new Number[n * 2];
		final Number[] high = new Number[n * 2];
		final Number[] low = new Number[n * 2];
		final Number[] close = new Number[n * 2];

		final Calendar calendar = Calendar.getInstance(Locale.JAPANESE);
		calendar.set(2000, 1, 1);
		for (int i = 0; i < 50; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 2 + i;
			close[i] = 4 + i;
			calendar.add(Calendar.DATE, 1);
		}
		date[0] = null;

		new CandlestickGenerator().generate(date, open, high, low, close, new KagiTrendProcessor(TechnicalAnalysis.kagi(date, close, 0.05D)));
	}

	@Test(expected = TrendProcessorException.class)
	public void generate_RenkohTrendProcessor_TrendProcessorException() {
		final int n = 100;
		final Date[] date = new Date[n * 2];
		final Number[] open = new Number[n * 2];
		final Number[] high = new Number[n * 2];
		final Number[] low = new Number[n * 2];
		final Number[] close = new Number[n * 2];

		final Calendar calendar = Calendar.getInstance(Locale.JAPANESE);
		calendar.set(2000, 1, 1);
		for (int i = 0; i < 50; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 2 + i;
			close[i] = 4 + i;
			calendar.add(Calendar.DATE, 1);
		}
		date[0] = null;

		new CandlestickGenerator().generate(date, open, high, low, close, new RenkohTrendProcessor(TechnicalAnalysis.renkoh(date, close, 0.05D)));
	}

	@Test(expected = TrendProcessorException.class)
	public void generate_ShinneTrendProcessor_TrendProcessorException() {
		final int n = 100;
		final Date[] date = new Date[n * 2];
		final Number[] open = new Number[n * 2];
		final Number[] high = new Number[n * 2];
		final Number[] low = new Number[n * 2];
		final Number[] close = new Number[n * 2];

		final Calendar calendar = Calendar.getInstance(Locale.JAPANESE);
		calendar.set(2000, 1, 1);
		for (int i = 0; i < 50; i++) {
			date[i] = calendar.getTime();
			open[i] = 3 + i;
			high[i] = 5 + i;
			low[i] = 2 + i;
			close[i] = 4 + i;
			calendar.add(Calendar.DATE, 1);
		}
		date[0] = null;

		new CandlestickGenerator().generate(date, open, high, low, close, new ShinneTrendProcessor(TechnicalAnalysis.shinne(date, close, 10)));
	}

}
