चलिए आगे बढ़ते हैंपिछली बार की सामग्रीसमझाने के लिए।
तीसरा अतिरिक्त कार्यः
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
(गहन डेटा, जो खरीद आदेश सूची में स्तर जानकारी के रूप में मान्य होना चाहिए) ।
जब कथन 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
सच है (यदि आदेश विफल रहता है, आदेश आईडी वापस नहीं किया जाएगा, और 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.numTick
0 तक।
निर्माता का अंतिम निष्पादनLeeksReaper()
लौटाता हैself
वस्तु, अर्थात्, जबvar reaper = LeeksReaper()
, वस्तु वापस आ जाती हैreaper
.
अब तक हमने विश्लेषण किया है कि कैसेLeeksReaper()
constructor इस लाभ कटाई ऑब्जेक्ट का निर्माण करता है, ऑब्जेक्ट के विभिन्न तरीकों, और मुख्य तर्क कार्यों के निष्पादन की प्रक्रिया. लेख पढ़ने के बाद, मुझे लगता है कि आप उच्च आवृत्ति रणनीति एल्गोरिथ्म प्रक्रिया की स्पष्ट समझ होगा.