利益集約者戦略分析 (2)

作者: リン・ハーンニナバダス作成日:2022年4月26日 15:57:02 更新日:2022年4月26日 15:57:53

利益集約者戦略分析 (2)

続きを進めよう前回の内容説明するために

3つ目の追加機能:

    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log("start to balance", self.p)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
            }
        } else if (self.p > 0.52) {
            Log("start to balance", self.p)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

設計者がLeeksReaper()対象を構成しています.balanceAccount()対象に追加された機能は,アカウント資産情報を更新するために使用されます.self.account属性を構築する.accountオブジェクトの返金値を定期的に計算して印刷します.次に,最新の口座資産情報に基づいて,スポット通貨シンボル (スポットポジションバランス) の残高比率を計算し,オフセットの値が起動すると,シンボル (ポジション) をバランス状態に戻すために小さなオーダーが閉鎖されます.取引を実行するために一定期間待って,すべての未完了オーダーをキャンセルし,次のラウンドで機能を実行します.残高が再び検出され,対応した処理が行われます.

この関数文のコードを文ごとに見てみましょう. まず第一の主張はvar account = exchange.GetAccount()ローカル変数を宣言する.account呼び出すexchange.GetAccount()FMZ API インターフェイスで,現在の口座の最新のデータを取得し,変数に割り当てaccount変数を判断する.account変数の値がnull(タイムアウト,ネットワーク,プラットフォームインターフェース例外など) のような変数を取得できなければ,直接 (対応する) 返します.if (!account ){...}このページです)

声明self.account = accountローカル変数を割り当てることです.account属性に対してaccount建設されたオブジェクトの最新アカウント情報を記録する.

声明var now = new Date().getTime()ローカル変数を宣言する.now呼び出しますgetTime()JavaScript言語の時間&日付オブジェクトの関数で,現在のタイムスタンプを返し,変数にタイムスタンプを割り当てますnow.

コード:if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}現在のタイムスタンプと最後に記録されたタイムスタンプの違いを判断します.値がパラメータを超えると,CalcNetInterval * 1000超えたことを意味します.CalcNetInterval * 1000ミリ秒 (CalcNetInterval利益を計算する際に市場での1購入価格を使用する必要があるため,条件は,条件に限定されています.self.orderBook.Bids.length > 0(深度データ,購入注文リストでレベル情報として有効である必要があります).

命令の条件 if が起動すると実行します.self.preCalc = nowタイムスタンプ変数を更新するself.preCalc最新の印刷利益の現在のタイムスタンプnowここで,利益統計は,純価値計算法を用いて,コードは:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)),つまり,通貨を現在の買い1価格に従って資産 (引換通貨) に変換し,それを口座の資産金額に追加し,宣言されたローカル変数に割り当てますnet現在の総純価値が,最後に記録された総純価値と一致するかどうかを決定する.

            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }

矛盾している場合,つまりnet != self.preNettrue で,属性を更新します.self.preNet純価値を記録するnetそして,総純価値のデータを印刷します.netFMZ 量子取引プラットフォームのボットの利益曲線グラフに (あなたはLogProfitFMZ API ドキュメンテーションに記載されている)

返信の定期的な印刷が起動されていない場合,次のプロセスを継続します:記録account.Stocks(口座内の現有通貨シンボル) とaccount.Balance(口座内の現有資産)self.btcそしてself.cny計算し,それを割り当てます.self.p.

self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)

計算します. 口座の総純価値に 現金価値の何パーセントを 計算します.

通貨 (ポジション) バランスが起動する時の判断は? バッファーを超えると,残高を実行します. つまり,self.p < 0.48価格が0.01上昇するたびに3つの小注文をします.同様に,通貨残高が0.01上昇するたびに,通貨残高が0.01上昇します.self.p > 0.52市場で販売 1 価格の小さな注文を待ち. 最後に,パラメータ設定に従って,一定の期間を待つ.Sleep(BalanceTimeout)オーダーをキャンセルします

        var orders = exchange.GetOrders()                  # obtain all the current pending orders, and save them in the variable orders"
        if (orders) {                                      # if the variable "orders", which obtains all the current pending orders, is not null
            for (var i = 0; i < orders.length; i++) {      # use the loop to traverse "orders", and cancel the orders one by one 
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)     # call "exchange.CancelOrder", and cancel orders by "orders[i].Id"
                }
            }
        }

第4の追加機能:

戦略の核心部分です ハイライトself.poll = function() {...}戦略全体の主要な論理です. 我々はまた,前記事でそれについて話しました.main( )実行を開始します.whileループの定義はvar reaper = LeeksReaper()利益収集物体を構築し,それからReaper.poll()周期的に呼びますmain() function.

についてself.poll機能が実行を開始し,ループごとに準備をします.self.numTick++数を増やしますself.updateTrades()市場における最近の取引記録を更新し,関連するデータを使用を計算する.self.updateOrderBook()市場 (注文簿) のデータを更新し,関連するデータを計算する.self.balanceAccount()通貨 (ポジション) の残高をチェックします.

        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct   # calculate the burst price 
        var bull = false             # declare the variable marked by the bull market; the initial value is false
        var bear = false             # declare the variable marked by the bear market; the initial value is false
        var tradeAmount = 0          # declare the variable of trading amount; the initial value is 0

