FMZ 中級チュートリアル

作者: リン・ハーン小草, 作成日:2019年4月12日 14:28:19 更新日:2024年2月5日 20:07:56

[TOC]

img

このチュートリアルでは,FMZプラットフォームの詳細やAPIの使用に関する実践的なスキルを説明します. この中間チュートリアルを学ぶ前に,初心者チュートリアルを読み,FMZの基本的な理解を持つべきです.

FMZを完全に活用し,よりカスタマイズされ,より効率的で,より複雑な戦略を書くことができます.

1.複数の取引所を追加し,複数のシンボルを取引する

1つのロボット内で簡単に複数の取引所と複数のシンボルを取引できます.

  • ロボットを起動するときに 1 つまたは複数の交換を追加します.
  • この API はexchange.GetTicker()1つの交換が追加された場合
  • 複数の交換が追加されると,APIはexchanges[0].GetTicker(), exchanges[1].GetTicker() img
  • 同じ交換を異なるシンボルで追加できますimg
  • 結合するシンボルを変更できます.exchange使用することでIO機能
var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT", "BCC_USDT"]
var buyValue = 1000
function main(){
  for(var i=0;i<symbols.length;i++){
      exchange.IO("currency", symbols[i]) // It is always valid until the next change
      var ticker = exchange.GetTicker()
      var amount = _N(buyValue/ticker.Sell, 3)
      exchange.Buy(ticker.Sell, amount)
      Sleep(1000)
  }
}

2.Tradeフューチャーとスワップ契約

これまでのところ,FMZは,OKEX,HuobiDM,BitMEX,GateIO,Deribitなどのすべての主要先物取引所とそのスワップ契約をサポートしています.

FMZで先物取引をするには まず先物取引所を追加し ボット起動時にそのシンボルを設定し コードに契約型を設定する必要があります

取引所がスポットとフューチャーの両方をサポートしている場合,それらは FMZ に別々に追加されるべきです.img

下の画像は,ボットを起動するときにフューチャーシンボルを BTC に設定する方法を示しています.img

下記は,各取引所の契約タイプを設定する方法です.

  • オーケイ
    exchange.SetContractType("swap")        
    exchange.SetContractType("this_week")   
    exchange.SetContractType("next_week")  
    exchange.SetContractType("quarter")   
  • HuobiDMについて
    exchange.SetContractType("this_week")   
    exchange.SetContractType("next_week")  
    exchange.SetContractType("quarter")     
  • ビットメックス
    exchange.SetContractType("XBTUSD")  
    exchange.SetContractType("XBTM19") 
  • ゲート
    exchange.SetContractType("swap")    
  • デリビット
    exchange.SetContractType("BTC-PERPETUAL")  
    exchange.SetContractType("BTC-27APR18")

3.バックテストについて

基本紹介

FMZには 2 つのバックテストモードがあります.real tickそしてsimulate tick. リアル・ティックレベルには,完了した履歴データ (1秒あたり1つのティック) がすべて含まれているため,バックテスト結果はより信頼性があります. シミュレーションレベルは,戦略によって使用される間隔で履歴クリーンデータを使用します. 1つのクリーン内のティックは,MT4と同じアルゴリズムによって生成されます.https://www.mql5.com/en/articles/75一方,より短い間隔は,を生成するためにベース-klinesとして選択することができます. シミュレーションティックモードは,実際のティックモードよりもはるかに速く,しかし正確性が低い.シミュレーションティックモードでは,より短いクライン間隔は,テストの正確性と速度との間の妥協点である.

バックテスト設定

デフォルトの設定は次のとおりです.img隠された縫い目img

バックテスト結果

img

4.誤差許容性

交換 API にアクセスする任意の関数 (例えばGetTicker, Buy, CancelOrder, etc...), Exchange サーバーの問題,間違ったパラメータ,ネットワーク送信の問題などによりアクセス障害が発生する可能性があります.この場合は,関数は返しますnullロボットが停止するかもしれないので 間違いに対処する方法を知らなければなりません

