تیسرا اضافی فنکشن:
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()
موجودہ ٹائم اسٹیمپ واپس کرنے اور متغیر کو ٹائم اسٹیمپ تفویض کرنے کے لئے جاوا اسکرپٹ زبان کے وقت اور تاریخ آبجیکٹ کی تقریب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
FMZ 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)
الگورتھم بھی بہت سادہ ہے، جس کا حساب لگانا ہے کہ اکاؤنٹ کی کل خالص قیمت میں موجودہ کرنسی کی قیمت کے کتنے فیصد ہیں۔
تو آپ کس طرح فیصلہ کرتے ہیں جب کرنسی (پوزشن) بیلنس ٹرگر ہوتا ہے؟
یہاں ڈویلپر 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()
کہا جاتا ہے cyclically میں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
، یعنی منصوبہ بند تجارتی حجم کم سے کم تجارتی حجم سے کم ہے.
لوپ میں، موجودہ بیل مارکیٹ کی حالت یا ریچھ مارکیٹ کی حالت کے مطابق، حکم کو انجام دیں. اور متغیر میں آرڈر ID ریکارڈorderId
عملدرآمدSleep(200)
ہر راؤنڈ میں آرڈر دینے کے بعد 200 ملی سیکنڈ تک انتظار کرنا۔ اس کے بعد لوپ فیصلہ کرتا ہے کہ آیاorderId
درست ہے (اگر آرڈر ناکام ہوجاتا ہے تو ، آرڈر ID واپس نہیں کیا جائے گا ، اور 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()
تعمیر کار اس منافع کٹائی کرنے والے آبجیکٹ ، آبجیکٹ کے مختلف طریقوں اور اہم منطقی افعال کے عمل کو تشکیل دیتا ہے۔ مضمون پڑھنے کے بعد ، مجھے لگتا ہے کہ آپ کو اعلی تعدد کی حکمت عملی الگورتھم کے عمل کی واضح تفہیم ہوگی۔