
import java.util.ArrayList;
import java.util.Calendar;

import jp.tradesc.superkaburobo.sdk.driver.RobotDriver;
import jp.tradesc.superkaburobo.sdk.robot.AbstractRobot;
import jp.tradesc.superkaburobo.sdk.trade.EnumAnalysisSpan;
import jp.tradesc.superkaburobo.sdk.trade.EnumCurrentSession;
import jp.tradesc.superkaburobo.sdk.trade.InformationManager;
import jp.tradesc.superkaburobo.sdk.trade.OrderManager;
import jp.tradesc.superkaburobo.sdk.trade.TimeManager;
import jp.tradesc.superkaburobo.sdk.trade.TradeAgent;
import jp.tradesc.superkaburobo.sdk.trade.analysis.technicalindex.BollingerBand;
import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio;
import jp.tradesc.superkaburobo.sdk.trade.data.Stock;
import jp.tradesc.superkaburobo.sdk.trade.data.StockData;

public class BBRobot1 extends AbstractRobot {

	@Override
	public void order(TradeAgent arg0) {
		// TODO Auto-generated method stub
		TimeManager timeManager = arg0.getTimeManager();
		if( timeManager.getCurrentSession() == EnumCurrentSession.EARLY_SESSION ){
			//. 前場のみ売買する

			//. 売買候補リストを用意
			ArrayList<Stock> buyList = new ArrayList<Stock>();
			ArrayList<Stock> sellList = new ArrayList<Stock>();
			
			//. １営業日前と２営業日前のデータを取得・比較する
			Calendar c1 = timeManager.getBusinessDay( -1 ); //. １営業日前
			Calendar c2 = timeManager.getBusinessDay( -( 2 + 1 ) ); //. ２営業日前

			//. ボリンジャーバンド指標（20日）
			BollingerBand bb = arg0.getAnalysisManager().getBollingerBand( EnumAnalysisSpan.DAILY, 20 );
			
			InformationManager informationManager = arg0.getInformationManager();
			OrderManager orderManager = arg0.getOrderManager();
			
			ArrayList<Stock> stockList = informationManager.getStockList();
			for( Stock stock : stockList ){
				try{
					//. １営業日前と２営業日前の株価データを取得
					ArrayList<StockData> stockDataList
	                		= informationManager.getStockDailyByInterval( c2, c1, stock );

					Double v1 = ( double )( stockDataList.get( 0 ).getClosingPrice() ); //. １営業日前の終値
					Double v2 = ( double )( stockDataList.get( 1 ).getClosingPrice() ); //. ２営業日前の終値
					
					Double m1 = bb.getIndexMinus2( stock, 1 ); //. １営業日前の -2σ（偏差値30）の値
					Double m2 = bb.getIndexMinus2( stock, 2 ); //. ２営業日前の -2σ（偏差値30）の値
					Double p1 = bb.getIndexPlus2( stock, 1 ); //. １営業日前の +2σ（偏差値70）の値
					Double p2 = bb.getIndexPlus2( stock, 2 ); //. ２営業日前の +2σ（偏差値70）の値
					
					if( v2 <= m2 && v1 > m1 ){
						//. 株価の偏差値が30以下から30以上になっていたら、買いリストに追加
						buyList.add( stock );
					}else if( v2 >= p2 && v1 < p1 ){
						//. 株価の偏差値が70以上から70以下になっていたら、売りリストに追加
						sellList.add( stock );
					}
				}catch( Exception e ){
					e.printStackTrace();
				}
			}

			//. 決済注文
			ArrayList<Portfolio> portfolioList = arg0.getPortfolioManager().getPortfolio();
			for( Portfolio portfolio : portfolioList ){
				int qty = portfolio.getExecQty();
				if( qty > 0 ){
					//. 買い注文に対しては売りリストと比較
					for( Stock stock : sellList ){
						if( portfolio.getStock().equals( stock ) ){
							//. 決済
							portfolio.orderReverseNowMarketAll();
						}
					}
				}else{
					//. 売り注文に対しては買いリストと比較
					for( Stock stock : buyList ){
						if( portfolio.getStock().equals( stock ) ){
							//. 決済
							portfolio.orderReverseNowMarketAll();
						}
					}
				}
			}
			
			//. 新規注文
			for( Stock stock : buyList ){
				//. 単元数だけ買い注文
				orderManager.orderActualNowMarket( stock, stock.getUnit() );
			}
			for( Stock stock : sellList ){
				//. 単元数だけ空売り注文
				int cp = informationManager.getStockSession( stock ).getClosingPrice();
				int spread = informationManager.checkSpread( cp );
				//orderManager.orderCreditNowMarket( stock, -1 * stock.getUnit() ); //. こっちだと成立しない・・・
				orderManager.orderCreditNowLimit( stock, cp + spread, -1 * stock.getUnit() );
			}
		}
	}

	@Override
	public void screening(TradeAgent arg0) {
		// TODO Auto-generated method stub

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] arg = { "-n", "me.juge.kaburobocolumn.BBRobot1" };
		RobotDriver.main( arg );
	}

}

