今回は海外の仮想通貨取引所である FTX で提供されている Quant Zoneというサービスについてみていきます。
FTX とは2020年にメイン仮想通貨取引所として一気に知名度を獲得した話題の取引所で、ユニークなサービスをいくつも提供しています。
その取引所が提供するサービスの1つがQuant Zoneです。
Quant Zoneはなんとだれでも自動売買Botを作ることができるサービスということで、
今回はそのQuant Zoneの基本的な使い方と実際に自動売買Botを作ってみるところまでやっていきたいと思います。
もし自動売買Botを作ることができれば、日中は仕事や学業でなかなかチャートを見れない兼業トレーダーの力強い味方になると思うので、ぜひ使い方を身につけてもらえればと思います。
もしまだFTXに登録していない人がいれば下記の記事で取引手数料が5%割引になる招待リンクを載せているのでぜひ登録してみてください。
(ちなみにこの記事かなり長いので挫折率高いかもしれません。。笑)
Quant Zoneとは
ここでは改めてQuant Zoneについて紹介していきます。
Quant Zoneとは最低限のプログラム(Excelの数式レベル)を書くだけで自動売買Botを運用できる革新的なサービスです。
普通、自動売買Botを運用するとなれば取引するためのプログラムを書くことはもちろん、そのプログラムを24時間365日動かしておくためのパソコン(いわゆるサーバー)を用意して、そのパソコンで自動売買Botを動かせるようにソフトやらツールをインストールして〜〜うんたらかんたら
というようにプログラムを書く以外にも手間と知識が必要で、さらにトレードの勝ち負けに関わらずサーバー代も月々払う必要が出てきます。
しかし FTX の Quant Zone を使えば取引をするためのプログラムが簡単に書けるだけでなく、それ以降(サーバー準備など)の作業は必要なくすぐに運用を開始できます。
もちろんサーバー代もかかりません。
他のブログ記事ではほとんど言及されていませんが、このサーバーを用意せずに自動売買Botを作れるというのは Quant Zone 最大の魅力だと私は思っています。
また今ある他のブログ記事では予め決めた価格に指値を入れるだけの使い物にならないBotをレンジ用Botなどと称して紹介しているばかりで Quant Zone が使えないサービスだと勘違いしている人も多いと思います。
(なんならインジケータを使ったBotは作れないと言っている記事まであります。。)
たしかに自分でイチからプログラムを書いて自動売買ルールを作るのと比べると制限はあります。
ただ、それでも工夫次第で実用的なBotを作ることは十分可能だと思っています。
なのでこの後の実際に自動売買Botを作るところでは、このブログで何度もお世話になっているいSMAを使ったゴールデンクロス・デッドクロス(GCDC戦略)をBotとして作って、インジケータを使ったBotを作れることを見せていきたいと思います。
Quant Zoneの基本的な使い方
ここからは Quant Zone の具体的な使い方について説明していきます。
1. Quant Zoneの画面を開く
まずは Quant Zone の画面の開き方について説明していきます。

① 左上の Windows みたいな四角マークをクリックすると、メニューが表示されるのでその中から Quant Zone をクリックしてください

② Quant Zone のトップ画面が開かれるので、 GET STARTED をクリックしましょう
これで Quant Zone のマイページを開くことができます。
画面の見方
続いて画面の見方について説明していきます。
まずはマイページの見方についてです。

CREATE NEW RULE:新しいルールを作る画面に遷移するためのボタン。詳しくは後述しますが、ルールというのはトリガーとアクションの2つの要素から作るもので、ルールを組み合わせて1つのBotを作ることになります。
Rules:これまで作ってきたルールの一覧です。左から ルール名/最終更新日時/状態(有効か無効か) を表示しています。
少し下にスクロールします。

Logs:ルールの有効化/無効化や有効化されたルールのアクションが実行された時のログを一覧で表示しています。最大50件までしか表示されない点に注意してください。
少し下にスクロールします。

Variables:アクションで設定した変数が一覧で表示されます。変数名、現在の値以外に右側のペンのマークをクリックすることでこの画面から変数の値を変更することができます。
以上でマイページの画面の説明は以上です。
続いてルール作成画面の説明をしていきます。
先ほどの CREATE NEW RULES ボタンをクリックしてルール作成画面を開きます。

