
حکمت عملی کے ڈیزائن میں ابتدائی افراد کے لیے، ہیجنگ کی حکمت عملی ایک بہت اچھی تربیتی حکمت عملی ہے۔ یہ مضمون ایک سادہ لیکن حقیقی دنیا کی ڈیجیٹل کرنسی اسپاٹ ہیجنگ کی حکمت عملی کو نافذ کرتا ہے، امید ہے کہ ابتدائی افراد ڈیزائن کا کچھ تجربہ سیکھ سکیں گے۔
سب سے پہلے، یہ واضح ہے کہ ڈیزائن کی جانے والی حکمت عملی ایک ڈیجیٹل کرنسی سپاٹ ہیجنگ کی حکمت عملی ہے، جو کہ دو سپاٹ ایکسچینجز کے درمیان زیادہ قیمت کے ساتھ ایکسچینج پر فروخت کرنا اور کم قیمت پر خریدنا ہے۔ منافع کمانے کے لیے۔ جب زیادہ قیمتوں والے تمام ایکسچینجز کو سکوں میں تبدیل کیا جاتا ہے (کیونکہ زیادہ قیمتوں والے تمام سکے بیچے جاتے ہیں)، اور کم قیمت والے تمام ایکسچینج سکوں میں ہوتے ہیں (کم قیمتوں والے تمام سکے خریدے جاتے ہیں)، یہ ہیج کرنا ناممکن ہے۔ اس وقت، آپ صرف قیمت کے ریورس اور ہیج ہونے کا انتظار کر سکتے ہیں۔
ہیجنگ کرتے وقت، ایکسچینج میں آرڈر کی قیمت اور مقدار پر درستگی کی پابندیاں ہوتی ہیں، اور آرڈر کی مقدار کی کم از کم حد بھی ہوتی ہے۔ کم از کم حد کے علاوہ، حکمت عملی کو ایک وقت میں ہیجنگ کے لیے زیادہ سے زیادہ آرڈر والیوم پر بھی غور کرنا چاہیے اگر آرڈر کا حجم بہت زیادہ ہے، تو مارکیٹ میں کافی آرڈرز نہیں ہوں گے۔ آپ کو اس بات پر بھی غور کرنے کی ضرورت ہے کہ اگر دو ایکسچینج مختلف کرنسیوں میں ڈینومینیٹ کیے گئے ہیں تو ایکسچینج ریٹ کا استعمال کرتے ہوئے تبدیل کیسے کریں۔ جب ہیجنگ، ہینڈلنگ فیس اور لین دین کی لاگت اس وقت تک ممکن نہیں ہے جب تک کہ قیمت میں فرق نہ ہو۔ ایک خاص سطح، ہیجنگ کے نتیجے میں نقصان ہو گا۔
ان خیالات کی بنیاد پر، حکمت عملی کو کئی پیرامیٹرز ڈیزائن کرنے کی ضرورت ہے:
hedgeDiffPriceجب قیمت کا فرق اس قدر سے زیادہ ہو جاتا ہے تو ہیجنگ آپریشن شروع ہو جاتا ہے۔minHedgeAmount، کم از کم آرڈر کی مقدار (سکوں میں) جسے ہیج کیا جا سکتا ہے۔maxHedgeAmount، ایک ہیج کے لیے زیادہ سے زیادہ آرڈر کی مقدار (سکوں کی تعداد)۔pricePrecisionA، ایکسچینج A کی آرڈر کی قیمت کی درستگی (اعشاریہ جگہوں کی تعداد)۔amountPrecisionA, ایکسچینج A کے آرڈر کی مقدار کی درستگی (اعشاریہ جگہوں کی تعداد)۔pricePrecisionB، ایکسچینج B کے آرڈر کی قیمت کی درستگی (اعشاریہ جگہوں کی تعداد)۔amountPrecisionB، ایکسچینج B کے آرڈر کی مقدار کی درستگی (اعشاریہ جگہوں کی تعداد)۔rateA، پہلے شامل کردہ ایکسچینج آبجیکٹ کی شرح مبادلہ کی تبدیلی، ڈیفالٹ قدر 1 ہے، کوئی تبدیلی نہیں۔rateB، دوسری شامل کردہ ایکسچینج آبجیکٹ کی شرح مبادلہ کی تبدیلی، پہلے سے طے شدہ قدر 1 ہے اور کوئی تبدیلی نہیں کی جاتی ہے۔ہیجنگ کی حکمت عملی کو دو کھاتوں میں سکوں کی تعداد میں کوئی تبدیلی نہ کرنے کی ضرورت ہے (یعنی کسی سمتی پوزیشن کو برقرار رکھنا اور غیرجانبداری کو برقرار رکھنا)، لہذا توازن کو ہمیشہ چیک کرنے کے لیے حکمت عملی میں توازن کی منطق ہونے کی ضرورت ہے۔ بیلنس چیک کرتے وقت، دو ایکسچینجز سے اثاثوں کا ڈیٹا حاصل کرنا ناگزیر ہے۔ ہمیں اسے استعمال کرنے کے لیے ایک فنکشن لکھنے کی ضرورت ہے۔
function updateAccs(arrEx) {
var ret = []
for (var i = 0 ; i < arrEx.length ; i++) {
var acc = arrEx[i].GetAccount()
if (!acc) {
return null
}
ret.push(acc)
}
return ret
}
اگر آرڈر دینے کے بعد اس پر عمل نہیں ہوتا ہے تو ہمیں اسے بروقت منسوخ کرنا ہوگا اور اسے زیر التواء نہیں چھوڑنا ہوگا۔ اس آپریشن کو بیلنس ماڈیول اور ہیجنگ منطق دونوں میں ہینڈل کرنے کی ضرورت ہے، لہذا ایک مکمل آرڈر واپس لینے کے فنکشن کو ڈیزائن کرنے کی ضرورت ہے۔
function cancelAll() {
_.each(exchanges, function(ex) {
while (true) {
var orders = _C(ex.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
ex.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
}
})
}
سکوں کی تعداد کو متوازن کرتے وقت، ہمیں اعداد و شمار کی ایک خاص گہرائی میں جمع ہونے والے سکوں کی ایک خاص تعداد کی قیمت معلوم کرنے کی ضرورت ہوتی ہے، اس لیے ہمیں اسے سنبھالنے کے لیے اس طرح کے فنکشن کی ضرورت ہوتی ہے۔
function getDepthPrice(depth, side, amount) {
var arr = depth[side]
var sum = 0
var price = null
for (var i = 0 ; i < arr.length ; i++) {
var ele = arr[i]
sum += ele.Amount
if (sum >= amount) {
price = ele.Price
break
}
}
return price
}
اس کے بعد ہمیں مخصوص ہیجنگ آرڈر آپریشن کو ڈیزائن اور لکھنے کی ضرورت ہے، جسے ہم آہنگی کے آرڈر کے لیے ڈیزائن کرنے کی ضرورت ہے:
function hedge(buyEx, sellEx, price, amount) {
var buyRoutine = buyEx.Go("Buy", price, amount)
var sellRoutine = sellEx.Go("Sell", price, amount)
Sleep(500)
buyRoutine.wait()
sellRoutine.wait()
}
آخر میں، آئیے بیلنس فنکشن کے ڈیزائن کو مکمل کرتے ہیں، جو کچھ زیادہ ہی پیچیدہ ہے۔
keepBalance
function keepBalance(initAccs, nowAccs, depths) {
var initSumStocks = 0
var nowSumStocks = 0
_.each(initAccs, function(acc) {
initSumStocks += acc.Stocks + acc.FrozenStocks
})
_.each(nowAccs, function(acc) {
nowSumStocks += acc.Stocks + acc.FrozenStocks
})
var diff = nowSumStocks - initSumStocks
// 计算币差
if (Math.abs(diff) > minHedgeAmount && initAccs.length == nowAccs.length && nowAccs.length == depths.length) {
var index = -1
var available = []
var side = diff > 0 ? "Bids" : "Asks"
for (var i = 0 ; i < nowAccs.length ; i++) {
var price = getDepthPrice(depths[i], side, Math.abs(diff))
if (side == "Bids" && nowAccs[i].Stocks > Math.abs(diff)) {
available.push(i)
} else if (price && nowAccs[i].Balance / price > Math.abs(diff)) {
available.push(i)
}
}
for (var i = 0 ; i < available.length ; i++) {
if (index == -1) {
index = available[i]
} else {
var priceIndex = getDepthPrice(depths[index], side, Math.abs(diff))
var priceI = getDepthPrice(depths[available[i]], side, Math.abs(diff))
if (side == "Bids" && priceIndex && priceI && priceI > priceIndex) {
index = available[i]
} else if (priceIndex && priceI && priceI < priceIndex) {
index = available[i]
}
}
}
if (index == -1) {
Log("无法平衡")
} else {
// 平衡下单
var price = getDepthPrice(depths[index], side, Math.abs(diff))
if (price) {
var tradeFunc = side == "Bids" ? exchanges[index].Sell : exchanges[index].Buy
tradeFunc(price, Math.abs(diff))
} else {
Log("价格无效", price)
}
}
return false
} else if (!(initAccs.length == nowAccs.length && nowAccs.length == depths.length)) {
Log("错误:", "initAccs.length:", initAccs.length, "nowAccs.length:", nowAccs.length, "depths.length:", depths.length)
return true
} else {
return true
}
}
اب چونکہ یہ افعال حکمت عملی کی ضروریات کے مطابق ڈیزائن کیے گئے ہیں، ہم حکمت عملی کے مرکزی فنکشن کو ڈیزائن کرنا شروع کر سکتے ہیں۔
FMZ پر حکمت عملی یہ ہے۔mainفنکشن کا عمل شروع ہوتا ہے۔ موجودmainفنکشن کے آغاز میں ہمیں کچھ حکمت عملی شروع کرنے کی ضرورت ہے۔
var exA = exchanges[0]
var exB = exchanges[1]
یہ بعد میں کوڈ لکھنے میں بہت آرام دہ بناتا ہے۔
// 精度,汇率设置
if (rateA != 1) {
// 设置汇率A
exA.SetRate(rateA)
Log("交易所A设置汇率:", rateA, "#FF0000")
}
if (rateB != 1) {
// 设置汇率B
exB.SetRate(rateB)
Log("交易所B设置汇率:", rateB, "#FF0000")
}
exA.SetPrecision(pricePrecisionA, amountPrecisionA)
exB.SetPrecision(pricePrecisionB, amountPrecisionB)
اگر زر مبادلہ کی شرح پیرامیٹرrateA、rateBکچھ 1 پر سیٹ ہیں (پہلے سے طے شدہ 1 ہے)، یعنیrateA != 1یاrateB != 1ٹرگر نہیں کرے گا، لہذا شرح مبادلہ کی کوئی تبدیلی سیٹ نہیں کی جائے گی۔

بعض اوقات جب کوئی پالیسی فعال ہوتی ہے، تو تمام لاگز کو حذف کرنا اور ریکارڈ شدہ ڈیٹا کو صاف کرنا ضروری ہوتا ہے۔ آپ حکمت عملی انٹرفیس پیرامیٹر ڈیزائن کرسکتے ہیں۔isReset، اور پھر حکمت عملی کے ابتدائی حصے میں ری سیٹ کوڈ ڈیزائن کریں، مثال کے طور پر:
if (isReset) { // 当isReset为真时重置数据
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("重置所有数据", "#FF0000")
}
nowAccsیہ متغیر موجودہ اکاؤنٹ کے ڈیٹا کو ریکارڈ کرنے کے لیے استعمال کیا جاتا ہے، اس فنکشن کا استعمال کرتے ہوئے جسے ہم نے ابھی ڈیزائن کیا ہے۔updateAccsموجودہ ایکسچینج کے اکاؤنٹ کا ڈیٹا حاصل کریں۔initAccsاکاؤنٹ کی ابتدائی حیثیت کو ریکارڈ کرنے کے لیے استعمال کیا جاتا ہے (ڈیٹا جیسے سکوں کی تعداد اور ایکسچینج A اور ایکسچینج B کے متفرق سکوں کی تعداد)۔ کے لیےinitAccsپہلے استعمال کریں۔_G()فنکشن ریکوری (_G فنکشن ڈیٹا کو مستقل طور پر ریکارڈ کرے گا اور ریکارڈ شدہ ڈیٹا کو دوبارہ واپس کر سکتا ہے تفصیلات کے لیے، API دستاویزات دیکھیں:لنک)، اگر استفسار ناکام ہوجاتا ہے، تو قیمت تفویض کرنے اور استعمال کرنے کے لیے کرنٹ اکاؤنٹ کی معلومات استعمال کریں۔_Gفنکشن ریکارڈ۔مثال کے طور پر، درج ذیل کوڈ:
var nowAccs = _C(updateAccs, exchanges)
var initAccs = _G("initAccs")
if (!initAccs) {
initAccs = nowAccs
_G("initAccs", initAccs)
}
مرکزی لوپ میں کوڈ حکمت عملی کی منطق کے عمل کے ہر دور کا عمل ہے۔ آئیے مین لوپ میں پروگرام کے ہر عمل کے بہاؤ پر ایک نظر ڈالتے ہیں۔
var ts = new Date().getTime()
var depthARoutine = exA.Go("GetDepth")
var depthBRoutine = exB.Go("GetDepth")
var depthA = depthARoutine.wait()
var depthB = depthBRoutine.wait()
if (!depthA || !depthB || depthA.Asks.length == 0 || depthA.Bids.length == 0 || depthB.Asks.length == 0 || depthB.Bids.length == 0) {
Sleep(500)
continue
}
یہاں آپ FMZ پلیٹ فارم کے کنکرنٹ فنکشنز دیکھ سکتے ہیں۔exchange.Go، کال بنائیGetDepth()انٹرفیس کا کنکرنسی آبجیکٹdepthARoutine、depthBRoutine. جب یہ دو سمورتی اشیاء بن جائیں تو کال کریں۔GetDepth()انٹرفیس بھی فوری طور پر واقع ہوا، اور گہرائی کا ڈیٹا حاصل کرنے کے لیے دو درخواستیں ایکسچینج کو بھیجی گئیں۔
پھر کال کریں۔depthARoutine、depthBRoutineاعتراضwait()گہرائی سے ڈیٹا حاصل کرنے کا طریقہ۔
گہرائی کا ڈیٹا حاصل کرنے کے بعد، اس کی درستگی کا تعین کرنے کے لیے گہرائی کے ڈیٹا کو چیک کرنا ضروری ہے۔ ڈیٹا کی بے ضابطگیوں کے لیے عمل درآمد کو متحرک کریں۔continueبیان مین لوپ کو دوبارہ چلاتا ہے۔
价差值پیرامیٹرز یا差价比例پیرامیٹر؟ var targetDiffPrice = hedgeDiffPrice
if (diffAsPercentage) {
targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
}
ہم نے پیرامیٹرز کے لحاظ سے ایسا ڈیزائن بنایا ہے۔ FMZ کے پیرامیٹرز ایک مخصوص پیرامیٹر پر مبنی ہو سکتے ہیں۔دکھائیںیاچھپائیں، لہذا ہم استعمال کرنے کا فیصلہ کرنے کے لیے ایک پیرامیٹر بنا سکتے ہیں۔价格差، اب بھی差价比例。

حکمت عملی انٹرفیس کے پیرامیٹرز میں ایک پیرامیٹر شامل کیا گیا ہے۔diffAsPercentage. اس پیرامیٹر کی بنیاد پر دکھائے گئے یا چھپے ہوئے دو دیگر پیرامیٹرز کو سیٹ کیا گیا ہے:
hedgeDiffPrice@!diffAsPercentage، جبdiffAsPercentageFalse اس پیرامیٹر کو دکھاتا ہے۔
hedgeDiffPercentage@diffAsPercentage، جبdiffAsPercentageیہ پیرامیٹر ظاہر کرنے کے لیے درست ہے۔
اس ڈیزائن کے بعد، ہم نے جانچ پڑتال کیdiffAsPercentageپیرامیٹرز ہیجنگ ٹرگر کی حالت کے طور پر قیمت کے فرق کے تناسب پر مبنی ہیں۔ غیر چیک کریں۔diffAsPercentageپیرامیٹر قیمت کے فرق کو ہیجنگ ٹرگر کی حالت کے طور پر استعمال کرنا ہے۔
if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPrice && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) { // A -> B 盘口条件满足
var price = (depthA.Bids[0].Price + depthB.Asks[0].Price) / 2
var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance / price > minHedgeAmount) {
amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance / price, maxHedgeAmount)
Log("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, price, amount, nowAccs[1].Balance / price, nowAccs[0].Stocks) // 提示信息
hedge(exB, exA, price, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
} else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPrice && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) { // B -> A 盘口条件满足
var price = (depthB.Bids[0].Price + depthA.Asks[0].Price) / 2
var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance / price > minHedgeAmount) {
amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance / price, maxHedgeAmount)
Log("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, price, amount, nowAccs[0].Balance / price, nowAccs[1].Stocks) // 提示信息
hedge(exA, exB, price, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
}
ہیجنگ ٹرگر کی کئی شرائط ہیں:
1. سب سے پہلے، ہیجنگ کی قیمت کے فرق کو پورا کریں ہیجنگ صرف اس وقت کی جا سکتی ہے جب مارکیٹ کی قیمت کا فرق سیٹ کی قیمت کے فرق کو پورا کرتا ہے۔
2. مارکیٹ میں ہیجنگ والیوم کو پیرامیٹرز میں مقرر کردہ کم از کم ہیجنگ والیوم کو پورا کرنا چاہیے کیونکہ مختلف ایکسچینجز میں کم از کم آرڈر والیوم مختلف ہو سکتے ہیں، ان دونوں میں سے سب سے چھوٹا ہونا چاہیے۔
3. فروخت کرنے کے آپریشنز فروخت کرنے کے تبادلے میں کافی اثاثے ہیں، اور خریدنے کے لیے آپریشن خریدنے کے بدلے میں کافی اثاثے ہیں۔
جب ان شرائط کو پورا کیا جاتا ہے، ہیجنگ فنکشن کو ہیجنگ آرڈر دینے کے لیے انجام دیا جاتا ہے۔ مین فنکشن سے پہلے ہم نے پہلے سے متغیر کا اعلان کر دیا تھا۔isTradeیہ نشان زد کرنے کے لیے استعمال کیا جاتا ہے کہ آیا ہیجنگ ہوتی ہے، اگر ہیجنگ شروع ہوتی ہے، تو یہ متغیر پر سیٹ ہے۔true. اور عالمی متغیرات کو دوبارہ ترتیب دیں۔lastKeepBalanceTSlastKeepBalanceTS کو 0 پر سیٹ کریں (lastKeepBalanceTS کا استعمال حالیہ بیلنسنگ آپریشن کے ٹائم اسٹیمپ کو نشان زد کرنے کے لیے کیا جاتا ہے۔ اسے 0 پر سیٹ کرنے سے بیلنسنگ آپریشن فوری طور پر شروع ہو جائے گا) اور پھر تمام زیر التواء آرڈرز کو منسوخ کریں۔
if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
nowAccs = _C(updateAccs, exchanges)
var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
cancelAll()
if (isBalance) {
lastKeepBalanceTS = ts
if (isTrade) {
var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
isTrade = false
}
}
}
آپ دیکھ سکتے ہیں کہ بیلنس فنکشن کو باقاعدگی سے انجام دیا جاتا ہے، لیکن اگر ہیجنگ آپریشن کو متحرک کیا جاتا ہے،lastKeepBalanceTSاگر 0 پر ری سیٹ کیا جاتا ہے، تو بیلنس آپریشن فوری طور پر شروع ہو جائے گا۔ بیلنس کامیاب ہونے کے بعد، منافع کا حساب لگایا جائے گا۔
LogStatus(_D(), "A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, " B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, " targetDiffPrice:", targetDiffPrice, "\n",
"当前A,Stocks:", nowAccs[0].Stocks, "FrozenStocks:", nowAccs[0].FrozenStocks, "Balance:", nowAccs[0].Balance, "FrozenBalance", nowAccs[0].FrozenBalance, "\n",
"当前B,Stocks:", nowAccs[1].Stocks, "FrozenStocks:", nowAccs[1].FrozenStocks, "Balance:", nowAccs[1].Balance, "FrozenBalance", nowAccs[1].FrozenBalance, "\n",
"初始A,Stocks:", initAccs[0].Stocks, "FrozenStocks:", initAccs[0].FrozenStocks, "Balance:", initAccs[0].Balance, "FrozenBalance", initAccs[0].FrozenBalance, "\n",
"初始B,Stocks:", initAccs[1].Stocks, "FrozenStocks:", initAccs[1].FrozenStocks, "Balance:", initAccs[1].Balance, "FrozenBalance", initAccs[1].FrozenBalance)
اسٹیٹس بار ڈیزائن میں خاص طور پر پیچیدہ نہیں ہے، یہ موجودہ وقت، ایکسچینج A سے ایکسچینج B میں قیمت کا فرق، اور ایکسچینج B سے ایکسچینج A میں قیمت کا فرق دکھاتا ہے۔ موجودہ ہیج ہدف کے پھیلاؤ کو دکھاتا ہے۔ A ایکسچینج اکاؤنٹ اور B ایکسچینج اکاؤنٹ کا اثاثہ ڈیٹا دکھاتا ہے۔
پیرامیٹرز کے لحاظ سے، ہم نے حکمت عملی کے آغاز میں تبادلوں کی شرح کی قدر کا پیرامیٹر ڈیزائن کیا۔mainہم نے فنکشن کے ابتدائی آپریشن کے لیے شرح مبادلہ کی تبدیلی کو بھی ڈیزائن کیا ہے۔ واضح رہے کہ ۔SetRateایکسچینج ریٹ کنورژن فنکشن کو پہلے انجام دینے کی ضرورت ہے۔
کیونکہ یہ فنکشن دو سطحوں کو متاثر کرتا ہے:
BTC_USDT، قیمت کی اکائیاں ہیں۔USDTاکاؤنٹ کے اثاثوں میں دستیاب کرنسی ہے۔USDT. اگر میں اسے CNY میں تبدیل کرنا چاہتا ہوں تو اسے کوڈ میں سیٹ کریں۔exchange.SetRate(6.8)بسexchangeاس ایکسچینج آبجیکٹ کے تحت تمام فنکشنز سے حاصل کردہ ڈیٹا کو CNY میں تبدیل کیا جاتا ہے۔
تبدیلی کے لیے کرنسی کیوں استعمال کی جاتی ہے؟SetRateفنکشن پاسنگموجودہ کرنسی سے ہدف کرنسی تک کی شرح تبادلہ。مکمل حکمت عملی:مختلف کرنسیوں کے لیے اسپاٹ ہیجنگ کی حکمت عملی (ٹیوٹوریل)