トップ  >  リファレンス  >  APIを取得して始める  >  JForex SDKを使う >  SDKクライアント
SDKクライアント

IClientの機能

IClientインターフェースはライブデータを操作する為に使用します。
ITesterClient継承はヒストリカルデータを操作する為に使用します。

この項目では、主要なIClientの機能を例に説明します。
この例では、JForex-SDKプロジェクトのMain.javaを基にしています。

接続

ClientFactory.getDefaultInstance()を使用して、IClientインターフェースを取得します。
以下の例では、connectメソッドを使ってデューカスコピーのサーバーへ接続します。




client.connect("http://platform.dukascopy.com/demo/jforex.jnlp", "username", "password");



ライブサーバーへの接続方法は、JForexSDKライブモードの項目参照。





システムリスナー

ISystemListenerインターフェースは、ストラテジー起動時にシステムへ接続し、ストラテジー停止時に接続の切断を可能にします。
システムリスナーはsetSystemListenerメソッドを使用してIClientへ追加されます。


client.setSystemListener(new ISystemListener() {
    private int lightReconnects = 3;

    @Override
    public void onStart(long processId) {
        LOGGER.info("ストラテジー起動: " + processId);
    }

    @Override
    public void onStop(long processId) {
        LOGGER.info("ストラテジー停止: " + processId);
        if (client.getStartedStrategies().size() == 0) {
            System.exit(0);
        }
    }

    @Override
    public void onConnect() {
        LOGGER.info("接続完了");
        lightReconnects = 3;
    }

    @Override
    public void onDisconnect() {
        LOGGER.warn("切断完了");
        if (lightReconnects > 0) {
            LOGGER.error("再接続を試みます。残り: " + lightReconnects);
            client.reconnect();
            --lightReconnects;
        } else {
            try {
                // 10秒間スリープしてから再接続します
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                // 無視します
            }
            try {
                client.connect(jnlpUrl, userName, password);
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }
});







通貨ペア登録

JForexクライアントと違って、スタンドアローンAPIでは、ストラテジーで使用する通貨ペアは全て明示的に登録する必要があります。
setSubscribedInstrumentsメソッドを使って登録できます。
注意:登録は非同期で行われるので、以下の方法で登録する事をお勧めします。



Set<Instrument> instruments = new HashSet<Instrument>();
instruments.add(Instrument.EURSEK);
instruments.add(Instrument.AUDUSD);
               
client.setSubscribedInstruments(instruments);

// 最大で2秒間通貨ペア登録待ちします
int i = 10;
while (!client.getSubscribedInstruments().containsAll(instruments)) {
    try {
        LOGGER.info("未だ通貨ペア登録完了していません " + i);
        Thread.sleep(200);
    } catch (InterruptedException e) {
        LOGGER.error(e.getMessage());
    }
    i--;
}










ストラテジー実行

IClient.startStrategyへ渡してストラテジーを実行します。
例えば、


client.startStrategy(new MA_Play());



ストラテジーを複数実行させるには、client.startStrategyを複数実行します。
例では、異なるパラメーターの同じストラテジーを2つ実行します。


StrategySimple strategy1 = new StrategySimple();
StrategySimple strategy2 = new StrategySimple();
strategy1.amount         = 0.01;
strategy1.stopLossPips   = 20;
strategy1.takeProfitPips = 10;
strategy2.amount         = 0.02;
strategy2.stopLossPips   = 60;
strategy2.takeProfitPips = 60;
       
client.startStrategy(strategy1);
client.startStrategy(strategy2);







ストラテジーのリモート実行

IClient.getRemoteStrategyManager().startStrategyメソッドを呼ぶ事でリモート実行する事が出来ます。
他リモートストラテジー管理メソッドについての詳細はIStrategyManagerを参照。
以下例では、リモートストラテジーの管理と実行を行います。


File jfxFile = new File("src/singlejartest/MA_Play.jfx");
if (!jfxFile.exists()) {
    LOGGER.error(jfxFile + " jfxファイルが見つかりません。ストラテジーをコンパイルするか、別のパスを選択して下さい。");
    System.exit(1);
}

final IRemoteStrategyManager remoteManager = client.getRemoteStrategyManager();

remoteManager.addStrategyListener(new RemoteStrategyListener() {

    public void onStrategyRun(IRemoteStrategyDescriptor descriptor) {
        LOGGER.info("リモートストラテジー起動: " + descriptor);
        if (!descriptor.getId().equals(myStrategyId)) {
            LOGGER.info("リモートストラテジーが指定されていません。");
            remoteManager.stopStrategy(descriptor.getId());
        }
    };

    public void onStrategyStop(IRemoteStrategyDescriptor descriptor) {
        LOGGER.info("リモートストラテジー停止: " + descriptor);
    };
});

// IDフェッチ無しでストラテジーを実行
remoteManager.startStrategy(jfxFile , true );

// 実行とIDフェッチ
IStrategyResponse<UUID> startResponse = remoteManager.startStrategy(jfxFile , true ).get();
if (startResponse.isError()) {
    LOGGER.error("リモートストラテジー開始エラー: " + startResponse.getErrorMessage());
} else {
    myStrategyId = startResponse.getResult();
    LOGGER.info("リモートストラテジー開始成功: " + myStrategyId);
}

Set<IRemoteStrategyDescriptor> strategyDescriptors = remoteManager.getStartedStrategies().get().getResult();
LOGGER.info(strategyDescriptors.size() + " ストラテジーはリモートスタートしました。: ");
for (IStrategyDescriptor strategyDescriptor : strategyDescriptors) {
    LOGGER.info(strategyDescriptor.toString());
}


サンプルソースコード:MainRemote.java
注意:この機能はJForex-API 2.9.5以降で使用可能です。







ストラテジーの停止

IClient.startStrategyからストラテジープロセスIDを取得し、IClient.stopStrategyメソッドを使ってストラテジーを停止する事が出来ます。
以下例では、ユーザーがコンソールで"stop"と入力したかを毎秒チェックし、入力されたらストラテジーを停止させます。



final long strategyId = client.startStrategy(new IStrategy(){
    public Instrument instrument = Instrument.EURUSD;
    private IConsole console;

    public void onStart(IContext context) throws JFException {        
        console = context.getConsole();    
    }
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        if ( instrument == this.instrument){
            console.getOut().println(" bar: " + period  + " " + askBar);
        }
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {    }
    public void onMessage(IMessage message)               throws JFException {    }
    public void onAccount(IAccount account)             throws JFException {    }
    public void onStop()                                  throws JFException {    }
});
// ストラテジー実行中

// ユーザーがコンソールで"stop"と入力したかを毎秒チェックし、入力されたらストラテジーを停止させます。 
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {                
        Scanner s = new Scanner(System.in);                
        while( true ){
            while( s.hasNext() ){
                String str = s.next();
                if( str.equalsIgnoreCase( "stop" ) ){
                    System.out.println( "コンソールコマンドによるストラテジー停止" );
                    client.stopStrategy(strategyId);
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});
thread.start();



サンプルソースコード:MainStopFromConsole.java








チャート操作

チャートを開く方法は2つあります。
・IClient.openChartはストラテジーを実行せずにチャートを開きます。
・IClient.addClientGUIListenerはIContext.openChartとIContext.closeChartイベントハンドラをリスナーに追加します。





IClientからチャートを開く

注意:JForex-API 2.7.1以降で利用可能です。
以下例は、instrArr配列の通貨ペアチャートを複数開きます。


for (Instrument instrument : instrArr) {
    IFeedDescriptor feedDescriptor = new TicksFeedDescriptor(instrument);
    feedDescriptor.setOfferSide(OfferSide.BID); // プラットフォームでの要求に合わせた設定が必要です
    IChart chart                   = client.openChart(feedDescriptor);
    final IClientGUI clientGUI    = client.getClientGUI(chart);

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            ChartFrame frame = new ChartFrame(clientGUI, client.getSubscribedInstruments());
            chartFrameMap.put(clientGUI.getChart(), frame);

            // 手動クローズハンドル:チャートが無くなっている事をストラテジーに知らせる為にIClient.closeChartを呼ぶ必要があります。
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    LOGGER.info("チャートは手動で閉じられました。ストラテジーコンテキストからチャートを削除します");
                    client.closeChart(clientGUI.getChart());
                    chartFrameMap.remove(clientGUI.getChart());
                    if (chartFrameMap.isEmpty()) {
                        LOGGER.info("全チャートを閉じられました。プログラムを停止します。");
                        System.exit(0);
                    }
                }
            });
        }
    });
}



