
তারপরপূর্ববর্তী বিষয়বস্তুব্যাখ্যা
তৃতীয় যুক্ত ফাংশন:
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("开始平衡", 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("开始平衡", 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, এবং উদ্ভাবক API ইন্টারফেস কল করুনexchange.GetAccount()ফাংশন, বর্তমান অ্যাকাউন্টের সর্বশেষ ডেটা প্রাপ্ত করুন এবং এটিকে বরাদ্দ করুন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সেকেন্ড) নিয়মিত আয় মুদ্রণের কার্যকারিতা উপলব্ধি করা যেহেতু আয় গণনা করার সময় প্রতিবন্ধী একটি কেনার মূল্য ব্যবহার করা হয়, শর্তগুলিও সীমিত।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)), অর্থাৎ, বর্তমান ক্রয় মূল্য অনুসারে মুদ্রাকে অর্থে (মূল্য মুদ্রা) রূপান্তর করুন এবং তারপরে অ্যাকাউন্টে অর্থের পরিমাণে এটি যোগ করুন এবং ঘোষিত স্থানীয় পরিবর্তনশীলের সাথে বরাদ্দ করুন।net. বর্তমান মোট নেট মূল্য শেষ রেকর্ড করা মোট সম্পদের সাথে সামঞ্জস্যপূর্ণ কিনা তা নির্ধারণ করুন:
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
যদি এটি অসামঞ্জস্যপূর্ণ হয়, যেnet != self.preNetযদি এটি সত্য হয়, ব্যবহার করুনnetনেট মূল্য রেকর্ড করতে ব্যবহৃত পরিবর্তনশীল আপডেট বৈশিষ্ট্যself.preNet. তারপর এই মুদ্রণ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, যদি আপনি মনে করেন যে অনেক কয়েন আছে, বাজারে একটি বিক্রি করুন এবং একটি ছোট অর্ডার দিন। অবশেষে, প্যারামিটার সেটিংস অনুযায়ী একটি নির্দিষ্ট সময়ের জন্য অপেক্ষা করুন।Sleep(BalanceTimeout)তারপর সমস্ত আদেশ বাতিল করুন।
var orders = exchange.GetOrders() # 获取当前所有挂单,存在orders变量
if (orders) { # 如果获取当前挂单数据的变量orders不为null
for (var i = 0; i < orders.length; i++) { # 循环遍历orders,逐个取消订单
if (orders[i].Id != self.tradeOrderId) {
exchange.CancelOrder(orders[i].Id) # 调用exchange.CancelOrder,根据orders[i].Id取消订单
}
}
}
চতুর্থ যোগ ফাংশন:
কৌশলের মূল অংশ, হাইলাইট আসছে,self.poll = function() {...}ফাংশন হল পুরো কৌশলের মূল যুক্তি আমরা আগের নিবন্ধে এটি সম্পর্কে কথা বলেছি।main()ফাংশনটি কার্যকর করা শুরু করে এবং প্রবেশ করেwhileঅসীম লুপের আগে, আমরা ব্যবহার করিvar reaper = LeeksReaper()লিক হার্ভেস্টার অবজেক্ট তৈরি করে এবং তারপরেmain()ফাংশন লুপ কলreaper.poll()এই যে ফাংশন বলা হয়.
self.pollফাংশনটি কার্যকর করা শুরু করে এবং প্রতিটি লুপের আগে কিছু প্রস্তুতিমূলক কাজ করে।self.numTick++সংখ্যা বাড়াও,self.updateTrades()সাম্প্রতিক বাজারের লেনদেনের রেকর্ড আপডেট করুন এবং সম্পর্কিত ব্যবহার ডেটা গণনা করুন।self.updateOrderBook()হ্যান্ডিক্যাপ (অর্ডার বুক) ডেটা আপডেট করুন এবং সম্পর্কিত ডেটা গণনা করুন।self.balanceAccount()মুদ্রা (পজিশন) ব্যালেন্স চেক করুন।
var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct # 计算爆发价格
var bull = false # 声明牛市标记的变量,初始为假
var bear = false # 声明熊市标记的变量,初始为假
var tradeAmount = 0 # 声明交易数量变量,初始为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)) // 会截取 4 ~ 1 这几个元素,返回一个新数组:[4,3,2,1]
}

