資源の読み込みに... 荷物...

FMZ 初心者チュートリアル

作者: リン・ハーン小草作成日:2019-04-09 11:29:07 更新日:2024-02-06 17:35:38

[TOC]

img

1.FMZプラットフォームから開始

これは初心者のための基本的な説明です. APIのドキュメントの完全なバージョンについては,FMZ APIこのチュートリアルには含まれていない多くのスペックがあります.

FMZの仕組みを知って,基本的な戦略を書けるようになるでしょう.

1.1 FMZプラットフォームについて

FMZプラットフォームとは?

FMZは,多くのビットコイン/eth/altcoin取引市場をサポートする仮想通貨トレーダーの自動取引プラットフォームです.

FMZは何ができるの?

オープンソースコードをたくさん含む私たちの戦略スクエアからあなたのボットを書く方法を学ぶことができます. あなたの戦略のコードを他の人と共有し,いつでも専門家の助けを求め,多くの取引所であなたの戦略を実行,コンピュータまたは携帯電話でウェブサイトであなたのボットを制御します.グループ簡単に言うと,FMZは自動取引をしたい人のための完璧なプラットフォームです.

FMZはどの仮想通貨取引所をサポートしていますか?

FMZは,ほぼすべての取引所をサポートしています.Binance, Bitfinex, Bitstamp, OKEX, Huobi, Poloniex取引もできます.OKEXそしてBitMEXサポートリストをチェックしてくださいAPIすべての取引所で変更なしに実行するだけです.

FMZ はどのプログラミング言語をサポートしていますか?

FMZ は JavaScript,Python,C++ (JavaScript と Python が推奨されます) をサポートし,戦略をコードします.完成した言語のサポートを利用して (カスタム言語は1つのプラットフォームにのみ使用できるわけではありません),プログラミングスキルを向上させ,戦略を書くことを学ぶことができます.

API キーが安全ですか?

暗号化後,APIキーが保存されます.

  • 鍵を追加するときに,あなたは FMZ パスワードを入力する必要があります. Web ブラウザは,あなたの API キーを暗号化し,使用して FMZ サーバに暗号化された鍵を転送します.https.
  • FMZ パスワードを入力する必要があります サーバーやコンピュータでドッカーを実行するときに
  • FMZ は bot を起動するときに https を使って暗号化された鍵をドッカーに送ります.ドッカーが暗号を解読して鍵を取得します.
  • FMZ は パスワードを保存しないので API キーも知らない.
  • 自分のパスワードとドッカーサーバーを保護する必要があります.第二の認証ログイン FMZ を使用するのが最善です.

現在の機能リスト:

  • 1.クロスプラットフォーム,すべての主要な暗号通貨取引所のサポート
  • 2.シミュレーション交換のサポート. https://wex.app/
  • 3.有効なバックテストシミュレーションシステムを備えています.
  • 4.メールを送信し,メッセージをテレグラムアカウントに送信するサポート.
  • 5.携帯電話でアクセスできるウェブベースの制御
  • 6.Python\C++\JavaScriptプログラミングをサポートする.
  • 7.コストは非常に低く,1時間あたり0.125 RMB,約0.018ドルです.
  • 8.NoAPI-KEY またはパスワードはサーバーに保存されています. FMZはセキュリティ上の問題なく4年以上にわたって実行されています.

1.2 FMZプラットフォームの利用を迅速に開始する

ロボットを実行するには 戦略が必要です 交換を追加し ドーカーを最初に展開します ドーカーとは 自身のコンピュータやサーバーで実行されている 戦略の実行者です

主ページの簡単な見方

img

  • 1.メインのコントロールページ
  • 2.すべてのボットを管理する (スタート,ストップ,削除,オープンなど)
  • 3.すべての戦略を管理する
  • 4.ドーカーを展開し管理する
  • 5.新しい取引所を追加する
  • 6.あなたが追加した取引所で手動取引
  • 7. 請求書を支払う
  • 8.質問はこちらから
  • 9.FMZのシミュレーション交換
  • 10.ボットを起動せずにコードのブロックを実行できるデバッグツール.
  • 11.あらゆる種類のメッセージ
  • 12.オープンソースと充電戦略がリストされている戦略のスクエア
  • 13.ライブ・ロボットのリスト
  • 14. 関連問題について議論するために投稿できるフォーラム.
  • 15.誰かにコードを書くように頼むか,他の人のためにこのサービスを提供する.
  • 16. 取引所や代理店向け製品
  • 17.APIドキュメント
  • 18.有用なツール,自分で確認してください.
  • 19.あなたの口座情報

交換を追加する

追加するhttps://www.fmz.com/m/add-platformまたはクリックPlatformラベル アクセスキーと秘密キーは暗号通貨取引所で適用できます. API-KEYは取引に使用され,取引所からのプライベート情報を取得します. 私たちはサーバーにAPI-KEYやパスワードを保存しません. FMZで登録できますシミュレーション交換テストのために追加します

img

ドーカーを展開する

FMZはボットを実行しません. 実行者としてドッカーを自分で展開する必要があります. 私たちのサービスはボットを実行することに参加しないため,より柔軟で安全です. 公開ドッカーも提供していますが,テストのためにのみ使用する必要があります.