間違いは何ですか?

ボットがエラーが発生するとエラーメッセージが返されます. 交換名 + エラーMsg を検索すれば,問題は何なのかを見つけることができます. 例えば,エラー{"result":false,"error_code":20049}呼び出し時に返されます.exchange.GetAccount()OKEXで検索しますOKEX 20049これは結果ですimgExchange API ドックでも確認できます.OKEX フューチャースのエラーコード

取引の誤り

戦略コードを書くときにエラーに対処する方法について考えるべきです. 以下はいくつかの例です.

 // 1.Deal when the result is null
 var ticker = exchange.GetTicker()
 while(ticker == null){
     Log('GetTicker error')
     Sleep(100)
     ticker = exchange.GetTicker()
 }
 Log(ticker.Last);
 // 2.Refer when the result is not null
 var ticker = exchange.GetTicker()
 if(!ticker){
     Log(ticker.Last)
 }
 // 3._C() fucntion retry
 var ticker = _C(exchange.GetTicker) // can't  apply _C to CancelOrder, Why?
 Log(ticker.Last)
 // 4. try catch
 try{
     var ticker = exchange.GetTicker()
     Log(ticker.Last)
 }
 catch(err){
     Log('GetTicker error: ', err)
     Log(GetLastError()) //literal means, get last error
 } 

5.直接取引所に接続する

FMZは,すべての異なる交換データを同じフォーマットに包み込み,クロスプラットフォーム戦略を書くことを容易にする.しかし,追加の情報を提供する特定のAPIの特定のデータを入手できず,FMZがサポートしていないAPIにアクセスできない.この問題には2つの解決策があります.

GetRawJSON は

最後の REST API リクエストで返された元のコンテンツ (文字列) を返します. この文字列は,自分で原始情報を解析するために使用できます.

function main(){
    var account = exchange.GetAccount() //the account doesn't contain all data returned by the request
    var raw = JSON.parse(exchange.GetRawJSON())//raw data returned by GetAccount()
    Log(raw)
}

HttpQuery をインストールする

詳細をすべて調べてくださいHttpQueryについてhttps://fmz-docs.readthedocs.io/en/latest/code_Instruction/Global Function.html#httpquery は,このコードを表示する上で,

HttpQueryこのリクエストの原始データを返します.最初に解析する必要があります.

//FMZ doesn't have a standard function for exchangeInfo that return the trading-information about all symbols. 
var exchangeInfo = JSON.parse(HttpQuery('https://api.binance.com/api/v1/exchangeInfo'))
Log(exchangeInfo) // FMZ doesn't have a standard function for this API
var ticker = JSON.parse(HttpQuery('https://api.binance.com/api/v1/ticker/24hr'))
Log(ticker)

公開されたAPIではHttpQueryこの関数は,HttpQueryPythonでは JavaScriptのみをサポートしています.urlib2またはrequestHTTP リクエストを直接送信します

IO

プライベートなAPIでは,HttpQueryAPIキー,サイン,ハッシュ等を扱う必要があります.IOこの条件のために便利な関数です,それをチェックしてくださいhttps://fmz-docs.readthedocs.io/en/latest/code_Instruction/Extent API.html#io. IOこの部分では,私的なAPIへのアクセスだけに焦点を当てます.

この機能を使用するには,最初に取引所のオリジナル API を理解する必要があります.以下は,BitMEX で FMZ がサポートしていないストップオーダーを作成するための手順です.

  • まず,BitMEX APIのドキュメントページを見つけます.https://www.bitmex.com/api/explorer/
  • 停止命令を行うURLはhttps://www.bitmex.com/api/v1/order方法としてPOST,パラメータには,シンボル,サイド,orderQty,stopPx,ordTypeが含まれます.これは"シンボル=XBTUSD&side=Buy&orderQty=1&stopPx=4000&ordType=Stop"のように配置する必要があります.

最終的なJavaScriptコード:

var id = exchange.IO("api", "POST", "/api/v1/order", "symbol=XBTUSD&side=Buy&orderQty=1&stopPx=4000&ordType=Stop")