サンプルソースコード:MainOpenChart.java





IContext.openChartハンドル

以下例では、ストラテジーがIContext.openChartを呼び出す度にチャートを開きます、
IContext.closeChartを呼び出す度にチャートを閉じます。



client.addClientGUIListener(new IClientGUIListener() {  

    @Override
    public void onOpenChart(final IClientGUI clientGUI) {
        LOGGER.info("ストラテジーからチャートが開かれました" + clientGUI.getChart().getFeedDescriptor());
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                ChartFrame frame = new ChartFrame(clientGUI, client.getSubscribedInstruments());
                chartFrameMap.put(clientGUI.getChart(), frame);
                // 手動クローズハンドル:チャートが無くなっている事をストラテジーに知らせる為にIClient.closeChartを呼ぶ必要があります。
                frame.addWindowListener(new WindowAdapter(){
                    public void windowClosing(WindowEvent e) {
                        LOGGER.info("チャートは手動で閉じられました。ストラテジーコンテキストからチャートを削除します");
                        client.closeChart(clientGUI.getChart());
                        updateOnClose(clientGUI.getChart());
                    }
                });
            }
        });
    }
    
    @Override
    public void onCloseChart(IChart chart) {
        LOGGER.info("ストラテジーからチャートが閉じられました" + chart.getFeedDescriptor());
        // GUIのフレーム自身がチャートを閉じる事に注意して下さい
        ChartFrame frame = chartFrameMap.get(chart);
        frame.dispose();
        updateOnClose(chart);
    }
    
    private void updateOnClose(IChart chart){
        chartFrameMap.remove(chart);
        if(chartFrameMap.isEmpty()){
            LOGGER.info("全チャートを閉じられました。プログラムを停止します。");
            System.exit(0);
        }
    }
});




