मुनाफा कटाई करने वाली रणनीति का विश्लेषण (2)

लेखक:निनाबादास, बनाया गयाः 2022-04-26 15:57:02, अद्यतन किया गयाः 2022-04-26 15:57:53

मुनाफा कटाई करने वाली रणनीति का विश्लेषण (2)

चलिए आगे बढ़ते हैंपिछली बार की सामग्रीसमझाने के लिए।

तीसरा अतिरिक्त कार्यः

    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 एपीआई इंटरफ़ेस में समारोह, चालू खाता के नवीनतम डेटा प्राप्त करें और चर के लिए यह असाइनaccount. फिर, चर का न्याय करेंaccount; यदि चर मान है:null(जो तब होगा जब यह चर प्राप्त करने में विफल रहता है, जैसे कि टाइमआउट, नेटवर्क, प्लेटफॉर्म इंटरफ़ेस अपवाद, आदि), यह सीधे वापस आ जाएगा (अनुरूप)if (!account ){...}यहाँ) ।

बयानself.account = accountस्थानीय चर असाइन करने के लिए हैaccountविशेषता के लिएaccountनिर्मित वस्तु में नवीनतम खाता जानकारी दर्ज करने के लिए निर्मित वस्तु का।

बयानvar now = new Date().getTime()स्थानीय चर घोषित करता हैnow, और बुलाता हैgetTime()जावास्क्रिप्ट भाषा के समय और दिनांक ऑब्जेक्ट का कार्य वर्तमान टाइमस्टैम्प वापस करने के लिए, और चर को टाइमस्टैम्प असाइन करने के लिए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.preNetसच है, विशेषता अद्यतन करेंself.preNetजो शुद्ध मूल्य को रिकॉर्ड करता हैnetचर. फिर, कुल शुद्ध मूल्य डेटा प्रिंटnetएफएमजेड क्वांट ट्रेडिंग प्लेटफॉर्म बॉट के लाभ वक्र चार्ट पर (आप क्वेरी कर सकते हैंLogProfitएफएमजेड एपीआई प्रलेखन में कार्य) ।

यदि रिटर्न की नियमित छपाई ट्रिगर नहीं की जाती है, तो निम्नलिखित प्रक्रिया जारी रखेंः रिकॉर्ड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)

एल्गोरिथ्म भी बहुत सरल है, जो गणना करने के लिए है कि खाते के कुल शुद्ध मूल्य में वर्तमान मुद्रा मूल्य का कितना प्रतिशत है।

तो आप कैसे न्याय करते हैं जब मुद्रा (स्थिति) संतुलन ट्रिगर किया जाता है? यहाँ डेवलपर एक बफर के रूप में 50% ऊपर और नीचे 2 प्रतिशत अंक का उपयोग करता है; यदि यह बफर से अधिक है, तो शेष निष्पादित करें, अर्थात जबself.p < 0.48, मुद्रा संतुलन ऑफसेट ट्रिगर किया जाता है. यदि आपको लगता है कि मुद्रा राशि कम है, हर बार कीमत 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"
                }
            }
        }

चौथा जोड़ा गया कार्यः

यहाँ रणनीति का मुख्य हिस्सा आता है, हाइलाइट।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इस कोड का टुकड़ा तीन नए कार्यों का उपयोग करता है, अर्थात्_.min, _.max, slice, जो समझने में भी बहुत आसान हैं।

  • _.min: फंक्शन पैरामीटर सरणी में न्यूनतम खोजने के लिए है.

  • _.max: फंक्शन पैरामीटर सरणी में अधिकतम खोजने के लिए है.

  • slice: यह फ़ंक्शन जावास्क्रिप्ट सरणी ऑब्जेक्ट का सदस्य फ़ंक्शन है. यह सूचकांक के अनुसार सरणी के एक हिस्से को काटने और वापस करने के लिए है. उदाहरण के लिएः

    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सच होना चाहिए, यानी यदि मूल्य विस्फोट का पता लगाने के एक नए दौर में होता है, तो इसे पता लगाने के कम से कम तीन दौरों के बाद ट्रिगर किया जाना चाहिए, और शुरुआत में ट्रिगर से बचना चाहिए।
  • मूल्य श्रृंखला के अंतिम आंकड़ेself.prices, यानी नवीनतम आंकड़ों और अधिकतम या न्यूनतम मूल्य के बीच का अंतरself.pricesपिछले सीमा में सरणी के माध्यम से तोड़ना चाहिएburstPrice .

यदि सभी शर्तें सही हैं, चिह्नित करेंbullयाbearजैसा किtrue, और चर के लिए एक मूल्य असाइन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, यानी नियोजित व्यापारिक मात्रा न्यूनतम व्यापारिक मात्रा से कम है। लूप में, वर्तमान बैल बाजार की स्थिति या भालू बाजार की स्थिति के अनुसार, आदेश निष्पादित. और चर में आदेश आईडी रिकॉर्डorderIdनिष्पादित करेंSleep(200)प्रत्येक दौर में आदेश देने के बाद 200 मिलीसेकंड तक प्रतीक्षा करने के लिए।orderIdसच है (यदि आदेश विफल रहता है, आदेश आईडी वापस नहीं किया जाएगा, और if शर्त ट्रिगर नहीं किया जाएगा). यदि शर्त सच है, आदेश आईडी प्राप्त करें और इसे असाइन करने के लिएself.tradeOrderId.

चर घोषित करेंorderके प्रारंभिक मूल्य के साथ आदेश डेटा स्टोर करने के लिएnull. फिर, आईडी के साथ ऑर्डर डेटा प्राप्त करने के लिए एक लूप का उपयोग करें, और निर्धारित करें कि क्या ऑर्डर लंबित ऑर्डर स्थिति में है; यदि यह लंबित ऑर्डर स्थिति में है, तो आईडी के साथ ऑर्डर रद्द करें; यदि यह लंबित ऑर्डर स्थिति में नहीं है, तो यह डिटेक्शन लूप से बाहर निकल जाएगा.

                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()constructor इस लाभ कटाई ऑब्जेक्ट का निर्माण करता है, ऑब्जेक्ट के विभिन्न तरीकों, और मुख्य तर्क कार्यों के निष्पादन की प्रक्रिया. लेख पढ़ने के बाद, मुझे लगता है कि आप उच्च आवृत्ति रणनीति एल्गोरिथ्म प्रक्रिया की स्पष्ट समझ होगा.


अधिक