このチュートリアルでは、チャートにオブジェクトを追加しカスタマイズする方法を学びます。
SMAインジケータ、IOhlcChartObject・ISignalDownChartObject・ISignalUpChartObjectオブジェクトを追加し、カスタマイズします。
このストラテジーはSMAの値に応じてオーダーし、新しいオーダーされた時にチャートのタイムライン上にISignalDownChartObject・ISignalUpChartObjectオブジェクトを追加します。
以前作成した
SMASampleTrade.javaファイルを基に新しいストラテジーを作成します。
チャートにオブジェクトを追加する方法の詳細は、チャートオブジェクトカタログの項目を参照して下さい。
まず初めに、以下のインポートを追記します。
import com.dukascopy.api.drawings.IChartObjectFactory;
import com.dukascopy.api.drawings.IOhlcChartObject;
import com.dukascopy.api.indicators.OutputParameterInfo.DrawingStyle;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
チャート上で動作するIChart・IChartObjectFactoryオブジェクトを使用します。
そしてinteger型のインスタンスパラメータを作成します。
これは後で必要になります。
private IChart openedChart;
private IChartObjectFactory factory;
private int signals;
ストラテジーを実行している時、チャート上にOHLC値を表示させるか否か選択出来るようにします。
ストラテジーを終了した後に、後処理を行うか選択出来るようにもします。
コードに以下のようにパラメータを追加します。
@Configurable("チャート上にOHLCインデックス表示")
public boolean addOHLC = true;
@Configurable("フィルター")
public Filter filter = Filter.WEEKENDS;
@Configurable("SMA描画")
public boolean drawSMA = true;
@Configurable("ストラテジー停止時にチャートを閉じる")
public boolean closeChart;
次に、チャートにSMAインジケータを追加するのに必要なインスタンス変数を初期化し、addToChartメソッド(チャート上にSMAインジケータを描画するメソッド)を呼び出します。
onStartメソッドを以下のようにします。
public void onStart(IContext context) throws JFException {
this.engine = context.getEngine();
this.console = context.getConsole();
this.history = context.getHistory();
this.context = context;
this.indicators = context.getIndicators();
this.userInterface = context.getUserInterface();
this.openedChart = context.getChart(myInstrument);
this.factory = openedChart.getChartObjectFactory();
Set<Instrument> instruments = new HashSet<Instrument>();
instruments.add(myInstrument);
context.setSubscribedInstruments(instruments, true );
if( drawSMA )
if( !addToChart(openedChart) ){
printMeError("チャート上にインジケータをプロット出来ませんでした。チャートの設定値を確認して下さい。");
}
}
パラメータ設定でストラテジー停止時にチャートを閉じる設定にしている場合に、
チャートを閉じるようにonStopメソッドを変更します。
public void onStop() throws JFException {
if( closeChart )
context.closeChart(openedChart);
}
以前作成したロジックに加えて、
ISignalDownChartObjectとISignalUpChartObjectオブジェクトをチャートに追加します。
onBarメソッドを以下のようにします。
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (!instrument.equals(myInstrument) || !period.equals(myPeriod)) {
return;
}
int candlesBefore = 2, candlesAfter = 0;
previousBar = myOfferSide == OfferSide.ASK ? askBar : bidBar;
long currBarTime = previousBar.getTime();
double sma[] = indicators.sma(instrument, period, myOfferSide, IIndicators.AppliedPrice.CLOSE,
smaTimePeriod, Filter.NO_FILTER, candlesBefore, currBarTime, candlesAfter);
printMe(String.format("Bar SMA Values: Second-to-last = %.5f; Last Completed = %.5f", sma[SECOND_TO_LAST], sma[PREV]));
IEngine.OrderCommand myCommand = null;
printMe( String.format("SMAの値: 2つ前 = %.5f; 1つ前 = %.5f", sma[SECOND_TO_LAST], sma[PREV]));
if( sma[PREV] > sma[SECOND_TO_LAST]){
printMe("SMA上昇");
myCommand = IEngine.OrderCommand.BUY;
} else if ( sma[PREV] < sma[SECOND_TO_LAST]){
printMe("SMA下降");
myCommand = IEngine.OrderCommand.SELL;
} else {
return;
}
order = engine.getOrder("MyStrategyOrder");
if (order != null && engine.getOrders().contains(order) && order.getOrderCommand() != myCommand){
order.close();
order.waitForUpdate(IOrder.State.CLOSED);
console.getOut().println( order.getLabel() + " ラベルのポジションをクローズしました");
}
if( order == null || !engine.getOrders().contains(order)){
engine.submitOrder("MyStrategyOrder", instrument, myCommand, 0.1);
long time = previousBar.getTime() + myPeriod.getInterval();
IChartObject signal = myCommand.isLong() ?
factory.createSignalUp("signalUpKey" + signals++, time, previousBar.getLow() - instrument.getPipValue()*2)
: factory.createSignalDown("signalDownKey" + signals++, time, previousBar.getHigh() + instrument.getPipValue()*2);
signal.setText(String.format("delta SMA %+.7f", sma[PREV] - sma[SECOND_TO_LAST]), new Font("Monospaced", Font.BOLD, 12));
openedChart.addToMainChart(signal);
}
}
Strategy出力にエラーメッセージを出力する新しいユーティリティメソッドを追加します。
private void printMeError(Object o){
console.getErr().println(o);
}
最後に、addToChartメソッドを実装します。
このメソッドはSMAインジケータとOHLC値をチャート上に追加します。
private boolean addToChart(IChart chart){
if (chart == null){
printMeError(myInstrument + " の通貨ペアチャートが開かれていません。");
return false;
}
if (chart.getSelectedOfferSide() != this.myOfferSide) {
printMeError("チャートのオーダータイプ(アスク/ビッド)と一致していません" + this.myOfferSide);
return false;
}
if (chart.getSelectedPeriod() != this.myPeriod) {
printMeError(this.myPeriod + "の時間軸チャートが開かれていません。" );
return false;
}
if (chart.getFilter() != this.filter){
printMeError("chart filter is not " + this.filter);
return false;
}
chart.addIndicator(indicators.getIndicator("SMA"), new Object[] {smaTimePeriod},
new Color[]{Color.GREEN}, new DrawingStyle[]{DrawingStyle.LINE}, new int[]{3});
if(addOHLC){
IOhlcChartObject ohlc = null;
for (IChartObject obj : chart.getAll()) {
if (obj instanceof IOhlcChartObject) {
ohlc = (IOhlcChartObject) obj;
}
}
if (ohlc == null) {
ohlc = chart.getChartObjectFactory().createOhlcInformer();
ohlc.setPreferredSize(new Dimension(100, 200));
chart.addToMainChart(ohlc);
}
ohlc.setShowIndicatorInfo(true);
}
return true;
}
サンプルソースコード:
ChartUsage.java
このストラテジーをテストします。
ヒストリカルテスターでテストする場合は、"ストラテジー停止時にチャートを閉じる"にチェックを入れないで下さい。チェックを入れるとエラーになります。
ストラテジー実行結果