StopLossStrategy.java

注意事項:
サンプルソースコードには実際にオーダーを発注するものがあります。
サンプルソースコードのストラテジーを起動する場合は、必ずデモ口座で行ってください。



// Copyright (c) 2009 Dukascopy (Suisse) SA. All Rights Reserved.

package stoploss;

import com.dukascopy.api.*;
import java.util.HashSet;
import java.util.Set;
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.util.HashMap;
import java.util.Map;

//1. インポート追加:
import com.dukascopy.api.drawings.IChartDependentChartObject;
import com.dukascopy.api.drawings.ITriangleChartObject;
import com.dukascopy.api.drawings.ITextChartObject;

//2. 不要なインポートを削除
//import java.awt.Font;




public class StopLossStrategy implements IStrategy { 

    private IEngine        engine;
    private IConsole       console;
    private IHistory       history;
    private IContext       context;
    private IIndicators    indicators;
    private IUserInterface userInterface;
    private IBar           previousBar;
    private IOrder         order;
    private IChart              openedChart;
    private IChartObjectFactory factory;
    private int                 signals;
    private static final int PREV = 1;
    private static final int SECOND_TO_LAST = 0;

    //3. インスタンス変数追加
    private int     uniqueOrderCounter   = 1;
    private SMATrend previousSMADirection = SMATrend.NOT_SET;
    private SMATrend currentSMADirection  = SMATrend.NOT_SET;
    private Map<IOrder, Boolean> createdOrderMap = new HashMap<IOrder, Boolean>();
    private int shorLineCounter;
    private int textCounterOldSL;
    private int textCounterNewSL;
    
    // パラメータを定義します
    @Configurable( value = "通貨ペア" )
    public Instrument myInstrument = Instrument.EURGBP;
    @Configurable( value = "オーダータイプ", obligatory = true )
    public OfferSide myOfferSide = OfferSide.ASK;
    @Configurable( value = "時間軸" )
    public Period myPeriod = Period.TEN_MINS;
    @Configurable( "SMA期間" )
    public int smaTimePeriod = 30;
    @Configurable("チャート上にOHLCインデックス表示")
    public boolean addOHLC = true;
    @Configurable("フィルター")
    public Filter filter = Filter.WEEKENDS;
    @Configurable("SMA描画")
    public boolean drawSMA = true;
    @Configurable("ストラテジー停止時にチャートを閉じる")
    public boolean closeChart;

    //4. Add new parameters
    @Configurable("ストップロス(pips)")
    public int    stopLossPips   = 10;
    @Configurable("リミット(pips)")
    public int    takeProfitPips = 10;
    @Configurable("ブレークイーブン(pips)")
    public double breakEventPips = 5;
    