サンプルソースコード:MainHandleStrategyOpenChart.java





チャートオブジェクト追加

IClientを実行しているプログラムから、ストラテジーがプロットしたチャートオブジェクトでチャートを開く事が出来ます。
以下例では、IClientGUI.getChart()からIChartへ受信するボタンを作成します。



@SuppressWarnings("serial")
private class ChartObjectPanel extends JPanel {
    
    private final IChart chart;
    private ChartObjectPanel(IChart chart){
        this.chart = chart;
        addButtons();
    }
    
    private void addButtons(){            
        JButton btnVLine = new JButton("Add VLine");
        btnVLine.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                // チャート上の最後に描画された時間の位置にラインを描画します
                ITimedData[] chartData = chart.getLastRequestedData();
                long time = chartData[chartData.length - 1].getTime();
                IChartObject obj = chart.getChartObjectFactory().createVerticalLine("vLine", time);
                obj.setColor(Color.RED);
                chart.add(obj);
            }});
        add(btnVLine);            

        JButton btnHLine = new JButton("Add HLine");
        btnHLine.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {    
                // チャート価格の中間地点にラインを描画します
                double price = chart.getMinPrice() + (chart.getMaxPrice() - chart.getMinPrice()) / 2;
                System.out.println(String.format("%.5f", price));                    
                IChartObject obj = chart.getChartObjectFactory().createHorizontalLine("hLine", price);
                obj.setColor(Color.GREEN);
                chart.add(obj);
            }});
        add(btnHLine);
    }
    
}




サンプルソースコード:MainOpenChartAddChartObject.java





チャートテーマ変更

注意:JForex-API 2.7.9以降で使用可能です。

IChartThemeはチャートテーマの代表です。
IClientChartPresentationManagerのsetThemeメソッドとgetThemeメソッド使用する事で、チャートの値を取得したり設定する事が出来ます。
以下例では、チャートの背景とtick/ローソク足の色を変更します。



chartPresentationManager.setTheme(
    chartPresentationManager.getTheme()
        .setName("Custom tick/candle color theme")
        .setColor(ColoredElement.BACKGROUND, new Color(254, 244, 214))
        .setColor(ColoredElement.CANDLE_BEAR, Color.CYAN           )
        .setColor(ColoredElement.CANDLE_BULL, Color.ORANGE         )
        .setColor(ColoredElement.ASK        , Color.YELLOW.darker())
        .setColor(ColoredElement.BID        , Color.PINK.darker()  )
);


