ウチコムラボ

FX自動売買の自作

dukascopy.jpでバックテスト

まずはヒストリカル実行

サンプルで実行。デモ口座のID,パスワードを使用し、通貨は身近なドル円に変更。

    private static String userName = "username"; // DEMO口座のログインID
    private static String password = "password"; // DEMO口座のパスワード
    instruments.add(Instrument.EURUSD); // tickデータの種類を指定、ドル円の場合はUSDJPYを設定
  

バックテストのデータがほしい

デューカスコピーではヒストリカルデータ取得ページからダウンロードが可能。 ただしデモ口座のアカウントが必要。

githubで調べてみると、pythonとかでデータを直接元データを取得しているコードを発見。Javaでもやってみることにした。 どうやら、CSVダウンロード時に裏側では1時間ごとのバイナリデータをダウンロードして、それをフロント側で結合してCSVに変換していると想定。 最初はCSVをgzipに暗号化して小さくしてと考えていたが、どうやら、もっと圧縮率の高い方法で圧縮しているようだ。 ならそのデータを直接保存する。 ということで、ダウンロードプログラムはこちら。ただし、csvを読み込んでonTickを呼び出すとか、オーダーを制御するとかは自前で用意しないとだめかな。 ちなみにデータ構造は1tickが20byte(int,int,int,float,float)でデータとしては、たぶん(時ちょうどからのミリ秒,ask(1000倍),bid(1000倍),askvolume(桁調整なし),bidVolume(桁調整なし))。

  oid execute(Parameter parameter) {
    process(
        () -> {
          try {
            var instrument = parameter.get("instrument", "USDJPY");
            if (parameter.is("from") && parameter.is("to")) {
              System.out.println("from to!");
              var from = parameter.getLocalDate("from");
              var to = parameter.getLocalDate("to");
              download(instrument, from, to);
            } else {
              System.out.println("date!");
              var date =
                  parameter.getLocalDate("date", dateTimeService.getLocalDate().minusDays(1));
              download(instrument, date);
            }
            System.out.println("download!");
          } catch (Exception e) {
            e.printStackTrace();
          }
        });
  }

  void download(String instrument, LocalDate from, LocalDate to)
      throws IOException, InterruptedException {
    System.out.println("from to !!");
    if (from.isAfter(to)) {
      throw new IllegalArgumentException("from <= to");
    }
    for (var date = from; date.isBefore(to); date = date.plusDays(1)) {
      System.out.println("date !!");
      download(instrument, date);
    }
  }

  void download(String instrument, LocalDate date) throws IOException, InterruptedException {
    System.out.println("download !!");

    for (int i = 0; i < 24; i++) {
      var file =
          new File(
              String.format("./%1$s/%2$tY/%2$tm/%2$td/%3$02dh_ticks.bi5", instrument, date, i));
      if (file.exists()) {
        System.out.println("ダウンロード済み:" + file.getCanonicalPath());
        continue;
      }
      download(
          String.format(
              "/%1$s/%2$tY/%3$02d/%2$td/%4$02dh_ticks.bi5",
              instrument, date, date.getMonthValue() - 1, i),
          file);
    }
  }

  /** 非同期だと503になるので */
  void download(String path, File saveFile) throws IOException, InterruptedException {
    System.out.println(path);
    var request = createRequestBuilder(path).GET().build();
    var response = client.send(request, BodyHandlers.ofByteArray());
    // .thenAccept(
    //         response -> {
    System.out.println("download!!!" + response.statusCode());
    if (response.statusCode() != 200) {
      return;
    }
    System.out.println("mkdirs:" + saveFile.getParentFile().mkdirs());
    try (var fos = new FileOutputStream(saveFile)) {
      fos.write(response.body());
      fos.flush();
    } catch (Exception e) {
      e.printStackTrace();
    }
    // });
  }

  HttpRequest.Builder createRequestBuilder(String path) {
    return HttpRequest.newBuilder().uri(createUri(path));
  }

  URI createUri(String path) {
    return URI.create("https://datafeed.dukascopy.com/datafeed" + path);
  }
}

実行条件

期間2023-08-10〜2023-08-16
初期資金100万円
取引数量1000通貨

実行結果

注文日時オーダ損益手数料
2023-09-11(月) 09:02:10売り146円9.77円
2023-09-11(月) 10:12:20売り-105円9.77円
2023-09-11(月) 13:01:20買い150円9.77円
2023-09-11(月) 13:02:50買い-109円9.77円
2023-09-11(月) 13:15:40売り143円9.77円
2023-09-11(月) 15:07:00売り143円9.77円
2023-09-11(月) 19:20:20買い-107円9.77円
2023-09-11(月) 21:04:50売り146円9.77円
2023-09-11(月) 22:10:50売り-106円9.77円
2023-09-11(月) 22:58:10売り148円9.77円
2023-09-12(火) 06:02:02売り-176円9.77円
2023-09-12(火) 10:12:40売り-109円9.77円
2023-09-12(火) 21:40:50売り-109円9.77円
2023-09-13(水) 21:30:00売り-385円9.77円
2023-09-13(水) 21:30:10買い-124円9.77円
2023-09-13(水) 21:30:20買い145円9.77円
2023-09-13(水) 21:30:30買い-117円9.77円
2023-09-13(水) 21:31:10買い-114円9.77円
2023-09-13(水) 21:33:10売り-108円9.77円
2023-09-13(水) 21:35:40売り-109円9.77円
2023-09-13(水) 21:41:00買い-105円9.77円
2023-09-13(水) 21:51:10売り-104円9.77円
2023-09-14(木) 06:00:10売り76円9.77円
2023-09-14(木) 21:16:00売り-120円9.77円
2023-09-14(木) 21:30:10買い-112円9.77円
2023-09-14(木) 22:07:10売り-105円9.77円
2023-09-14(木) 23:00:00買い-106円9.77円
2023-09-15(金) 14:01:10買い161円9.77円
2023-09-15(金) 14:01:50買い-105円9.77円
2023-09-15(金) 23:00:10売り-108円9.77円
開始終了損益手数料
10,000,000円998,323.44円-1,676.56円-291.56円

順調に減っています。そんなに簡単ではない。

実際のデータで自動取引->自動取引(リアルタイムデータテスト)