[TOC]
このチュートリアルでは,FMZプラットフォームの詳細やAPIの使用に関する実践的なスキルを説明します. この中間チュートリアルを学ぶ前に,初心者チュートリアルを読み,FMZの基本的な理解を持つべきです.
FMZを完全に活用し,よりカスタマイズされ,より効率的で,より複雑な戦略を書くことができます.
1つのロボット内で簡単に複数の取引所と複数のシンボルを取引できます.
exchange.GetTicker()
1つの交換が追加された場合exchanges[0].GetTicker()
, exchanges[1].GetTicker()
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)
}
}
これまでのところ,FMZは,OKEX,HuobiDM,BitMEX,GateIO,Deribitなどのすべての主要先物取引所とそのスワップ契約をサポートしています.
FMZで先物取引をするには まず先物取引所を追加し ボット起動時にそのシンボルを設定し コードに契約型を設定する必要があります
取引所がスポットとフューチャーの両方をサポートしている場合,それらは FMZ に別々に追加されるべきです.
下の画像は,ボットを起動するときにフューチャーシンボルを BTC に設定する方法を示しています.
下記は,各取引所の契約タイプを設定する方法です.
exchange.SetContractType("swap")
exchange.SetContractType("this_week")
exchange.SetContractType("next_week")
exchange.SetContractType("quarter")
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")
基本紹介
FMZには 2 つのバックテストモードがあります.real tick
そしてsimulate tick
. リアル・ティックレベルには,完了した履歴データ (1秒あたり1つのティック) がすべて含まれているため,バックテスト結果はより信頼性があります. シミュレーションレベルは,戦略によって使用される間隔で履歴クリーンデータを使用します. 1つのクリーン内のティックは,MT4と同じアルゴリズムによって生成されます.https://www.mql5.com/en/articles/75一方,より短い間隔は,
バックテスト設定
デフォルトの設定は次のとおりです.隠された縫い目
バックテスト結果
交換 API にアクセスする任意の関数 (例えばGetTicker
, Buy
, CancelOrder
, etc...), Exchange サーバーの問題,間違ったパラメータ,ネットワーク送信の問題などによりアクセス障害が発生する可能性があります.この場合は,関数は返しますnull
ロボットが停止するかもしれないので 間違いに対処する方法を知らなければなりません
間違いは何ですか?
ボットがエラーが発生するとエラーメッセージが返されます. 交換名 + エラーMsg を検索すれば,問題は何なのかを見つけることができます. 例えば,エラー{"result":false,"error_code":20049}
呼び出し時に返されます.exchange.GetAccount()
OKEXで検索しますOKEX 20049
これは結果ですExchange 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
}
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
この関数は,HttpQuery
Pythonでは JavaScriptのみをサポートしています.urlib2
またはrequest
HTTP リクエストを直接送信します
IO
プライベートなAPIでは,HttpQuery
APIキー,サイン,ハッシュ等を扱う必要があります.IO
この条件のために便利な関数です,それをチェックしてくださいhttps://fmz-docs.readthedocs.io/en/latest/code_Instruction/Extent API.html#io. IO
この部分では,私的なAPIへのアクセスだけに焦点を当てます.
この機能を使用するには,最初に取引所のオリジナル API を理解する必要があります.以下は,BitMEX で FMZ がサポートしていないストップオーダーを作成するための手順です.
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")
基本的にはすべてのデジタル通貨取引所はwebsocket経由で市場データを送信することをサポートしており,一部の取引所はアカウント情報を更新することもサポートしています. Websocketは,通常,残りのAPIと比較して遅延が低く,周波数が高く,プラットフォームの残りのAPI要求頻度によって制限されません.デメリットとしては,中断され,処理が直感的ではありません.
JavaScript は JavaScript を使うことができます.Dial
Pythonでは,Webソケットに接続する関数を使用できます.Dial
またはwebsocket_client
libray.
このチュートリアルでは JavaScript を使って Webソケットを接続することに焦点を当てます.Dial
FMZ 量子化プラットフォーム上の機能.様々な用途を拡張するために,ダイヤル機能は数回更新されています.このチュートリアルでは,webソケットベースのイベント駆動戦略と複数の交換に接続する方法を示します.
Webソケットに接続
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
compress
データが圧縮形式にあることを意味し,パラメータmode
OKEX に接続する例var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr?reconnect=true")
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()
}
今,私たちが持っているすべてのコードは,シングルスレッド,順序実行です. 原始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
エラーが返されます. エラーが返されます.
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
テンプレートは,多くの高度な機能を収録したライブラリで,戦略を書くことを容易にする.テンプレートを使用するには,まず必要なテンプレートをコピーする必要があります.例としてJavaScript Plotライブラリを取って,それをコピーします.https://www.fmz.com/strategy/27293戦略編集ページで選択してください.この関数は$.
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ありがとうございました
小草私はこのチュートリアルに取り組んでいます. 完了するのに数日かかります. 任意の質問をすることは自由です.