6.Webソケットを使用

基本的にはすべてのデジタル通貨取引所はwebsocket経由で市場データを送信することをサポートしており,一部の取引所はアカウント情報を更新することもサポートしています. Websocketは,通常,残りのAPIと比較して遅延が低く,周波数が高く,プラットフォームの残りのAPI要求頻度によって制限されません.デメリットとしては,中断され,処理が直感的ではありません.

JavaScript は JavaScript を使うことができます.DialPythonでは,Webソケットに接続する関数を使用できます.Dialまたはwebsocket_client libray.

このチュートリアルでは JavaScript を使って Webソケットを接続することに焦点を当てます.DialFMZ 量子化プラットフォーム上の機能.様々な用途を拡張するために,ダイヤル機能は数回更新されています.このチュートリアルでは,webソケットベースのイベント駆動戦略と複数の交換に接続する方法を示します.

Webソケットに接続

  • 1.ほとんどの場合,直接接続できます.下記は,Binance all tickerに接続する例です.
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
    
  • 2.圧縮形式の返却データについては,接続時に指定する必要があります.compressデータが圧縮形式にあることを意味し,パラメータmodeOKEX に接続する例
    var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
    
  • 3.ダイヤル機能は,基礎となるGo言語で実行される自動再接続をサポートします.リクエストデータコンテンツは,Biannceの例のように,URLに既に含まれています.これは便利で推奨されます.サブスクリプションメッセージを送信する必要がある方には,再接続を自分で維持できます.
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr?reconnect=true")
    
  • 4.Binanceのようないくつかの取引所購読チャンネルがURLに含まれていますが,Coinbaseのようなサブスクリプションチャンネルを送信する必要があります.
    var client = Dial("wss://ws-feed.pro.coinbase.com", 60)
    client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
    

データ受信

Webソケットからのデータは,通常,無限のループでスリープなしで継続的に読み取れます.コードは以下のとおりです:

function main() {
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
    while (true) {
        var msg = client.read() //receve data from client
        var data = JSON.parse(msg) //change raw string to js object
        // do something, don't need sleep. 
    }
}

Webソケットはデータを非常に迅速にプッシュします.ドーカーの基礎は,キュー内のすべてのデータをキャッシュし,プログラムが呼び出すときに最初のものを返します.readロボットのネットワーク操作はBuy,GetAccount,CancelOrder取引プッシュ,アカウントプッシュ,サブセットディーププッシュなどの情報には,歴史的なデータが必要です.市場データについては,通常最新のデータだけを気にします.

についてread()この関数は,配列に引数がない場合,最古のデータを返し,データがない場合,ブロックします (プログラムがここで一時停止されます). 最新のデータを欲しければ,read(-2)最新のデータを即座に返却しnull列にデータがない場合 (プログラムが一時停止しない).

複数のWebソケットに接続する

プログラムがシンプルな方法を使うことはできません.read()交換は新しいデータをブロックし,新しいデータを待っていて,別の交換はすぐに新しいデータを受け取らないからです.一般的な処理は:

function main() {
    var binance = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
    var coinbase = Dial("wss://ws-feed.pro.coinbase.com")
    coinbase.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
    while (true) {
        var msgBinance = binance.read(-1)
        var msgCoinbase = coinbase.read(-1)
        if(msgBinance){
            // Binance has new data
        }
        if(msgCoinbase){
            // coinbase has new data
        }
        Sleep(1) // just sleep 1ms
    }
}

Webソケットを使用するための一般的枠組み

プッシュデータが既に使用されているため,プログラムは自然にイベント駆動型として書かれ,API要求頻度に注意を払います.

var tradeTime = Date.now()
var accountTime = Date.now()
function trade(data){
    if(Date.now() - tradeTime > 2000){//only trade once within 2s
        tradeTime = Date.now()
        //trading code
    }
}
function GetAccount(){
    if(Date.now() - accountTime > 5000){//only get account once within 5s
        accountTime = Date.now()
        return exchange.GetAccount()
    }
}
function main() {
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
    while (true) {
        var msg = client.read()
        var data = JSON.parse(msg)
        var account = GetAccount()
        trade(data)
    }
}