IClientChartPresentationManager.getPredefinedThemeメソッドを呼ぶことで、定義済みテーマを取得出来ます。
以下例は、チャートに定義済みテーマを設定します。



chartPresentationManager.setTheme(
 chartPresentationManager.getPredefinedTheme( IChartTheme.Predefined.BLUE_BLACK_ON_GRAY) 
);


サンプルソースコード:MainOpenChart.java

(サンプルソースコードのcmbChartThemeの設定を参照)








ストラテジーでの通信プログラム

ストラテジー内のリスナー定義する事によって、ストラテジーイベントにクライアント側のロジックを実装する事が出来ます。


新規オーダーとクローズ

プログラムから新規オーダーとクローズオーダーとストップロス設定を行うロジックの例。



client.startStrategy(new StrategyPublicMethods(new StrategyPublicMethods.ClientActions() {

  @Override
  public void onOrderFill(IOrder order) {
    LOGGER.info("新規オーダー。クライアント側でロングオーダーしたらストップロス設定を実行します。");
    if(order.isLong()){
      try {
        order.setStopLossPrice(order.getOpenPrice() - order.getInstrument().getPipValue() * 10);
      } catch (JFException e) {
        e.printStackTrace();
      }
    }
  }
  
  @Override
  public void onOrderClose(IOrder order) {
    LOGGER.info("クローズオーダー。クライアント側で実行します。");          
  }
}));


新規オーダーとクローズオーダーリスナーとして役に立つインターフェース導入の例。
IClientプログラムから渡されたインターフェースの実装を行います。



public class StrategyPublicMethods implements IStrategy {
  
    private IConsole console; 
    private IEngine engine;
    private StrategyPublicMethods.ClientActions clientActions;
    
    public interface ClientActions {
        void onOrderClose(IOrder order);
        void onOrderFill(IOrder order);
    }  
    
    // スタンドアローンから起動
    public StrategyPublicMethods (StrategyPublicMethods.ClientActions clientActions){
        this.clientActions = clientActions;
    }

    // …中略…


}


IClientプログラムから渡されたロジックで全ての新規オーダーとクローズオーダーを執行します。



    @Override
    public void onMessage(IMessage message) throws JFException {
        if(message.getType() == IMessage.Type.ORDER_FILL_OK){
            clientActions.onOrderFill(message.getOrder());
        }
        if(message.getType() == IMessage.Type.ORDER_CLOSE_OK){
            clientActions.onOrderClose(message.getOrder());
        }
    }


サンプルソースコード:
StrategyPublicMethods.java
MainPublicMethods.java




新規オーダーカバーアップ

同じパターンの別例です。
クライアントプログラムが各新規オーダーをカバーアップします。