次に,現在の短期市場が 牛なのか熊なのかを判断する必要があります.

        if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
            )) {
            bull = true
            tradeAmount = self.cny / self.bidPrice * 0.99
        } else if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
            )) {
            bear = true
            tradeAmount = self.btc
        }

覚えてる?self.updateOrderBook()時間の連続を構成するために 重み平均のアルゴリズムを使用しました.pricesこのコードは3つの新しい関数を使用します._.min, _.max, slice簡単に理解できます

  • _.min: パラメータ配列の最小値を求めることです.

  • _.max: パラメータ配列の最大値を見つけることです.

  • slice: この関数はJavaScript配列オブジェクトのメンバー関数です. 配列の一部をインデックスに従って遮断して返します. たとえば:

    function main() {
        // index     .. -8 -7 -6 -5 -4 -3 -2 -1
        var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
        Log(arr.slice(-5, -1))    // it will intercept several elements from 4 to 1, and return a new array: [4,3,2,1]
    }
    

牛市場か熊市場かを判断する条件は次のとおりです

  • self.numTick > 2つまり,価格爆発が新たな検知ラウンドで起こると,少なくとも3回の検知ラウンド後に引き起こす必要があります.そして,最初から引き起こすのを避ける必要があります.
  • 価格シリーズの最後のデータself.pricesつまり,最新のデータと最大または最低価格の差です.self.prices前の範囲で配列を突破する必要があります.burstPrice .

すべての条件が正しい場合,マークbullまたはbeartrue変数に値を代入します.tradeAmount交換を計画する

このパラメータは,BurstThresholdVol基準として,self.vol更新され,前回のデータで計算されました.self.updateTrades()取引の強度 (計画された取引量を減らす) を決定する.

        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol   // reduce the planned trading volume, and reduce it to the previous volume multiplied by "self.vol / BurstThresholdVol" 
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8      // reduced to 80% of the plan 
        }
        
        if (self.numTick < 10) {    // reduced to 80% of the plan
            tradeAmount *= 0.8
        }

次に,取引信号と取引量が要件を満たしているか判断します.

        if ((!bull && !bear) || tradeAmount < MinStock) {   # if it is not a bull market nor a bear market, or the planned trading volume "tradeAmount" is less than the minimum trading volume "MinStock" set by the parameter, the "poll" function returns directly without any trading operation
            return
        }

上記の判決の後,執行するvar tradePrice = bull ? self.bidPrice : self.askPrice熊市場か牛市場かによって,取引価格を設定し,対応する配達注文価格に値を割り当てます.

最後に,入力してくださいwhileループの唯一の停止とブレークアウト条件はtradeAmount >= MinStockつまり,計画された取引量は最低取引量より少ない. ループでは,現在の牛市場状態または熊市場状態に応じて,注文を実行します. そして変数に注文IDを記録します.orderId処刑するSleep(200)ループは,各ラウンドで注文をすると200ミリ秒間待っています.orderIdtrue である場合 (order ID が返されず,条件が起動しない場合). condition が true である場合,order ID を取得し,self.tradeOrderId.

変数を宣言するorder初期値で注文データを保存するnull. その後,ループを使用して,IDで注文データを取得し,注文が待ち受けている注文状態にあるかどうかを決定します.

                var order = null           // declare a variable to save the order data 
                while (true) {             // a while loop 
                    order = exchange.GetOrder(orderId)    // call "GetOrder" to query the order data with the ID of  orderId
                    if (order) {                          // if the order data is queried,and the query fails, the order is null, and "if" will not be triggered  
                        if (order.Status == ORDER_STATE_PENDING) {   // judge whether the current order status is pending order
                            exchange.CancelOrder(orderId)            // if the current order status is pending order, cancel the order 
                            Sleep(200)
                        } else {                                     // if not, execute "break" to break out of the while loop 
                            break
                        }
                    }
                }

次に次の手順を実行します.

                self.tradeOrderId = 0              // reset "self.tradeOrderId"
                tradeAmount -= order.DealAmount    // update "tradeAmount", and subtract the executed amount of the orders in the delivery order 
                tradeAmount *= 0.9                 // reduce the intensity of ordering  
                if (order.Status == ORDER_STATE_CANCELED) {     // if the order is canceled 
                    self.updateOrderBook()                      // update the data, including the order book data
                    while (bull && self.bidPrice - tradePrice > 0.1) {   // in a bull market, if the updated bid price exceeds the current trading price by 0.1, reduce the trading intensity, and slightly adjust the trading price 
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {  // in a bear market, if the updated ask price exceeds the current trading price by 0.1, reduce the trading intensity, and slightly adjust the trading price 
                        tradePrice -= 0.1
                    }
                }

プログラムフローがwhile (tradeAmount >= MinStock) {...}ループは,価格爆発取引の実行が完了することを意味します. 実行するself.numTick = 0つまり,リセットself.numTick0 にする

建設者の最後の実行LeeksReaper()を返します.self対象となる場合です.var reaper = LeeksReaper(),オブジェクトは戻されます.reaper.

分析したところ,LeeksReaper()このコンストラクタは,このプロフィットハーベスターオブジェクト,オブジェクトの様々な方法,および主要な論理関数の実行プロセスを構築します. この記事を読んだ後,あなたは高周波戦略アルゴリズムプロセスについてより明確に理解できると思います.


もっと