すべてのプライメーター

パラメータDial(Address, Timeout): Timeout:接続のタイムアウト アドレスは他のパラメータによってフォローすることができます.&アドレスとパラメータは|,

パラメーター 記述
圧縮する 圧縮方法gzip_raw, gzip. OKEXの利用gzip_raw
モード かもしれないdual送信と受信の両方が圧縮される必要があります.send圧縮される必要があります.recv受け取るという意味です
代理 ss5のプロキシ設定socks5://name:pwd@192.168.0.1:1080
再接続する Reconnect=true再接続を可能にするために
インターバル interval復試間隔で,デフォルトは1000msです
パイロード wss が再接続するときに送信する必要があるサブスクリプションメッセージ

パラメータread()について Webソケットが切断されたときread()文字列を返します.

パラメーター ない -1 -2 2000
列は空ではありません 最古のデータをすぐに返します 最古のデータをすぐに返します 最新のデータをすぐに返します 最古のデータをすぐに返します
列は空いている 新しいデータが戻るまでブロックする 返信するnullすぐに 返信するnullすぐに 新しいデータが戻るまで2000ms未満を待つ,そうでなければ,戻るnull

薬剤の使用close()について Webソケット接続を閉じる.

function main() {
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
    client.close()
}
    

7.非同期または多スレッド

今,私たちが持っているすべてのコードは,シングルスレッド,順序実行です. 原始JavaScriptは,非同期に対応していません. しかし,FMZは,関数を提供するGO制限されています.Go遅延や API リクエストの時間消費を気にします

交換.Go (方法,Args)

方法:関数の名前 方法の議論.

サポートされている機能リスト:GetTicker, GetDepth, GetTrades, GetRecords, GetAccount, GetOrders, GetOrder, CancelOrder, Buy, Sell, GetPosition.

JavaScript の例:

function main(){
    var a = exchange.Go("GetTicker"); //GetTicker Asynchronous multithreaded execution
    var b = exchange.Go("GetDepth");
    var c = exchange.Go("Buy", 1000, 0.1);
    var d = exchange.Go("GetRecords", PERIOD_H1);
    // The above four operations are concurrent multi-threaded asynchronous execution, will not block and immediately return
    var ticker = a.wait(); // Call wait method wait for return to asynchronous get ticker result
    var depth = b.wait(); // Return depth, it is also possible to return null if it fails
    var orderId = c.wait(1000); // Return the order number, 1 second timeout, timeout returns undefined, this object can continue to call wait until the last wait timeout
    var records = d.wait(); // Wait for K-line result
    var ret = d.wait();  // Here waits for an asynchronous operation that has waited and ended, returns null, and logs an error message.
}

wait()函数に呼び出す必要があります.Goエラーが返されます. エラーが返されます.

8.表とグラフ

LogStatusテーブル

ログステータスはボットのステータスバーにメッセージやテーブルをログします. 毎回リフレッシュします.

//Normal uses of LogStatus
LogStatus(" This is a normal status prompt")
LogStatus(" This is a red font status prompt #ff0000")
LogStatus(" This is a multi-line status message\n I'm the second line")

ログステータスはロボットページのテーブルをログすることができます.追加`複雑なメッセージ形式として扱う (現在サポートされている表).

var table = {type: 'table', title: ' Account information support color #ff0000', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]}
LogStatus('`' + JSON.stringify(table)+'`')
//Another example, information can also appear in multiple lines:
LogStatus("First line message\n" + JSON.stringify(table)+"`\n third line message")
//Log multiple tables in a group, switching by TAB:
var table1 = {type: 'table', title: ' Account information 1', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]}
var table2 = {type: 'table', title: ' Account information 2', cols: ['BTC', 'ETH', 'USDT'], rows: [ ['free', 1, 2000], ['frozen', 0, 3000]]}
LogStatus('`' + JSON.stringify([table1, table2])+'`')