    //5. SMAトレンド状態の全てのパターンの定数を持つ列挙を定義
    private enum SMATrend {
        UP, DOWN, NOT_SET;
    }

    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("チャート上にインジケータをプロット出来ませんでした。チャートの設定値を確認して下さい。");
            }
        }
    } // onStartメソッド終了

    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {        
        if( message.getOrder() != null )
            console.getOut().println("オーダーラベル: " + message.getOrder().getLabel() 
                                     + " || メッセージログ: " + message.getContent());
    }

    public void onStop() throws JFException {
        if( closeChart )
            context.closeChart(openedChart);
    }

    
    // 6. onTickメソッドはtick更新毎に呼び出されます。
    // 特定の通貨ペアだけフィルタリングするようにしなければなりません。 
    // 後でonBarメソッドにて、全ての新しいオーダーを Mapオブジェクト に追加します。  
    // ブレークイーブンレベル到達によって既にストップロスレベルが移動しているか、Mapでオーダーを確認します。
    // まだ移動していない場合、含み益がbreakEventPipsパラメータよりも大きいか確認します。 
    // 含み益がブレークイーブンレベルに到達しているなら、ストップロスレベルをエントリー価格のレベルに変更する事が出来ます。  
    // ストップロスの値がエントリー価格に設定されたら、
    // チャート上に視覚的な三角形の変更プロセス(後述するaddBreakToChartメソッドを呼びます)を表示します。 
    // 最後に、ストップロスオーダーを変更し、マップのエントリーを更新します。
    

    public void onTick(Instrument instrument, ITick tick) throws JFException {
        // 通貨ペアでフィルタリング
        if ( instrument != myInstrument) {
            return;
        }
    
        // 拡張forループ
        for ( Map.Entry<IOrder, Boolean> entry : createdOrderMap.entrySet() ) {
            IOrder   currentOrder = entry.getKey();
            boolean currentValue = entry.getValue();
    
            if ( currentValue == false && currentOrder.getProfitLossInPips() >= breakEventPips ) {
                printMe( currentOrder.getProfitLossInPips() + "pipsリミットのポジションのストップロスはエントリーレートに移動しました。");
                addBreakToChart( currentOrder, tick, currentOrder.getStopLossPrice(), currentOrder.getOpenPrice() );
    
                // ストップロス変更を表示するラインをチャートに追加
                currentOrder.setStopLossPrice( currentOrder.getOpenPrice() );
                entry.setValue( true );
            }
        }
    }// onTickメソッド終了

    
    
    // 7. 前回作成したonBarメソッドを変更します。 新しいオーダーをする際にSMATrend列挙を用いてチェックするようにします。 
    // 更にストップロスとリミットの設定も行います。
    // 前回との違いは、既にポジションを持っていたとしてもそのポジションをクローズしない所です。 
    // ストップロスやリミットに到達した時は、ポジションは自動的にクローズされます。 
    // それと、全ての新しいオーダーは、後でonTickメソッドでチェックするのでMapに記録します。 
    

    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;
        long completedBarTimeL = myOfferSide == OfferSide.ASK ? askBar.getTime() : bidBar.getTime();
        double sma[] = indicators.sma(instrument, period, myOfferSide, IIndicators.AppliedPrice.CLOSE,
                smaTimePeriod, Filter.NO_FILTER, candlesBefore, completedBarTimeL, candlesAfter);

        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;
            currentSMADirection = SMATrend.UP;
        } else if ( sma[PREV] < sma[SECOND_TO_LAST]){
            printMe("SMA下降"); // インジケータが下降している
            myCommand = IEngine.OrderCommand.SELL;
            currentSMADirection = SMATrend.DOWN;
        } else {
            return;
        }

        double lastTickBid           = history.getLastTick(myInstrument).getBid();
        double lastTickAsk           = history.getLastTick(myInstrument).getAsk();
        double stopLossValueForLong  = myInstrument.getPipValue() * stopLossPips;
        double stopLossValueForShort = myInstrument.getPipValue() * takeProfitPips;
        double stopLossPrice   = myCommand.isLong() ? (lastTickBid - stopLossValueForLong ) : (lastTickAsk + stopLossValueForLong);
        double takeProfitPrice = myCommand.isLong() ? (lastTickBid + stopLossValueForShort) : (lastTickAsk - stopLossValueForShort);

        // SMAトレンドが変わったら、新しいオーダーを行う
        if ( currentSMADirection != previousSMADirection ) {
            previousSMADirection = currentSMADirection;
            IOrder newOrder      = engine.submitOrder("MyStrategyOrder" + uniqueOrderCounter++, instrument, myCommand,
                                                       0.001, 0, 1, stopLossPrice, takeProfitPrice);
            createdOrderMap.put(newOrder, false);
    
            if( openedChart == null ){
                return;
            }

            long   time  = bidBar.getTime() + myPeriod.getInterval(); // ISignalDownChartObjectを現在のバーに描画する
            double space = myInstrument.getPipValue() * 2;            // ISignalDownChartObject用にバーの上限のマージンを設定する

            IChartDependentChartObject signal = myCommand.isLong()
                    ? factory.createSignalUp(  "signalUpKey"   + signals++, time, bidBar.getLow()  - space)
                    : factory.createSignalDown("signalDownKey" + signals++, time, bidBar.getHigh() + space);

            signal.setStickToCandleTimeEnabled(false);
            signal.setText("MyStrategyOrder" + (uniqueOrderCounter - 1));
            openedChart.addToMainChart(signal);
        }
    
    } // onBarメソッド終了

    private void printMe(Object toPrint){
        console.getOut().println(toPrint);
    }
    

    private void printMeError(Object o){
        console.getErr().println(o);
    }

    
    
    // 8. addToChartメソッドを変更し、チャートのチェックは新しい(checkChart)メソッドで行います。
    

    private boolean addToChart(IChart chart){
        if ( !checkChart(chart) ) {
            return false;
        }

        chart.addIndicator(indicators.getIndicator("SMA"), new Object[] {smaTimePeriod},
                new Color[]{Color.BLUE}, 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インデックスを表示
            ohlc.setShowIndicatorInfo(true);
        }
        return true;
    }// addToChartメソッドの終了

    
    
    // 9. チャート上のストップロス変更を視覚的に表示するaddBreakToChartメソッドを実装します。
    // このメソッドはストップロスオーダーが変更されたら、チャート上に三角形のオブジェクトを追加します。
    // 緑の三角形はロングポジションのストップロス変更で、赤い三角形はショートポジションのストップロス変更を表しています。
    // この三角形は新しいオーダーを行った時に開始し、ストップロス変更時が終点です。
    // 古いストップロスと新しいストップロスの値をテキストで三角形の所に表示します。 
    

    private void addBreakToChart(IOrder changedOrder, ITick tick, double oldSL, double newSL) throws JFException {
        if ( openedChart == null ) {
            return;
        }
    
        ITriangleChartObject orderSLTriangle = factory.createTriangle("Triangle " + shorLineCounter++,
                changedOrder.getFillTime(), changedOrder.getOpenPrice(), tick.getTime(), oldSL, tick.getTime(), newSL);
    
        Color lineColor = oldSL > newSL ? Color.RED : Color.GREEN;
        orderSLTriangle.setColor(lineColor);
        orderSLTriangle.setLineStyle(LineStyle.SOLID);
        orderSLTriangle.setLineWidth(1);
        orderSLTriangle.setStickToCandleTimeEnabled(false);
        openedChart.addToMainChart(orderSLTriangle);
    
        // テキスト描画
        String breakTextOldSL       = String.format(" Old SL: %.5f", oldSL);
        String breakTextNewSL       = String.format(" New SL: %.5f", newSL);
        double textVerticalPosition = oldSL > newSL ? newSL - myInstrument.getPipValue() : newSL + myInstrument.getPipValue();
        ITextChartObject textOldSL   = factory.createText("textKey1" + textCounterOldSL++, tick.getTime(), oldSL);
        ITextChartObject textNewSL   = factory.createText("textKey2" + textCounterNewSL++, tick.getTime(), newSL);
    
        textOldSL.setText(breakTextOldSL);
        textNewSL.setText(breakTextNewSL);
        textOldSL.setStickToCandleTimeEnabled(false);
        textNewSL.setStickToCandleTimeEnabled(false);
        openedChart.addToMainChart(textOldSL);
        openedChart.addToMainChart(textNewSL);
    }

    //10. チャートをチェックするメソッド 
    private boolean checkChart(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;
        }
        return true;
    }
    
}








スポンサーリンク

スポンサーリンク
検索
リファレンスツリー


Copyright ©2016 JForexAPIで自動売買させ隊! All Rights Reserved.


Top

inserted by FC2 system