Windowsでは,非常に簡単です. 指示に従ってくださいhttps://www.fmz.com/m/add-node

img

Linux の場合は,docker を自動的に展開する VPS を当社のウェブサイトでレンタルできます.自分の Linux サーバーに展開するための手順は以下です (推奨):

  • 1.AmazonやGoogleからクラウドサーバー (VPS) を購入すれば,最低で安価な設定で十分です.
  • 2.サーバーにログインし,サーバープロバイダの指示に従って,Googleで検索してください.
  • 3.システムバージョンに合うドーカーを選択します.ほとんどの場合,それは64ビットです.
  • 4 セントで走るwget www.fmz.com/dist/robot_linux_amd64.tar.gz命令が見つかりませんでした.yum install wget -y.
  • 5.Run tar -xzvf robot_linux_amd64.tar.gz解き放つ
  • 6.Run ./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.
  • SHH クライアントを閉じると,ドーカーが停止します. 押すctrl + Cドーカーを停止する
  • 8.Run nohup ./robot -s node.fmz.com/xxxxx -p yourFMZpassword &このステップは,また,実行することができますScreen command.
  • 9. チェックhttps://www.fmz.com/m/nodesドーカーがそこに配置されています.

戦略を書いて

編集ページの使い方を示すために簡単なJavaScript戦略をデモとして使用します. 戦略は,編集ページからコピーすることができます.https://www.fmz.com/strategy/125482- わかった このチュートリアルでは JavaScript の使い方を説明しません. ネットでたくさんのチュートリアルがあります.

img

  • 1.コードを編集する
  • 2.バックテストでは,この部分を中間チュートリアルでカバーします.
  • このデモでは JavaScript が使われました
  • 4.タイトル,は,中国語と英語のタイトルを分割し,どのタイトルが表示されるかは,FMZのウェブサイトの言語によって決定されます.
  • 5.戦略の種類,デフォルトは一般的です
  • 6.戦略のカテゴリー.戦略が多くなった場合,さまざまなカテゴリーに分けることができます.
  • 7.私たちのウェブサイトではなく,自分のIDEからコードをリモートで編集
  • 8.APIドキュメントへのリンク
  • 9.戦略の注記 (あなた自身で確認してください).
  • 10.戦略の説明.Squareで戦略をシェアしたり販売したりすると,他のユーザーがその説明を見ることができます.
  • 戦略のマニュアルは,誰かがあなたの戦略を買ったときにのみ見ることができます.
  • 12.コードを保存するか,Ctrl+S編集モードに
  • 13. バックテストの設定をコードに保存します.
  • 14.Download戦略ファイル
  • 15.すべてのパラメータを保持しながら戦略を輸出・輸入
  • 16.フォントのサイズを変更し,テーマを編集する
  • 17.コードを自動的にフォーマットする
  • 18. VIM モードで編集する.

携帯にメッセージを送信するには,電報をアカウントに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直接ボットを追加しますimg

  • 1.ボットの名前
  • 2.このボットを実行するドーカー
  • 3.実行する戦略
  • 4.パラメータ,デフォルト値は変更できます.
  • 5.交換を使用するときにデフォルトのKline期間.GetRecords()
  • 6.Exchange
  • 7.Tradingシンボルまたはペア
  • 8.必要な取引シンボルがリストに載っていない場合は,自分で入力してください.
  • 9.Click交換を加えるために
  • 10.既に追加された取引所.複数の取引所が1ボットで追加され,exchanges[0], exchanges[1]
  • 11.Clickロボットを動かして!

ボットを管理する

その上Robotこのページでは,ボットが動いていることがわかります.img

  • 1.ボットの名前,ボットページへ ここをクリックします.
  • 2.ボットが実行する戦略,ここをクリックして戦略ページへ.
  • 3.ボットの状態. 動作,停止,エラーなどがあります.
  • 4.ボットの利益LogProfit()好きな数になる
  • 5.作成日,最後の通信時間に変更できます.
  • 6.ボットを監視する. FMZはボットが誤って停止されたときにメッセージを送信します.
  • 7. ロボットを停止する.

ボットページのボトの名前をクリックすると,詳細が表示されます:img

2.最もよく使われるAPIの導入

この部分では,最も一般的に使用されている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) パラメーター:

名前 タイプ 必須 記述
期間 グローバル・ヴァルブル 違う クラインのサイクル,オプションパラメータ,ロボット起動時にデフォルトのKラインサイクルが設定されます.

可能なすべてのパラメータ:PERIOD_M11分前PERIOD_M55分後にはPERIOD_M1515分後にはPERIOD_M30半分後PERIOD_H11時間PERIOD_D11d記述:クライン/キャンドルスタイクバーを 現時点の市場に返信する:

[
    {"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)

3.2つの完全な戦略

学習の戦略はたくさんありますhttps://www.fmz.com/square/s:tag:Study/1初心者にとっては簡単です

3.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)
    }
}

3.2 ダブルスロープ OKEX機能

クラシックな脱出戦略だ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);
    }
}


もっと

小草この記事の更新を続けてください,任意の質問を自由に