Rule Name:ルール名を入力します。
Trigger:そのルールのトリガーを設定します。有効化されているルールは15秒に1回自動的に実行されます。その時にこのトリガーの内容の実行結果が true ならこの後に続くアクションの処理を実行します。実行結果が false ならアクションは実行せずに終了します。

Actions:トリガーの結果が true だった時に実行する処理を設定します。Type で処理の内容を選ぶことができ、大別すると 注文/ルールの一時停止/変数設定 があります。
ADD ACTION:アクションを追加するボタンです。いくつまで追加できるのかわかりませんが、少なくとも5つ以上は追加できます。
SAVE DRAFT:作っているルールを下書きとして保存します。つまりは無効化状態で保存するということですね。
SAVE AND RUN:作っているルールを有効化して保存します。次の15秒後から処理が実行されます。
以上で画面の説明はおわりです。
はじめは戸惑うかもしれませんが、画面やボタンは少ないのですぐ慣れると思います。
トリガーの設定方法
続いてトリガーの設定方法について説明します。
上述したようにトリガーにはアクションを実行するかどうかの条件を書きます。
なのでトリガーの実行結果は真偽値(boolean)になる必要があります。
もし真偽値がなにかわからない方はこちらの記事でプログラミングに必要な最低限の知識を説明していますので合わせて読んでみてください。
例えばデフォルトで入力されている条件では BTC-PERP(つまりBTC価格) が 9000 より大きければ true になり、アクションが実行されるように設定されています。
price("BTC-PERP") > 9000
トリガーの条件式にはもちろん and や or を使って複雑な式を設定することもできます。
アクションの設定方法
最後にアクションの設定方法について説明していきます。
アクションでは 注文/ルールの一時停止/変数の設定 ができます。
Typeからどの処理を設定するか選べます。

Open Position:ポジションを構築する注文を出せます。注文は指値注文になります。
Close Position:ポジションを決済する注文を出せます。こちらも指値注文になります。
Place Custom Order:上の2つより複雑な注文を出せます。成行や逆指値注文も出せます。注文するときにはこれを使うことが多そうです。
Cancel Custom Order:ルールを指定していま出している注文をキャンセルすることができます。
Pause Rule:ルールと時間を指定して一時停止することができます。
Unpause Rule:ルールを指定して一時停止を解除できます。
Set Variable:変数を設定・代入できます。変数は get_variable(“変数名”) で呼び出すことができます。
Place Custom Order について
まずは Place Custom Order です。

Order Type / Side / Market / Order Size で 注文方法 / 売りor買い / 銘柄 / 注文量を指定できます。
Reduce Only:注文量をポジション量に合わせて調整してくれるオプションです。もしチェックを入れずにポジション量よりも注文量が多い場合、その分ドテンすることになります。
Post Only:注文を入れる時にテイカーにならないように注文するオプションです。
IOC:注文がすぐに約定されないときにキャンセルしてくれるオプションです。
その下の If an order already exists: は既にポジションがある場合にポジションをそのままにしておくか、前の注文はキャンセルするかというオプションです。
一番下は注文を出したあとにルールのトリガーが false になったときに注文をキャンセルするオプションです。
このように Quant Zone では様々な注文オプションを提供しているので注文方法で困るということはほとんどないと思います。
Set Variable について
続いて Set Variable です。

Variable Name:変数名を設定します。
Variable Value:変数に入れる値を入力します。
この変数設定について注意点が3つあります。
まず1つめが Variable Value には数値型と真偽値のデータしか入れられないということです。
文字列などは入れることができません。
2つめの注意点は変数の値を入力する欄には文字数制限があるのであまりに長いコードは書けないということです。
3つめの注意点は、変数に値が代入されるのはそのルールの処理が終了するタイミングということです。
なので同じルール内で上のアクションで変数に設定した値を下のアクションで参照するということができません。
自動売買Botを作る
それでは今までの内容を踏まえて実際にいつものアレ(GCDC戦略)を作っていきます。
まずはGCDC戦略のパフォーマンスについて改めて見ておきたいと思います。

