[TOC]
これは初心者のための基本的な説明です. APIのドキュメントの完全なバージョンについては,FMZ APIこのチュートリアルには含まれていない多くのスペックがあります.
FMZの仕組みを知って,基本的な戦略を書けるようになるでしょう.
FMZプラットフォームとは?
FMZは,多くのビットコイン/eth/altcoin取引市場をサポートする仮想通貨トレーダーの自動取引プラットフォームです.
FMZは何ができるの?
オープンソースコードをたくさん含む私たちの戦略
FMZはどの仮想通貨取引所をサポートしていますか?
FMZは,ほぼすべての取引所をサポートしています.Binance
, Bitfinex
, Bitstamp
, OKEX
, Huobi
, Poloniex
取引もできます.OKEX
そしてBitMEX
サポートリストをチェックしてくださいAPIすべての取引所で変更なしに実行するだけです.
FMZ はどのプログラミング言語をサポートしていますか?
FMZ は JavaScript,Python,C++ (JavaScript と Python が推奨されます) をサポートし,戦略をコードします.完成した言語のサポートを利用して (カスタム言語は1つのプラットフォームにのみ使用できるわけではありません),プログラミングスキルを向上させ,戦略を書くことを学ぶことができます.
API キーが安全ですか?
暗号化後,APIキーが保存されます.
https
.現在の機能リスト:
ロボットを実行するには 戦略が必要です 交換を追加し ドーカーを最初に展開します ドーカーとは 自身のコンピュータやサーバーで実行されている 戦略の実行者です
主ページの簡単な見方
交換を追加する
追加するhttps://www.fmz.com/m/add-platformまたはクリックPlatform
ラベル
アクセスキーと秘密キーは暗号通貨取引所で適用できます. API-KEYは取引に使用され,取引所からのプライベート情報を取得します. 私たちはサーバーにAPI-KEYやパスワードを保存しません.
FMZで登録できますシミュレーション交換テストのために追加します
ドーカーを展開する
FMZはボットを実行しません. 実行者としてドッカーを自分で展開する必要があります. 私たちのサービスはボットを実行することに参加しないため,より柔軟で安全です. 公開ドッカーも提供していますが,テストのためにのみ使用する必要があります.
Windowsでは,非常に簡単です. 指示に従ってくださいhttps://www.fmz.com/m/add-node
Linux の場合は,docker を自動的に展開する VPS を当社のウェブサイトでレンタルできます.自分の Linux サーバーに展開するための手順は以下です (推奨):
wget www.fmz.com/dist/robot_linux_amd64.tar.gz
命令が見つかりませんでした.yum install wget -y
.tar -xzvf robot_linux_amd64.tar.gz
解き放つ./robot -s node.fmz.com/xxxxx -p -p yourFMZpassword
想像してみてください2018/07/05 05:04:10 Login OK, SID: 62086, PID: 7226, Name: host.localdomain
つまり,すべては処理されています.node.fmz.com/xxxxx
ユーザーごとにユニークですhttps://www.fmz.com/m/add-node.ctrl + C
ドーカーを停止するnohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &
このステップは,また,実行することができますScreen
command.戦略を書いて
編集ページの使い方を示すために簡単なJavaScript戦略をデモとして使用します. 戦略は,編集ページからコピーすることができます.https://www.fmz.com/strategy/125482- わかった このチュートリアルでは JavaScript の使い方を説明しません. ネットでたくさんのチュートリアルがあります.
Ctrl+S
編集モードに携帯にメッセージを送信するには,電報をアカウントにhttps://www.fmz.com/m/account
/*
This strategy will send a message to your telegram when the price is higher or lower than
the set price.
All strategies must have a main function as the entrance.
*/
function main() {
//change symbol,will cover the default symbol which was set when start a bot.Currency is a strategy arguments
exchange.IO("currency", Currency)
var lastPushTime = 0 //the variable of last push timestamp.
while(true){ //run a infinite loop, which is the basic structure
//_C() function can retry the request automatically after failure. not necessary. var ticker = exchange.GetTicker() is ok.
var ticker = _C(exchange.GetTicker) // for information about GetTicker, check on https://fmz-docs.readthedocs.io/en/latest/code_Instruction/Market%20API.html#getticker
if(ticker.Last > UpPrice || ticker.Last < LowPrice){ //ticker.Last represents the last deal price
if(Date.now() - lastPushTime > 300*1000){ //only push once in 5 mins, Date.now() return ms.
lastPushTime = Date.now() //update lastPushTime
Log(Currency, 'Price is: ', ticker.Last, '@') //Log the price on the bot's page and sent the message. '@' in the end means push message
}
}
Log(Currency, 'Price is: ', ticker.Last) //just log the price
Sleep(Interval*1000) //check the last price again after Interval seconds
}
}
ロボットを実行
やっとボットを起動する時間です
その上Robot
ページをクリックAdd robot
訪問したりhttps://www.fmz.com/m/add-robot直接ボットを追加します
exchanges[0]
, exchanges[1]
ボットを管理する
その上Robot
このページでは,ボットが動いていることがわかります.
LogProfit()
好きな数になるボットページのボトの名前をクリックすると,詳細が表示されます:
この部分では,最も一般的に使用されているAPIをいくつか紹介します.FMZ API- わかった デモコードを起動するデバッグページ.
2.1 ログ
使用する: Log(msg)
パラメーター:文字列や数字記述:ロボットログページにメッセージをログインします.返信する:ないデモ
function main() {
var msg = 'msg string'
Log(msg)
Log('hello', 'world', 123)
Log("red color message", "#FF0000")
Log("push this message to telegram!@") // won't push on debug page
}
2.2 GetTicker
使用する: exchange.GetTicker()
パラメーター:ない記述:市場が動いてる返信する:
{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}
デモ
function main() {
var ticker = exchange.GetTicker()
Log(ticker)
Log('Last Price: ',ticker.Last, 'Bid Price: ', ticker.Buy)
}
2.3 深くなる
使用する: exchange.GetDepth()
パラメーター:ない記述:現在の市場オーダーブックを取得します.返信する:
{
"Info":null,
"Asks":[
{"Price":5866.38,"Amount":0.068644},
{"Price":5866.39,"Amount":0.263985},
{"Price":5866.73,"Amount":0.05},
{"Price":5866.77,"Amount":0.05},
{"Price":5867.01,"Amount":0.15},
{"Price":5875.89,"Amount":0.05},
......
]
"Bids":[
{"Price":5865.13,"Amount":0.001898},
{"Price":5865,"Amount":0.085575},
{"Price":5864.15,"Amount":0.013053},
{"Price":5863.65,"Amount":0.016727},
{"Price":5863.51,"Amount":0.128906},
{"Price":5863.15,"Amount":0.2}
......
],
"Time":1530241857399
}
デモ
function main() {
var depth = exchange.GetDepth()
Log(depth)
Log('Bid one: ', depth.Bids[0].Price, 'Ask one: ', depth.Asks[0].Price)
}
2.4 GetRecords を取得する
使用する: exchange.GetRecords()
, exchange.GetRecords(Period)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
期間 | グローバル・ヴァルブル | 違う | クライン |
可能なすべてのパラメータ:PERIOD_M1
1分前PERIOD_M5
5分後にはPERIOD_M15
15分後にはPERIOD_M30
半分後PERIOD_H1
1時間PERIOD_D1
1d記述:クライン/キャンドルスタイクバーを 現時点の市場に返信する:
[
{"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
{"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
{"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
......
]
デモ
//A useful JavaScript example using Records to get a close array:
function main(){
var close = []
var records = exchange.GetRecords(PERIOD_H1)
Log('total bars: ', records.length)
for(var i=0;i<records.length;i++){
close.push(records[i].Close)
}
return close
}
2.5 Getアカウント
使用する: exchange.GetAccount()
パラメーター:ない記述:アカウント情報を取得返信する:
{
"Stocks":0.38594816,// free base asset
"FrozenStocks":0, //locked base asset
"Balance":542.858308,//free quote asset
"FrozenBalance":0 //locked quote asset
"Info":{} //the raw data
}
デモ
//A useful JavaScript example of Log your account value for a certain trading pair:
function main(){
while(true){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
var price = ticker.Buy
var stocks = account.Stocks + account.FrozenStocks
var balance = account.Balance + account.FrozenBalance
var value = stocks*price + balance
Log('Account value is: ', value)
LogProfit(value)
Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
//when run in debug tool, add a break here
}
}
2.6 購入
使用する: exchange.Buy(Price, Amount)
, exchange.Buy(Price, Amount, Msg)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
価格 | 番号 | そうだ | 制限命令の購入価格 |
総額 | 番号 | そうだ | 制限注文の購入金額 |
Msg | 文字列 | 違う | ログページに追加メッセージを追加する |
記述:ボットのページに購入注文と購入ログを送信します返信する:順序ID を返します.null
そうでないならデモ
//A useful JavaScript example of Buy for buy certain amount of bitcoin at a certain price:
function main(){
while(true){
var ticker = exchange.GetTicker()
var price = ticker.Sell
if(price >= 7000){
exchange.Buy(price+5, 1, 'BTC-USDT')
}
Sleep(3000)//Sleep 3000ms
}
}
2.7 売る
使用する: exchange.Sell(Price, Amount)
, exchange.Sell(Price, Amount, Msg)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
価格 | 番号 | そうだ | 制限命令の販売価格 |
総額 | 番号 | そうだ | 制限オーダーの販売額 |
Msg | 文字列 | 違う | ログページに追加メッセージを追加する |
記述:販売注文と販売ログをボットページに送信します.返信する:順序ID を返します.null
そうでないならデモ
//A useful JavaScript example of Buy for buy certain amount of bitcoin at a certain price:
function main(){
while(true){
var ticker = exchange.GetTicker()
var price = ticker.Buy
if(price >= 7000){
var id = exchange.Sell(price-5, 1, 'BTC-USDT')
Log('OrderId: ', id)
}
Sleep(3000)
}
}
2.8 GetOrder を取得する
使用する: exchange.GetOrder(OrderId)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
オーダー | 番号 | そうだ | 注文 ID |
記述:注文の詳細を注文IDで取得します.返信する:
{
"Id":125723661,
"Amount":0.01,
"Price":7000,
"DealAmount":0,
"AvgPrice":0,
"Status":0, // 0:Not filled, 1:Filled, 2:Canceled
"Type":1,// 0:Buy, 1:Sell
"ContractType":"",//just for futures contract orders
"Info":{} //raw info from exchange
}
}
デモ
//A JavaScript example of using this API, which will buy until your account has 5 coins:
function main(){
while(true){
var amount = exchange.GetAccount().Stocks
var ticker = exchange.GetTicker()
var id = null
if(5-amount>0.01){
id = exchange.Buy(ticker.Sell, Math.min(10-amount,0.2))
}else{
Log('Job completed')
return //return the main function, bot will stop
}
Sleep(3000) //Sleep 3000ms
if(id){
var status = exchange.GetOrder(id).Status
if(Status == 0){
exchange.CancelOrder(id)
}
}
}
}
2.9 GetOrders を取得する
使用する: exchange.GetOrders()
パラメーター:ない記述:取引符号の注文をすべて開けなさい返信する:オープンオーダーのリスト,結果は同じ意味を持っていますGetOrder()
[
{
"Info":{},
"Id":16387538,
"Amount":1123,
"Price":0.00012826,
"DealAmount":0,
"AvgPrice":0,
"Status":0,
"Type":1,
"ContractType":""
}
]
デモ
//A JavaScript example of using this API, which will cancel all open orders for trading symbol:
fuction CancelAll(){
var orders = exchange.GetOrders()
for(var i=0;i<orders.length,i++){
exchange.CancelOrder(orders[[i].Id) // cancel order by orderID
}
}
function main(){
CancelAll()
while(true){
//do something
Sleep(10000)
}
}
2.10 注文をキャンセル
使用する: exchange.CancelOrder(OrderId)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
オーダー | 番号 | そうだ | 注文 ID |
記述:注文をキャンセルする返信する:bool タイプtrue
注文要求のキャンセルが成功しました.false
注文要求のキャンセルが失敗しました.
2.11 SetContractType について
使用する: exchange.SetContractType(ContractType)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
契約型 | 文字列 | そうだ | 契約型 |
記述:フューチャー取引の契約タイプを設定します.他のプライベートAPIを使用する前に最初に設定する必要があります.返信する:ないデモ
exchange.SetContractType("this_week") //OKEX future has “this_week”, “next_week”, “quarter” , "swap"
exchange.SetContractType("XBTUSD") //BitMEX future has "XBTUSD","XBTM19",etc
2.12 位置を把握する
使用する: exchange.GetPosition()
パラメーター:ない記述:現在の位置情報を取得します 期貨取引のみです返信する:ポジションのリストは,アカウントにポジションがない場合,空きリストを返します.デモ
// Note: GetPosition function obtains all positions.
function main(){
exchange.SetContractType("this_week") //for OKEX future
var position = exchange.GetPosition()
if(position.length>0){
Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type, "ContractType:", position[0].ContractType)
}
}
2.13 設定方向
使用する: exchange.SetDirection(Direction)
パラメーター:
名前 | タイプ | 必須 | 記述 |
---|---|---|---|
方向性 | 文字列 | そうだ | かもしれないbuy , closebuy , sell , closesell . |
記述:契約書取引のみの購入または販売オーダータイプを設定する.返信する:ないデモ
function main(){
exchange.SetContractType("this_week");
exchange.SetMarginLevel(5) // Set the leverage to 5 times
exchange.SetDirection("buy") // Set the order type to buy long
exchange.Buy(5000, 2) //buy long at the price 1000, quantity of 2
exchange.SetDirection("closebuy")
exchange.Sell(4999, 2) //close long position
}
2.14 他によく使われる機能:
FMZでそれらの機能についての詳細を確認してくださいAPI ドキュメント
名前 | 記述 | 例 |
---|---|---|
LogStatus |
ボットのステータスバーにメッセージやテーブルをログします.毎回リフレッシュします. | LogStatus('msg') |
_C |
再試行機能 | _C(exchange.GetRecords,PERIOD_H1) ,_C(exchange.GetTicker) |
_N |
位置関数 | _N(4001.512,2) ,_N(num,0) |
_G |
ロボットを再起動した後に保存できるグローバル辞書です | _G('initValue', 1000);_G('initValue') |
_D |
タイムスタンプを返します | _D() , _D(1478570053241) |
TA |
TA-Lib インディケーター ライブラリMACD , EMA , KDJ そういった... |
TA.MACD(records) |
Math |
数学機能のサポート,チェックhttps://mathjs.org/ | Math.min(1,2) , Math.sqrt(2) |
学習の戦略はたくさんありますhttps://www.fmz.com/square/s:tag:Study/1初心者にとっては簡単です
これはシンプルで強力な戦略で,実際のBTCスポット市場で数百倍稼ぎました.これは高い取引手数料を持つ取引所で実行できません.
var floatAmountBuy = 20
var floatAmountSell = 20
var diffPrice = 3
var Interval = 3000
function CancelPendingOrders() {
var orders = _C(exchange.GetOrders);
for (var j = 0; j < orders.length; j++) {
exchange.CancelOrder(orders[j].Id, orders[j])
}
}
function GetPrice(depth) {
var price = {buy:0, sell:0}
var askAmount = 0
var bidAmount = 0
for(var i=0; i<depth.Bids.length; i++){
askAmount += depth.Asks[i].Amount
bidAmount += depth.Bids[i].Amount
if(askAmount >= floatAmountBuy && !price.buy){
price.buy = depth.Asks[i].Price
}
if(bidAmount >= floatAmountSell && !price.sell){
price.sell = depth.Bids[i].Price
}
}
if(!price.buy || !price.sell){
price = {buy:depth.Asks[depth.Asks.length-1].Price, sell:depth.Bids[depth.Bids.length-1].Price}
}
return price
}
function onTick() {
var price = GetPrice(_C(exchange.GetDepth))
var buyPrice = price.buy + 0.01
var sellPrice = price.sell - 0.01
if ((sellPrice - buyPrice) <= diffPrice){
buyPrice -= 10
sellPrice += 10
}
CancelPendingOrders()
var account = _C(exchange.GetAccount)
var amountBuy = _N((account.Balance / buyPrice-0.01), 2)
var amountSell = _N((account.Stocks), 2)
if (amountSell > 0.02) {
exchange.Sell(sellPrice, amountSell)
}
if (amountBuy > 0.02) {
exchange.Buy(buyPrice, amountBuy)
}
}
function main() {
while (true) {
onTick()
Sleep(Interval)
}
}
クラシックな脱出戦略だhttps://www.fmz.com/strategy/103247コンフィギュレーション ソースコードから機能交換や図を描く方法を学ぶことができます
var ChartCfg = {
__isStock: true,
title: {
text: 'Dual Thrust Up-Down Track'
},
yAxis: {
plotLines: [{value: 0,
color: 'red',
width: 2,
label: {
text: 'Up Track',
align: 'center'}
},
{value: 0,
color: 'green',
width: 2,
label: {
text: 'Down Track',
align: 'center'},
}
]
},
series: [{type: 'candlestick',
name: 'current cycle',
id: 'primary',
data: []
},
{type: 'flags',
onSeries: 'primary',
data: [],
}
]
};
var STATE_IDLE = 0;
var STATE_LONG = 1;
var STATE_SHORT = 2;
var State = STATE_IDLE;
var LastBarTime = 0;
var UpTrack = 0;
var BottomTrack = 0;
var chart = null;
var InitAccount = null;
var LastAccount = null;
var Counter = {
w: 0,
l: 0
};
function GetPosition(posType) {
var positions = exchange.GetPosition();
for (var i = 0; i < positions.length; i++) {
if (positions[i].Type === posType) {
return [positions[i].Price, positions[i].Amount];
}
}
return [0, 0];
}
function CancelPendingOrders() {
while (true) {
var orders = exchange.GetOrders();
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
Sleep(Interval);
}
if (orders.length === 0) {
break;
}
}
}
function Trade(currentState, nextState) {
var pfn = nextState === STATE_LONG ? exchange.Buy : exchange.Sell;
if (currentState !== STATE_IDLE) {
exchange.SetDirection(currentState === STATE_LONG ? "closebuy" : "closesell");
while (true) {
var amount = GetPosition(currentState === STATE_LONG ? PD_LONG : PD_SHORT)[1];
if (amount === 0) {
break;
}
// pfn(amount);
pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount);
Sleep(Interval);
CancelPendingOrders();
}
var account = exchange.GetAccount();
if (account.Stocks > LastAccount.Stocks) {
Counter.w++;
} else {
Counter.l++;
}
LogProfit(_N(account.Stocks - InitAccount.Stocks), "Profit rate:", _N((account.Stocks - InitAccount.Stocks) * 100 / InitAccount.Stocks) + '%');
LastAccount = account;
}
exchange.SetDirection(nextState === STATE_LONG ? "buy" : "sell");
while (true) {
var pos = GetPosition(nextState === STATE_LONG ? PD_LONG : PD_SHORT);
if (pos[1] >= AmountOP) {
Log("Average Price", pos[0], "amount:", pos[1]);
break;
}
// pfn(AmountOP-pos[1]);
pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]);
Sleep(Interval);
CancelPendingOrders();
}
}
function onTick(exchange) {
var records = exchange.GetRecords();
if (!records || records.length <= NPeriod) {
return;
}
var Bar = records[records.length - 1];
if (LastBarTime !== Bar.Time) {
var HH = TA.Highest(records, NPeriod, 'High');
var HC = TA.Highest(records, NPeriod, 'Close');
var LL = TA.Lowest(records, NPeriod, 'Low');
var LC = TA.Lowest(records, NPeriod, 'Close');
var Range = Math.max(HH - LC, HC - LL);
UpTrack = _N(Bar.Open + (Ks * Range));
DownTrack = _N(Bar.Open - (Kx * Range));
if (LastBarTime > 0) {
var PreBar = records[records.length - 2];
chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1);
} else {
for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) {
var b = records[records.length - i];
chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]);
}
}
chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]);
ChartCfg.yAxis.plotLines[0].value = UpTrack;
ChartCfg.yAxis.plotLines[1].value = DownTrack;
ChartCfg.subtitle = {
text: 'Up Track: ' + UpTrack + ' Down Track: ' + DownTrack
};
chart.update(ChartCfg);
chart.reset(PeriodShow);
LastBarTime = Bar.Time;
} else {
chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1);
}
LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date());
var msg;
if (State === STATE_IDLE || State === STATE_SHORT) {
if (Bar.Close >= UpTrack) {
msg = 'Long Price: ' + Bar.Close + ' Up Track:' + UpTrack;
Log(msg);
Trade(State, STATE_LONG);
State = STATE_LONG;
chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: 'Long', text: msg});
}
}
if (State === STATE_IDLE || State === STATE_LONG) {
if (Bar.Close <= DownTrack) {
msg = 'Short Price: ' + Bar.Close + ' Down Track:' + DownTrack;
Log(msg);
Trade(State, STATE_SHORT);
chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: 'Short', text: msg});
State = STATE_SHORT;
}
}
}
function onexit() {
var pos = exchange.GetPosition();
if (pos.length > 0) {
Log("Warning, has positions when exiting", pos);
}
}
function main() {
if (exchange.GetName() !== 'Futures_OKCoin') {
throw "Only support OKEX features";
}
exchange.SetRate(1);
exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]);
exchange.SetMarginLevel([10, 20][MarginLevelIdx]);
if (exchange.GetPosition().length > 0) {
throw "Can't have Positions when start.";}
CancelPendingOrders();
InitAccount = LastAccount = exchange.GetAccount();
LoopInterval = Math.min(1, LoopInterval);
Log('Exchange Name:', exchange.GetName(), InitAccount);
LogStatus("Ready...");
LogProfitReset();
chart = Chart(ChartCfg);
chart.reset();
LoopInterval = Math.max(LoopInterval, 1);
while (true) {
onTick(exchange);
Sleep(LoopInterval * 1000);
}
}
小草この記事の更新を続けてください,任意の質問を自由に