logo
Published on

TradingViewのチャート上データをデータベースに保存するツール

Authors

トレーダー諸姉諸君はTradingViewにおいてインディケータを無論使っているだろう。それらの数値的なデータは右側サイドメニューの「データウィンドウ」から確認することができる。

アルゴトレード(システムトレード)において、TradingViewを活用する方法は大別して2つある。

  • TradingView上のPine Scriptで売買の意思決定を完結させる。

    buyシグナル、sellシグナルが出るようにアルゴリズムを書き、値が出たらwebhookリクエストして注文を出す。

  • TradingView上のPine Scriptと売買の意思決定アルゴリズムを区分する。

    TradingViewはあくまでインディケータの作成、レンダリング、チャーティングとして用途を限定し、売買の意思決定はそこから得られたデータを元に別のプログラムで行う。

今回のツールは後者の方法を取る場合に有用である。

以下はこのツールがTradingViewのデータウィンドウ上から取得したデータをログしている様子である。

TradingViewのチャート上データをデータベースに保存するツールの動作

上記スクリーンショットではログがされているだけだが、実際にはこのツールはデータベースにデータを保存させる機能を有している。

ツール、というよりも、ツールチェイン、あるいはシステムと呼んだ方が正確かもしれない。

このツールは以下のような構成になっている。

  • Chrome拡張機能

    TradingViewのデータウィンドウ上のデータを取得(スクレイピング)し、データをウェブサーバに送る

  • ウェブサーバ

    Chrome拡張機能から送られてきたデータを受け取り、データベース(mongodb)に保存する

ウェブサーバでインディケータのデータを受け取り

さらに言うと、私のセットアップでは、ここにもう二つのツールがシステムの構成に含まれる。これにより、アルゴトレードのシステムが完全性を持って構築される。

  • アルゴリズムプログラム

    データベースからデータを取得し、売買の意思決定を行う。これは手動、半自動(条件下実行、遅延実行など)、あるいは自動で行われる。

データをデータベース・mongodbに保存

  • ウェブサーバ(トレードサーバ)

    アルゴリズムプログラムからのリクエストを受け取り、注文を出す。これによりポジションの管理が行われる。

以下はこのツールのChrome拡張機能のコードの一部だ。

/**
 * tradingview data emitter
 */

(async () => {
  const sleep = m => new Promise(r => setTimeout(r, m));
  const moment = (await import('https://cdn.jsdelivr.net/npm/moment@2.29.4/+esm')).default;
  const axios = (await import('https://cdn.skypack.dev/axios@1.4.0')).default;
  const URLParse = (await import('https://cdn.skypack.dev/url-parse@1.5.10')).default;
  const uuid = (await import('https://cdn.skypack.dev/@lukeed/uuid@2.0.1')).v4;
  const jsyaml = (await import('https://cdn.skypack.dev/js-yaml@4.1.0')).default;
  const script = (await axios.get(`http://localhost:8080/web/lib/utils.js?ts=${(+new Date())}`)).data;
  eval(script);

  app.console.setLogPrefix("[tradingview data emitter]");

  tabs = await ChromeUtils.getTabs();
  app.console.log("waiting... (a tab matches)")
  const match = `https://www.tradingview.com/chart/`
  await waitUntil(() => typeof tabs.filter(a => a.url.match(match))?.[0]?.id == "number");
  let __target = tabs.filter(a => a.url.match(match))?.[0]?.id;

  const code = `
Array.from(document.querySelectorAll('div[class*=chart-data-window] div[class^=view-]')).map(
    view => {
        const headerTitle = view.querySelector('div[class^="header-"] > span[class^=headerTitle]')?.textContent

// (続く)

このツールおよびシステムの大枠は上述の通りである。

ツールの紹介は以上である。