デフォルトのストラテジーでこのパフォーマンスはすごいですね。。笑
直近少し成績落ちてますがそれでも十分利益を上げてくれています。
手動でやるとなるとめんどくさくてやらない人も多いと思うんですが、今回はBot化するので一度作ってしまえば後は放置しておくだけで済むのがありがたいですね。
投資資金の大半をこれに突っ込むんじゃなく、資金の何割かをこのBotにあててあげるだけでもかなりメンタル的に安定しそうです。
それでは手法整理をして実際に作っていきたいと思います。
手法整理についてはこちらの記事で説明しています。
手法整理
今回のGCDC戦略(1時間足)を整理すると下記のようになります。
エントリー条件
- 買い:ローソク足が1本前の14期間SMAが28期間SMAの下にあり、今の14期間SMAが28期間SMAより上にある場合に買い。売りポジションがある場合はドテンする。
- 売り:ローソク足が1本前の14期間SMAが28期間SMAの上にあり、今の14期間SMAが28期間SMAより下にある場合に売り。買いポジションがある場合はドテンする。
整理した内容から少なくとも 14期間SMAと28期間SMA、1本前の14期間SMAと28期間SMAの変数が必要になることがわかりました。
それではその4つの変数を設定し、その値を使って注文するルールを作っていきたいと思います。
実際にBotを作る
14期間SMAの変数を設定する
まずは14期間SMAの変数を設定するルールを作っていきます。
CREATE NEW RULE をクリックして新しいルールを作ります。
ルールを作ったら、わかりやすいように Set 14 SMA とルール名をつけます。

続いてトリガーを設定します。
ここについてはずっと動いていても困らないので true と設定してもいいのですが、遅延等で変なタイミングでエントリーしてしまわないように 00分 から 05分 の間で起動するようにします。
現在時刻の分を取得するには minute という変数が既に用意されているのでこれを使います。
minute >= 0 and minute <= 5

次にアクションを設定します。
ここのアクションでは14SMAと1本前の14SMAを変数に設定します。
アクションの Type を Set Variable に指定して、ADD ACTION をクリックしてアクションを2つにします。
1つめのアクションでは1本前のSMAを変数に設定する処理を書きます。
変数名は oldSma14 としておきます。
いまは設定していませんがもし14期間SMAの変数を持っている場合、このアクションが実行されるときにはその値は1本前のSMAの値になっているので、その変数を呼び出して1本前の14SMAの変数に代入しましょう。
自分で設定した変数を呼び出すには get_variable(“変数名”) という関数を使えばよいので、Valueは下記のようになります。
get_variable('sma14')

2つめのアクションではいまの14期間SMAを設定します。
変数名は先ほど出ていたように sma14 としておきます。
Pineスクリプトのように14期間SMAの値を得るための SMA 関数があれば便利なのですが、残念ながら Quant Zone にはそういう関数がないので自分で作る必要があります。
価格データを得るためにはこの2つの関数を使います。
# 現在の BTC-PERP の価格を取得する
price("BTC-PERP")
# 60分前の BTC-PERP の価格を取得する
price("BTC-PERP", 60)
この2つの関数を使って14期間分の価格の合計値を計算して、それを14で割ることでSMAを算出するとこのようになります。
(price("BTC-PERP") + price("BTC-PERP", 60) + price("BTC-PERP", 120) + price("BTC-PERP", 180) + price("BTC-PERP", 240) + price("BTC-PERP", 300) + price("BTC-PERP", 360) + price("BTC-PERP", 420) + price("BTC-PERP", 480) + price("BTC-PERP", 540) + price("BTC-PERP", 600) + price("BTC-PERP", 660) + price("BTC-PERP", 720) + price("BTC-PERP", 780)) / 14