এখানে ভালুক এবং ষাঁড়ের বিচারের শর্তগুলি হল:
self.numTick > 2সত্য হতে, এর মানে হল যে যখন শনাক্তকরণের দামের একটি নতুন রাউন্ড শুরু হয়, এটিকে শুরুতে ট্রিগার এড়াতে কমপক্ষে তিন রাউন্ড সনাক্তকরণের পরে এটি ট্রিগার করা উচিত।self.pricesসর্বশেষ তথ্য, যে, সর্বশেষ তথ্য এবংself.pricesঅ্যারেতে পূর্ববর্তী পরিসরের সর্বোচ্চ বা সর্বনিম্ন মূল্যের মধ্যে পার্থক্য ভাঙতে হবেburstPriceএটি একটি বিস্ফোরক মূল্য।যদি সমস্ত শর্ত পূরণ হয়, তাহলে চিহ্নিত করুনbullঅথবাbear, জন্যtrue, এবং দিনtradeAmountপরিবর্তনশীল অ্যাসাইনমেন্ট, স্টাড লেনদেনের পরিকল্পনা করা।
পূর্বের উপর ভিত্তি করেself.updateTrades()আপডেট এবং ফাংশন গণনাself.vol, পরামিতিগুলির জন্যBurstThresholdVolট্রেডিং এর তীব্রতা কমাতে হবে কিনা সিদ্ধান্ত নিন (পরিকল্পিত লেনদেনের পরিমাণ কমাতে হবে)।
if (self.vol < BurstThresholdVol) {
tradeAmount *= self.vol / BurstThresholdVol // 缩减计划交易量,缩减为之前量的self.vol / BurstThresholdVol 倍
}
if (self.numTick < 5) {
tradeAmount *= 0.8 // 缩减为计划的80%
}
if (self.numTick < 10) { // 缩减为计划的80%
tradeAmount *= 0.8
}
এরপর, ট্রেডিং সিগন্যাল এবং ট্রেডিং ভলিউম প্রয়োজনীয়তা পূরণ করে কিনা তা নির্ধারণ করুন:
if ((!bull && !bear) || tradeAmount < MinStock) { # 如果非牛市并且也非熊市,或者计划交易的量tradeAmount小于参数设置的最小交易量MinStock,poll函数直接返回,不做交易操作
return
}
উপরোক্ত রায় পাস করার পর, কার্যকর করুনvar tradePrice = bull ? self.bidPrice : self.askPriceএটি একটি বিয়ার মার্কেট বা ষাঁড়ের বাজারের উপর নির্ভর করে, লেনদেনের মূল্য নির্ধারণ করুন এবং লেডিং মূল্যের সংশ্লিষ্ট বিলের সাথে মূল্য নির্ধারণ করুন।
একটি শেষ লিখুনwhileলুপ, এই লুপের জন্য একমাত্র স্টপ শর্তtradeAmount >= MinStockপরিকল্পিত লেনদেনের পরিমাণ ন্যূনতম লেনদেনের পরিমাণের চেয়ে কম।
চক্রে, বর্তমান অবস্থা ষাঁড়ের বাজার বা ভালুকের বাজার কিনা তার উপর ভিত্তি করে আদেশটি কার্যকর করা হয়। এবং ভেরিয়েবলে অর্ডার আইডি রেকর্ড করুনorderId. প্রতিটি চক্রে একটি অর্ডার দেওয়ার পরে,Sleep(200)200 মিলিসেকেন্ড অপেক্ষা করুন। তারপর লুপে বিচার করুনorderIdএটি সত্য কিনা (অর্ডার ব্যর্থ হলে, অর্ডার আইডি ফেরত দেওয়া হবে না, এবং যদি শর্তটি ট্রিগার করা হবে না), যদি শর্তটি সত্য হয়। অর্ডার আইডি পান এবং এটি বরাদ্দ করুনself.tradeOrderId。
অর্ডার ডেটা সঞ্চয় করার জন্য একটি পরিবর্তনশীল ঘোষণা করুনorderপ্রাথমিক মান হলnull. তারপরে এই আইডির অর্ডার ডেটা পেতে লুপ করুন এবং অর্ডারটি পেন্ডিং অর্ডার স্ট্যাটাসে আছে কিনা, এই আইডি দিয়ে অর্ডারটি বাতিল করুন যদি এটি পেন্ডিং অর্ডার স্ট্যাটাসে না থাকে এই সনাক্তকরণ লুপের বাইরে।
var order = null // 声明一个变量用于保存订单数据
while (true) { // 一个while循环
order = exchange.GetOrder(orderId) // 调用GetOrder查询订单ID为 orderId的订单数据
if (order) { // 如果查询到订单数据,查询失败order为null,不会触发当前if条件
if (order.Status == ORDER_STATE_PENDING) { // 判断订单状态是不是正在挂单中
exchange.CancelOrder(orderId) // 如果当前正在挂单,取消该订单
Sleep(200)
} else { // 否则执行break跳出当前while循环
break
}
}
}
তারপর নিম্নলিখিত প্রক্রিয়া সম্পাদন করুন:
self.tradeOrderId = 0 // 重置self.tradeOrderId
tradeAmount -= order.DealAmount // 更新tradeAmount,减去提单的订单已经成交的数量
tradeAmount *= 0.9 // 减小下单力度
if (order.Status == ORDER_STATE_CANCELED) { // 如果订单已经是取消了
self.updateOrderBook() // 更新订单薄等数据
while (bull && self.bidPrice - tradePrice > 0.1) { // 牛市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格
tradeAmount *= 0.99
tradePrice += 0.1
}
while (bear && self.askPrice - tradePrice < -0.1) { // 熊市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格
tradeAmount *= 0.99
tradePrice -= 0.1
}
}
যখন প্রোগ্রাম প্রবাহ জাম্প আউটwhile (tradeAmount >= MinStock) {...}যখন এই চক্রটি ঘটে, তখন এর অর্থ হল এই মূল্য বিস্ফোরণ লেনদেন প্রক্রিয়াটি সম্পন্ন করা হয়েছে৷
বাস্তবায়নself.numTick = 0, অর্থাৎ রিসেটself.numTickহল 0।
LeeksReaper()কনস্ট্রাক্টর এক্সিকিউশন শেষে,selfফিরে আসা বস্তুটি হলvar reaper = LeeksReaper()যখন, ফিরে এসেছেreaper。
এ পর্যন্তLeeksReaper()আমরা বিশ্লেষণ করেছি কিভাবে কনস্ট্রাক্টর লিক হারভেস্টার অবজেক্ট তৈরি করে, লিক হারভেস্টার অবজেক্টের বিভিন্ন পদ্ধতি এবং প্রধান লজিক্যাল ফাংশনগুলির সম্পাদন প্রক্রিয়া। আমি বিশ্বাস করি যে এই নিবন্ধটি পড়ার পরে, আপনার উচ্চ-ফ্রিকোয়েন্সি সম্পর্কে আরও স্পষ্ট ধারণা থাকা উচিত। কৌশল অ্যালগরিদম প্রক্রিয়া। বুঝুন।