client.startStrategy(new StrategyFillListener(new StrategyFillListener.ClientActions() {

  @Override
  public void onOrderFill(IOrder order, IEngine engine) {
    LOGGER.info("新規オーダー完了。クライアント側でカバーアップオーダーを行います。");
    try {
      // 同じ通貨ペアで次のオーダーをする場合は1秒待ちます
      Thread.sleep(1000);
      OrderCommand cmd = order.isLong() ? OrderCommand.SELL : OrderCommand.BUY;
      engine.submitOrder("orderClient" + ++counter, order.getInstrument(), cmd, order.getAmount());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}));



リスナーインターフェースは一つだけメソッドを含んでいます。


public class StrategyFillListener implements IStrategy {

    // …中略…
    
    public interface ClientActions {
        void onOrderFill(IOrder order, IEngine engine);
    }  
    
    // スタンドアローンから起動
    public StrategyFillListener (StrategyFillListener.ClientActions clientActions){
        this.clientActions = clientActions;
    }

    // …中略…
}



IClientプログラムから渡されたロジックで全ての新規オーダー執行します。


@Override
public void onMessage(IMessage message) throws JFException {
  IOrder order = message.getOrder();

  // 新規オーダー用コールバック
    if(message.getType() == IMessage.Type.ORDER_FILL_OK && order.getLabel().startsWith(prefix)){
        clientActions.onOrderFill(order, engine);
    }
}


サンプルソースコード:
StrategyFillListener.java
ProgramFillCover.java







ニュースとカレンダー

ストラテジーでニュースまたはカレンダーメッセージを受信するには、ストラテジー実行前に以下処理をIClient にNewsFilterまたはCalendarFilterを適用する必要があります。


NewsFilter newsFilter = new NewsFilter();
//all today's news
newsFilter.setTimeFrame(NewsFilter.TimeFrame.TODAY);
client.addNewsFilter(newsFilter);


注意:NewsFilterはライブデータでのみ動作します。バックテスト中は使用出来ません(ニュースメッセージを受け取りません)。

タイムフレーム

利用可能な時間軸はTimeFrame列挙で定義されています。
以下のタイムフレームでニュースを取得出来ます。
時間軸 ニュース取得タイミング
ONLINE 新しいニュースが来る度、受信します。
LAST_10_MINUTES ストラテジー起動時と、10分毎にニュース受信します。
LAST_30_MINUTES,
LAST_HOUR,
TODAY
LAST_10_MINUTESと同様に、指定した時間毎にニュース受信します。
SPECIFIC_DATE ストラテジー起動時と特定の日時にニュースを受信します。
使用可能にするには、特定の日付を持ったNewsFilter.setFromを呼ぶ必要があります。



フィルターパラメータ

以下パラメータでニュースのフィルタリングが出来ます。
  • 国と地域
  • 通貨
  • イベントカテゴリー
  • マーケットセクター
  • 株式インデックス


パラメータは論理和のように設定出来ます。
  • パラメータ設定しない場合は、全てのニュースメッセージを受信します。
  • StockIndex.NYSEのパラメータ設定は、ニューヨーク証券取引所の株価指数に関連したニュースだけ受信します。
  • Country.FRとStockIndex.NYSEの複数パラメータ設定は、NYSE株価指数とフランスに関連したニュースだけ受信します。



フィルターキーワード

Keyword filtering can be perceived as an extra filter on top of parameter filtering, since it drops from parameter filtering results the ones that don't match the given text string criteria.


ニュースフィルター例

NYSE株価指数とNYダウ平均株価指数と米国とフランスに関する今日のニュースをフィルタリングします。
更に、"Profit"と"Loss"のワードを含んだニュースのみ取得します。


  NewsFilter newsFilter = new NewsFilter();
  newsFilter.setTimeFrame(NewsFilter.TimeFrame.TODAY);
  
  // インデックスでフィルター
  newsFilter.getStockIndicies().add(INewsFilter.StockIndex.NYSE);
  newsFilter.getStockIndicies().add(INewsFilter.StockIndex.DJI);
          
  // 国と地域でフィルター
  newsFilter.getCountries().add(INewsFilter.Country.US);
  newsFilter.getCountries().add(INewsFilter.Country.FR);
  
  // マーケットセクターでフィルター
  newsFilter.getMarketSectors().add(INewsFilter.MarketSector.FCL);
  newsFilter.getMarketSectors().add(INewsFilter.MarketSector.ENE);
  
  // キーワードでフィルター
  newsFilter.getKeywords().add("Profit");
  newsFilter.getKeywords().add("Loss");
  
  client.addNewsFilter(newsFilter);


サンプルソースコード:
NewsFilterMain.java
NewsStrategyNoTrades.java


カレンダーフィルター例

2011年3月11日以降のG7参加国に関連するカレンダーイベントのみフィルタリングします。
更に、"Treasury", "GDP", "trade"のキーワードのいずれかが含んでいるイベントのみ取得します。


    CalendarFilter calendarFilter = new CalendarFilter();
    calendarFilter.setTimeFrame(NewsFilter.TimeFrame.SPECIFIC_DATE);
    
    // カスタムヒストリカルインターバル
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    Date dateFrom = dateFormat.parse("2011-03-11");
    calendarFilter.setFrom(dateFrom);       

    // 国と地域でフィルター
    newsFilter.getCountries().add(INewsFilter.Country.G7);
    
    // キーワードでフィルター
    calendarFilter.getKeywords().add("Treasury");
    calendarFilter.getKeywords().add("GDP");
    calendarFilter.getKeywords().add("trade");
    
    
    client.addNewsFilter(calendarFilter);


サンプルソースコード:
NewsFilterMain.java
NewsStrategyNoTrades.java









ストラテジーをjfxファイルへコンパイル

IClient.compileStrategyメソッドを使う事で、スタンドアローンプログラムからストラテジーをコンパイルする事が出来ます。



    client.compileStrategy(new File("C:/temp/MyStrategy.java"), false);





スポンサーリンク

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


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


Top

inserted by FC2 system