これで Set 14 SMA ルールは完成かと思ったのですが、間違いがありました。
トリガーのところでいくら実行されても構わないといったのですが、oldSma14 に1本前(1時間前)の14SMAの値を代入するには何度も動かさずに1時間に1回だけ動かす必要がありそうです。
でなければ oldSma14 には前回(15秒前)の sma14 の値が入ってしまいます。
なのでその修正をしていきます。
修正方法としては以下のことが必要です。
- sma14 に値をセットした目印(フラグ)として hasSma14 変数に 1 という値を入れるアクションを追加します。
- トリガーに hasSma14 の値が 0 なら実行するという条件を追加する
- 別のルールとして minute が 05分 より大きくなれば hasSma14 の値を 0 に戻すという処理を入れる
これで1時間に一度だけ Set 14 SMA のアクションが実行されるようになります。
1 と 2 の対応をしたトリガーとアクションは次のようになります。


このルールを SAVE DRAFT で保存しておきます。
28期間SMAの変数を設定する
続いて14期間SMAと同様のやり方で28期間SMAを設定していきます。
Set 28 SMA という名前で新しいルールを作ります。
トリガーも14SMAのときと同じように00分から05分の間で動くようにします。
(hasSetSma28 は変数を定義した時に条件に追加します)
minute >= 0 and minute <= 5

続いて1本前の28SMAを oldSma28 という変数にsma28を代入して設定します。

この辺は先ほどとほぼ同じなので難しくないかなと思います。
次にこちらも前回同様 price 関数を多用して 28SMA を計算していきたいと思います。
(price("BTC-PERP") + price("BTC-PERP", 60) + price("BTC-PERP", 120) + price("BTC-PERP", 180) + price("BTC-PERP", 240) + price("BTC-PERP", 300) + price("BTC-PERP", 360) + price("BTC-PERP", 420) + price("BTC-PERP", 480) + price("BTC-PERP", 540) + price("BTC-PERP", 600) + price("BTC-PERP", 660) + price("BTC-PERP", 720) + price("BTC-PERP", 780) + price("BTC-PERP", 840) + price("BTC-PERP", 900) + price("BTC-PERP", 960) + price("BTC-PERP", 1020) + price("BTC-PERP", 1080) + price("BTC-PERP", 1140) + price("BTC-PERP", 1200) + price("BTC-PERP", 1260) + price("BTC-PERP", 1320) + price("BTC-PERP", 1380) + price("BTC-PERP", 1440) + price("BTC-PERP", 1500) + price("BTC-PERP", 1560) + price("BTC-PERP", 1620)) / 28
これを Variable Value の欄に入力します。すると、、

式が長すぎてエラーが出ています。。。
しかしSMAを計算してくれる関数がない以上はこのように足し上げていくしかありません。
どうすればいいでしょうか。
私は今回、Set 14 SMA のルールに新しく sum14 という変数を定義し、28SMAを計算するときは (sum14 + 15~28期間までの価格) / 28 で計算することで回避しようと考えました。
なのでここで一度 sma28 のアクションを消し、SAVE DRAFT で保存して再び Set SMA14 ルールに戻ります。
戻ってきたら sum14 のアクションを追加して、sma14 の Variable Value の14で割る前の式をそのままコピペします。
(アクションの順番は実行順序と関係ありませんが、並び的に私は sum14 のアクションは sma14 の前に持ってきました)
price("BTC-PERP") + price("BTC-PERP", 60) + price("BTC-PERP", 120) + price("BTC-PERP", 180) + price("BTC-PERP", 240) + price("BTC-PERP", 300) + price("BTC-PERP", 360) + price("BTC-PERP", 420) + price("BTC-PERP", 480) + price("BTC-PERP", 540) + price("BTC-PERP", 600) + price("BTC-PERP", 660) + price("BTC-PERP", 720) + price("BTC-PERP", 780)

これで SAVE DRAFT で保存して、 Set 28 SMA のルールに戻ります。
次に sma28 のアクションを追加する前にトリガーに1つ条件を追加する必要があります。
それは Set 28 SMA のルールのアクションは必ず Set 14 SMA が実行された後に実行されなければならないということです。
でなければ sma28 を計算する時に1時間前の sum14 を参照して計算してしまいかねません。
なので hasSetSma14 の変数を使ってトリガーに条件を追加します。
minute >= 0 and minute <= 5 and get_variable('hasSetSma14') == 1

