import java.util.ArrayList; import jp.tradesc.superkaburobo.sdk.trade.InformationManager; import jp.tradesc.superkaburobo.sdk.trade.OrderManager; import jp.tradesc.superkaburobo.sdk.trade.RobotLogManager; import jp.tradesc.superkaburobo.sdk.trade.TimeManager; import jp.tradesc.superkaburobo.sdk.trade.TradeAgent; import jp.tradesc.superkaburobo.sdk.trade.data.Portfolio; import jp.tradesc.superkaburobo.sdk.trade.data.Stock; import jp.tradesc.superkaburobo.sdk.trade.data.StockData; /** * トレーリングストップのサンプルロボット * @author (c) 2004-2007 kaburobo.jp and Trade Science Corp. All rights reserved. */ public class TrailingStopSampleRobot extends SampleRobot { @Override public void order(TradeAgent tradeAgent) { // 保存してあるメモを取得します。 SampleObjectMemo memo = (SampleObjectMemo) tradeAgent.getMemoManager().getObjectMemo(); // メモが null の時のことを考えて null チェックをします。 if(memo == null) return; // シグナルと反対のポジションを解消します。 orderReverseBySignal(memo); // ポートフォリオを参照します ArrayList portfolioList = tradeAgent.getPortfolioManager().getPortfolio(); for (Portfolio portfolio : portfolioList) { // トレーリングストップ注文を行います。 orderTrailingStop(portfolio, 5.0, 7.0, 6.0, 300); } // 新規注文を行います。 orderNew(memo); // 後場に同じものを購入しないように、メモの注文予定リストを削除します。 // 前場に約定しなかった注文は自動的に後場に引き継がれますので問題ありません。 memo.setMemoList(null); tradeAgent.getMemoManager().setObjectMemo(memo); } /** * トレーリングストップ注文を行います。 * @param portfolio 対象ポートフォリオ * @param targetRate 利益確定目標値(%)。5と指定すると、含み益が5%を超えた時点からストップロスの逆指値注文を行います。 * @param stopLossRate ストップロス幅(%)。2と指定すると、含み益の過去最高より2%安い(信用売りの場合は高い)価格で逆指値注文を行います。 * @param lossCutRate 損切り率(%)。3と指定すると、含み損が3%を上回ったら即時成行で反対注文を行います。 * @param maxHoldingDays 最長ホールド日数(日)。どのような場合でも、この期間が過ぎたら即時成行で反対注文を行います。 */ protected void orderTrailingStop( Portfolio portfolio, double targetRate, double stopLossRate, double lossCutRate, int maxHoldingDays ){ // オーダータイミング1:保有日数が制限を超えると反対売買します。 if (maxHoldingDays < portfolio.getHoldingDays()) { orderReverseForPortfolio(portfolio, "保有日数制限越え"); return; } // --------------------------------------- // ピークや各種価格の計算 セクション // --------------------------------------- TimeManager tm = TimeManager.getInstance(); InformationManager im = InformationManager.getInstance(); Stock stock = portfolio.getStock(); //購入時の株価 int execPrice = portfolio.getExecPrice(); // 保有期間中の最高値と最安値を算出 (初期値は約定価格) int peakPrice = execPrice; int bottomPrice = execPrice; // 保有銘柄の期間中の株価をリストとして取得します ArrayList stockDataList = im.getStockSessionByInterval( portfolio.getExecDate(), tm.getCurrentDate(), stock); for(int i=0;i stockData.getClosingPrice()) bottomPrice = stockData.getClosingPrice(); } else { if(peakPrice < stockData.getHighPrice()) peakPrice = stockData.getHighPrice(); if(bottomPrice > stockData.getLowPrice()) bottomPrice = stockData.getLowPrice(); } } // ------------------------------------ // 反対売買の実行 // ------------------------------------ if (portfolio.getExecQty() > 0 ) { // 現物買いトレードについての判断 // オーダータイミング2:ストップロスの逆指値注文を行います。 // 買付け後の最大利益率 double profitPeakRatio = ((double)peakPrice / execPrice - 1) * 100; String msg = String.format( "買いトレードのトレーリングストップの判断を行います。" + "銘柄コード:%4d 取得価格:%,9d 取得後の高値:%,9d 取得後の最大含み益:%6.2f(%%)", stock.getStockCode(), execPrice, peakPrice, profitPeakRatio ); RobotLogManager.getInstance().log(msg, 3); // 目標達成の判定 if( profitPeakRatio > targetRate ) { // 逆指値注文価格 int orderPrice = (int)(peakPrice * (1 - (stopLossRate / 100))); orderReverseStopForPortfolio( portfolio, orderPrice, "トレーリングストップによる売却 取得後の高値:" + peakPrice ); return; } // オーダータイミング3:損切りの対象です。 // 現物買いトレードの場合の損切り int lossCutPrice = (int)(execPrice * (1 - (lossCutRate / 100))); //損切りのための逆指値注文を行います。 orderReverseStopForPortfolio( portfolio, lossCutPrice, "現物買いの損切り:" ); } else { // 信用売りトレードについての判断 // オーダータイミング2:ストップロスの逆指値注文を行います。 // 信用売り後の最大利益率 double profitPeakRatio = (1 - (double)bottomPrice / execPrice) * 100; String msg = String.format( "売りトレードのトレーリングストップの判断を行います。" + "銘柄コード:%4d 取得価格:%,9d 取得後の安値:%,9d 取得後の最大含み益:%6.2f(%%)", stock.getStockCode(), execPrice, peakPrice, profitPeakRatio ); RobotLogManager.getInstance().log(msg, 3); // 目標達成の判定 if( profitPeakRatio > targetRate ) { // 逆指値注文価格 int orderPrice = (int)(bottomPrice * ((stopLossRate / 100) + 1)); // 反転値で逆指値注文を行います。 orderReverseStopForPortfolio( portfolio, orderPrice, "トレーリングストップによる買戻し 取得後の安値:" + bottomPrice ); return; } // オーダータイミング3:損切りの対象です。 // 信用売りトレードの場合の損切り int lossCutPrice = (int)(execPrice * ((lossCutRate / 100) + 1)); //損切りのための逆指値注文を行います。 orderReverseStopForPortfolio( portfolio, lossCutPrice, "信用売りの損切り:" ); } } /** * 指定のポートフォリオに対して反対売買の儀句指値注文を行い、ログに残します。
* @param portfolio 反対売買を行いたいポートフォリオ * @param orderPrice 逆指値の注文価格 * @param reason 注文の理由 */ protected void orderReverseStopForPortfolio(Portfolio portfolio,int orderPrice, String reason){ // ポートフォリオから直接反対売買注文を行います。 boolean result = portfolio.orderReverseNowStopAll(orderPrice); // 文言を注文の成否で切り替えます。 String retMsg = ""; if(result){ retMsg = "成功"; // 注文が成功していたら理由をつけます。 OrderManager.getInstance().setLastOrderReason(reason); } else { retMsg = "失敗"; } // ログ出力用のメッセージを作ります。 String msg = String.format( "逆指値反対売買注文しました:%s " + "銘柄コード:%4d 注文株数:%,d 注文価格:%,d 注文理由:%s 注文結果:%s", retMsg, portfolio.getStock().getStockCode(), portfolio.getExecQty().intValue(), orderPrice, reason, OrderManager.getInstance().getLastOrderResult().toString() ); // ログを出力します。 RobotLogManager.getInstance().log(msg, 3); } }