図表

ロボット管理ページに数字を描いてください チャートサポート ハイストックとハイチャート,チェックhttps://www.highcharts.com/demoそしてhttps://www.highcharts.com/stock/demo詳細については グラフオブジェクトには__isStock元の文字には存在しない属性.__isStockグラフは HighCharts として表示されます.__isStockグラフは HighStocks として表示されます.reset()グラフのデータをクリアします

2つのシンボルの価格を描くためのチャートを使用するJavaScriptの例:

// This chart is an object in the JS language. Before using the Chart function, we need to declare an object variable chart that configures the chart.
var chart = {
    // Whether the mark is a general chart, if you are interested, you can change it to false and run it.
    __isStock: true,
    tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},    // Zoom tool
    title : { text : 'Spread Analysis Chart'},          // title
    rangeSelector: {                                    // Selection range
        buttons:  [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
        selected: 0,
        inputEnabled: false
    },
    xAxis: { type: 'datetime'},                         // The horizontal axis of the coordinate axis is the x axis and the current setting type is :time
    yAxis : {                                           // The vertical axis of the axis is the y axis, and the default value is adjusted with the data size.
        title: {text: 'Spread'},                        // title
        opposite: false,                                // Whether to enable the right vertical axis
    },
    series : [                                          // Data series, this attribute is saved for each data series (line, K-line graph, label, etc...)
        {name : "line1", id : "Line 1,buy1Price", data : []},  // The index is 0, the data array is stored in the index series of data
        {name : "line2", id : "Line 2,lastPrice", dashStyle : 'shortdash', data : []},
        // The index is 1, dashStyle is set: 'shortdash' ie: Set the dotted line.
    ]
};
function main(){
    var ObjChart = Chart(chart);                      // Call the Chart function to initialize the chart.
    ObjChart.reset();                                 // Empty the chart
    while(true){
        var nowTime = new Date().getTime();           // Get the timestamp of this poll, which is a millisecond timestamp. Used to determine the position of the X axis written to the chart.
        var tickerOne = _C(exchanges[0].GetTicker);   // Get market data
        var tickerTwo = _C(exchanges[1].GetTicker);
        ObjChart.add([0, [nowTime, tickerOne.Last]]); // Use the timestamp as the X value and buy the price as the Y value to pass the index 0 data sequence.
        ObjChart.add([1, [nowTime, tickerTwo.Last]]); // Same as above
        ObjChart.update(chart);                       // Update the chart to show it.
        Sleep(2000);
    }
}

複数のフィギュアの表示をサポートします,完全な例:https://www.fmz.com/strategy/136056 img

9.戦略のテンプレート

テンプレートは,多くの高度な機能を収録したライブラリで,戦略を書くことを容易にする.テンプレートを使用するには,まず必要なテンプレートをコピーする必要があります.例としてJavaScript Plotライブラリを取って,それをコピーします.https://www.fmz.com/strategy/27293戦略編集ページで選択してください.imgこの関数は$.JavaScript テンプレートと後にext.Pythonのテンプレートで

function main() {
    var isFirst = true
    while (true) {
        var records = exchange.GetRecords();
        if (records && records.length > 0) {
            $.PlotRecords(records, 'BTC')
            if (isFirst) {
                $.PlotFlag(records[records.length - 1].Time, 'Start', 'S')
                isFirst = false
                $.PlotHLine(records[records.length - 1].Close, 'Close')
            }
        }
        var ticker = exchange.GetTicker()
        if (ticker) {
            $.PlotLine('Last', ticker.Last)
            $.PlotTitle('Last ' + ticker.Last)
        }
        Sleep(60000)
    }
}

グラフテンプレートを使用する別の簡単な例です.https://www.fmz.com/strategy/121917


もっと

q25459768ありがとうございました

小草私はこのチュートリアルに取り組んでいます. 完了するのに数日かかります. 任意の質問をすることは自由です.