これでやっと sma28 のアクション追加に戻ってこれました。
それでは用意した sum14 を使ってアクションを作ります。
(get_variable('sum14') + price("BTC-PERP", 840) + price("BTC-PERP", 900) + price("BTC-PERP", 960) + price("BTC-PERP", 1020) + price("BTC-PERP", 1080) + price("BTC-PERP", 1140) + price("BTC-PERP", 1200) + price("BTC-PERP", 1260) + price("BTC-PERP", 1320) + price("BTC-PERP", 1380) + price("BTC-PERP", 1440) + price("BTC-PERP", 1500) + price("BTC-PERP", 1560) + price("BTC-PERP", 1620)) / 28

最後に hasSetSma28 を定義して、それもトリガーの条件に組み込みたいと思います。
# トリガー
minute >= 0 and minute <= 5 and get_variable('hasSetSma14') == 1 and get_variable('hasSetSma28') == 0


これで SAVE DRAFT で保存して 28SMA の設定も完了です。
注文する
ここからは今まで作ってきたSMAの変数を使って注文するルールを作っていきます。
GCDC Long という名前で新しくルールを作り、買いエントリーするルールを設定していきます。
ここで買い条件を振り返ってみます。
買い:ローソク足が1本前の14期間SMAが28期間SMAの下にあり、今の14期間SMAが28期間SMAより上にある場合に買い。売りポジションがある場合はドテンする。
この条件にいつもの00分から05分までの条件を加えます。
さらにここにもう少し条件を入れる必要があるのですがおわかりになりますでしょうか?
正解は、14SMAと28SMAの計算が終わっていること という条件です。
この条件を踏まえてトリガーを設定していきます。
minute >= 0 and minute <= 5 and get_variable('hasSetSma14') == 1 and get_variable('hasSetSma28') == 1 and get_variable('oldSma14') <= get_variable('oldSma28') and get_variable('sma14') >= get_variable('sma28')

次に注文のアクションを追加していきます。
買いトリガーが true になった場合、売りポジションの決済と新規の買いポジションの注文の2つを行う必要があります。
まず決済の方から設定していきます。
設定値をこのようにしてください。
- Type:Place Custom Order
- Order type:Market order(成行)
- Side:buy
- Market:BTC-PERP
Order sizeに関しては今回は 0.01(BTC) の固定としますが、balance(“BTC”) でBTCの残高を取得できるので、現在価格と計算して数量を決定するように設定もできます。
# BTCの残高をレバ4倍で目一杯購入
balance("BTC") * 4
# USDTの残高でレバ1倍分で購入
price("BTC-PERP") / balance("USDT")
注文のオプションについてですが、Reduce Only にチェックを入れることで決済注文にすることができます。
その下のオプション(注文時に過去注文がアクティブな場合どうするか)については成行注文なのであまり関係ありませんが、念の為キャンセル(Cancel and place a new order)にしておきます。

これで決済注文の設定は終わりです。
新規の買いポジション注文については決済注文の Reduce Only 無しバージョンなので瞬殺です。笑

次に買い注文ルールにも hasOrder 変数を定義して、トリガーに条件を追加します。
でなければ00分から05分の間にひたすら買い注文を入れ続けてしまうので。
# トリガー
minute >= 0 and minute <= 5 and get_variable('hasSetSma14') == 1 and get_variable('hasSetSma28') == 1 and get_variable('oldSma14') <= get_variable('oldSma28') and get_variable('sma14') >= get_variable('sma28') and get_variable('hasOrder') == 0


あとは保存すれば買い注文ルールについては終了です。
次に売り注文ルールを作っていきます。
ほぼ買い注文の逆バージョンなので簡単です。
GCDC Short という名前でルールを作ります。
ここで売り条件を振り返ってみます。
売り:ローソク足が1本前の14期間SMAが28期間SMAの上にあり、今の14期間SMAが28期間SMAより下にある場合に売り。買いポジションがある場合はドテンする。
つまり買いトリガーのSMAの条件を逆にすればいいだけですね。コピペで持ってきてちょちょいと修正してしまいましょう。
(コピペなのでそのまま hasOrder についても最初から入れてしまいます)
minute >= 0 and minute <= 5 and get_variable('hasSetSma14') == 1 and get_variable('hasSetSma28') == 1 and get_variable('oldSma14') >= get_variable('oldSma28') and get_variable('sma14') <= get_variable('sma28') and get_variable('hasOrder') == 0

次に注文アクションですが、これも買い注文の時の Side を buy から sell に変えるだけなのでサクッとやっちゃいましょう。
売り注文も決済アクション->注文アクションの順で私は設定しました。


最後に hasOrder 変数を定義します。

これで売りルールの方も設定終了です。
あと少しで完成なので頑張ってください!
フラグをリセットする
最後に hasSetSma14 と hasSetSma28 と hasOrder のフラグをリセットするルールを作ります。
このルールがないと一度動いたきりフラグが立ちっぱなしになって一生アクションが実行されなくなってしまうので。
Reset Flag という名前でルールを作ります。
トリガーについては、このルールはSMA計算から注文までの処理が終わった後に実行されてほしいので06分以降に実行されるようにします。
minute > 5

アクションは3つの各フラグをリセットするようにします。


これでBotの処理が一通り終わって時間が経つと次の実行に向けてフラグがリセットされるようになったので、Botが毎時間動けるようになりました。
以上でBot開発終了です!お疲れ様でした!!
あとはこれまで作ったルールをルール一覧で enable(有効化)すればずっと放置でも常にチャートを見張ってエントリーしてくれるようになります。
マイページのルールから一つ選択すると ENABLE RULE と出るのでこれをクリックするだけで有効化されます。

完成品
最後にそれぞれのルールの完成品をまとめて載せておきます。
Set 14 SMA



Set 28 SMA


GCDC Long


GCDC Short


Reset Flag


作ってみてわかったメリット・デメリット
次に私が Quant Zone でBot開発をしてみて感じたメリットとデメリットについて挙げていきたいと思います。
メリット
- 記述した条件式の結果やValueの値を下に表示してくれるから間違ってないか確認しやすい
- 関数を用意してくれてるのがまあまあ便利
- セーブ時に文法のエラーチェックをしてくれる
- パーツを作って組み合わせていく感覚がパズルみたいで作ってて楽しい
- システムに詳しくなくてもLogsを見ればルールが動いてるかどうかわかるし、変数のセットされた値やエラーの原因がわかる
特にプログラミングに慣れてない人からすると1番の値表示してくれる機能はわかりやすくて良さそうだと感じました。
個人的には4番のパズル感が、ルール作っててゲーム感覚で楽しくなったので次どんなの作ろうかなと思えたのが最大のメリットでした。
デメリット
- 書き方がだいぶわかりづらい
(Pineスクリプトに慣れるとずらずらコードを書いたほうがわかりやすく感じる) - Actions のコードの長さが決まっているのであまりに長いコードは書けない
特に2番!これはほんとにいただけない!
28期間SMAを作るのにまさか一工夫必要だとは思いませんでした。。
逆にそうなった時に解決策が浮かんだ時の脳汁感はメリットかもしれませんが。笑
おわりに
今回はFTXの Quant Zone の使い方について見てきました。
ほんとに長い記事になってしまったんですが、ここまで読んでくださった皆さんありがとうございます。そしてほんとうにお疲れ様でした。
もしこの記事を読んで Quant Zone に興味が出たらまずは今回作ったGCDC戦略の真似でもいいのでぜひ自分の手を動かしてやってみてください。
FTXの手数料5%Offの招待リンクもあるので、登録の際にはこちらもよろしくおねがいします。
次回は過去に行われた Quant Zone のコンペティションで優勝した自動売買Botを作っていきたいと思います。
記事としてなにか取り上げて欲しいトピックやPineスクリプトでわからないところ等ありましたらTwitterアカウントにDMか質問箱に投稿していただければと思います。

今回はここまでです。お疲れ様でした。
コメント
まさに探してる情報です!
素人ですが触れそうです。
丁寧にありがとうございます\(^o^)/