حال ہی میں ، ایف ایم زیڈ کے سرکاری گروپ میں بہت ساری مارٹنگیل حکمت عملیوں پر تبادلہ خیال کیا گیا ہے ، اور پلیٹ فارم پر کریپٹوکرنسی معاہدوں کی بہت سی مارٹنگیل حکمت عملیاں موجود نہیں ہیں۔ لہذا ، میں نے اس موقع کو استعمال کرتے ہوئے کریپٹوکرنسی فیوچر کے لئے ایک سادہ مارٹنگیل حکمت عملی تیار کی۔ اسے مارٹنگیل حکمت عملی کیوں کہا جاتا ہے؟ کیونکہ مارٹن حکمت عملی کے ممکنہ خطرات دراصل چھوٹے نہیں ہیں ، لہذا اسے بالکل مارٹن حکمت عملی کے مطابق ڈیزائن نہیں کیا گیا ہے۔ تاہم ، اس قسم کی حکمت عملی میں ابھی بھی بہت سارے خطرات ہیں ، اور مارٹن قسم کی حکمت عملی کی پیرامیٹر کی ترتیبات خطرے سے قریب سے وابستہ ہیں ، اور اس خطرے کو نظرانداز نہیں کیا جانا چاہئے۔
یہ مضمون بنیادی طور پر مارٹن کی طرح کی حکمت عملیوں کے ڈیزائن کی وضاحت کرتا ہے اور سیکھتا ہے۔ چونکہ حکمت عملی کا خیال بہت واضح ہے ، لہذا ایف ایم زیڈ کے صارف کی حیثیت سے ، ہم حکمت عملی کے ڈیزائن پر زیادہ غور کرتے ہیں۔
کریپٹوکرنسی فیوچر کی حکمت عملیوں کو ڈیزائن کرتے وقت اکثر کل ایکویٹی کا استعمال کیا جاتا ہے۔ اس کی وجہ یہ ہے کہ واپسی کا حساب لگانا پڑتا ہے ، خاص طور پر جب آپ کو تیرتی واپسی کا حساب لگانے کی ضرورت ہوتی ہے۔ چونکہ پوزیشن مارجن کے ساتھ مقیم ہے ، لہذا زیر التواء آرڈر بھی مقیم ہے۔ اس وقت ، API انٹرفیسexchange.GetAccount()
ایف ایم زیڈ پلیٹ فارم کے دستیاب اثاثوں اور زیر التواء آرڈر منجمد اثاثوں کو حاصل کرنے کے لئے کہا جاتا ہے۔ در حقیقت ، زیادہ تر کریپٹوکرنسی فیوچر ایکسچینجز کل ایکویٹی کے اعداد و شمار فراہم کرتے ہیں ، لیکن یہ وصف ایف ایم زیڈ پر یکساں طور پر پیک نہیں کیا گیا ہے۔
لہذا ہم مختلف تبادلے کے مطابق ان اعداد و شمار کو حاصل کرنے کے لئے افعال ڈیزائن:
// OKEX V5 obtain total equity
function getTotalEquity_OKEX_V5() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
// Binance futures
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
کےtotalEquity
اس کے بعد ہم کال انٹری کے طور پر ایک فنکشن لکھتے ہیں، اور تبادلے کے نام کے مطابق متعلقہ فنکشن کو کال کرتے ہیں۔
function getTotalEquity() {
var exName = exchange.GetName()
if (exName == "Futures_OKCoin") {
return getTotalEquity_OKEX_V5()
} else if (exName == "Futures_Binance") {
return getTotalEquity_Binance()
} else {
throw "This exchange is not supported"
}
}
اہم فنکشن اور اہم منطق کو ڈیزائن کرنے سے پہلے، ہمیں کچھ تیاری کرنے اور کچھ معاون افعال کو ڈیزائن کرنے کی ضرورت ہے.
تمام زیر التواء احکامات منسوخ کریں
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
یہ فنکشن ان لوگوں کے لئے واقف ہے جو اکثر ایف ایم زیڈ حکمت عملی مربع پر حکمت عملی کی مثال کا کوڈ پڑھتے ہیں ، اور بہت سی حکمت عملیوں نے اسی طرح کے ڈیزائن استعمال کیے ہیں۔ فنکشن موجودہ زیر التواء آرڈر کی فہرست حاصل کرنا ہے ، اور پھر انہیں ایک ایک کرکے منسوخ کرنا ہے۔
فیوچر کے لئے جگہ کا تعین کرنے کے لئے کارروائی
function trade(distance, price, amount) {
var tradeFunc = null
if (distance == "buy") {
tradeFunc = exchange.Buy
} else if (distance == "sell") {
tradeFunc = exchange.Sell
} else if (distance == "closebuy") {
tradeFunc = exchange.Sell
} else {
tradeFunc = exchange.Buy
}
exchange.SetDirection(distance)
return tradeFunc(price, amount)
}
function openLong(price, amount) {
return trade("buy", price, amount)
}
function openShort(price, amount) {
return trade("sell", price, amount)
}
function coverLong(price, amount) {
return trade("closebuy", price, amount)
}
function coverShort(price, amount) {
return trade("closesell", price, amount)
}
فیوچر ٹریڈنگ کے لئے چار سمتیں ہیں: اوپن لانگ ، اوپن شارٹ ، کور لانگ اور کور شارٹ۔ لہذا ہم نے ان کارروائیوں کے مطابق چار آرڈر فنکشن ڈیزائن کیے ہیں۔ اگر آپ صرف آرڈر پر غور کرتے ہیں تو ، پھر کئی ضروری عوامل ہیں: سمت ، آرڈر کی قیمت اور آرڈر کا حجم۔
تو ہم نے ایک فنکشن بھی ڈیزائن کیا جس کا نام تھا:trade
جب آپریشن کو سنبھالنے کے لئےdistance
, price
, amount
کی وضاحت کی گئی ہے۔
openLong، openShort، coverLong اور coverShort کے لئے فنکشن کالز آخر میںtrade
فنکشن، یعنی، مقررہ فاصلے، قیمت، اور مقدار کی بنیاد پر فیوچر ایکسچینج پر ایک آرڈر رکھنے.
حکمت عملی کا خیال بہت آسان ہے ، موجودہ قیمت کو بیس لائن کے طور پر لیں ، اور ایک خاص فاصلے پر اوپر یا نیچے فروخت (مختصر) اور خریدنے کے احکامات (طویل) رکھیں۔ ایک بار جب لین دین مکمل ہوجائے تو ، باقی تمام احکامات منسوخ کردیئے جائیں گے ، اور پھر پوزیشن کی قیمت کے مطابق ایک خاص فاصلے پر ایک نیا اختتامی آرڈر دیا جائے گا ، اور ایک اضافہ آرڈر تازہ ترین موجودہ قیمت پر رکھا جائے گا ، لیکن اضافی پوزیشنوں کے لئے آرڈر کا حجم دوگنا نہیں ہوگا۔
ابتدائی کام زیر التواء آرڈر کی وجہ سے، ہمیں آرڈر کی شناخت ریکارڈ کرنے کے لیے دو عالمی متغیرات کی ضرورت ہے۔
var buyOrderId = null
var sellOrderId = null
اس کے بعد حکمت عملی انٹرفیس پیرامیٹرز OKEX_V5 مشابہ بوٹ آپشن استعمال کرنے کے لئے ڈیزائن کیا گیا ہے، تو کچھ پروسیسنگ کوڈ میں کیا جا کرنے کی ضرورت ہے:
var exName = exchange.GetName()
// Switch OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
انٹرفیس پیرامیٹرز میں تمام معلومات کو ری سیٹ کرنے کا بھی ایک آپشن ہے ، لہذا کوڈ میں اسی طرح کی پروسیسنگ ہونی چاہئے:
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
ہم صرف مستقل معاہدوں کو چلاتے ہیں، لہذا تحریر یہاں طے شدہ ہے اور صرف مستقل طور پر مقرر کیا جاتا ہے.
exchange.SetContractType("swap")
اس کے بعد ہمیں آرڈر کی قیمت اور آرڈر کی رقم کی درستگی پر بھی غور کرنے کی ضرورت ہے۔ اگر درستگی کو صحیح طریقے سے ترتیب نہیں دیا جاتا ہے تو ، حکمت عملی کے حساب کے عمل کے دوران درستگی ضائع ہوجائے گی۔ اگر اعداد و شمار میں اعشاریہ کی ایک بڑی تعداد ہے تو ، تبادلے کے انٹرفیس کے ذریعہ آرڈر کو مسترد کرنا آسان ہے۔
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set precision", pricePrecision, amountPrecision)
ڈیزائن کی طرف سے سادہ ڈیٹا کی بازیابی
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "failed to obtain initial equity"
}
} else {
totalEq = recoverTotalEq
}
}
آپ کی حکمت عملی چل رہا ہے جب اکاؤنٹ کے ابتدائی کل ایکویٹی کی وضاحت کرنا چاہتے ہیں تو، آپ پیرامیٹر مقرر کر سکتے ہیںtotalEq
اگر اس پیرامیٹر کو -1 پر سیٹ کیا جاتا ہے تو ، حکمت عملی ذخیرہ شدہ کل ایکویٹی ڈیٹا کو پڑھے گی۔ اگر ذخیرہ شدہ کل ایکویٹی ڈیٹا نہیں ہے تو ، موجودہ پڑھے ہوئے کل ایکویٹی کو جاری حکمت عملی کی ابتدائی کل ایکویٹی کے طور پر استعمال کیا جاتا ہے۔ اس کے بعد ، کل ایکویٹی میں اضافہ منافع کی نشاندہی کرتا ہے ، اور کل ایکویٹی میں کمی نقصان کی نشاندہی کرتی ہے۔ اگر کل ایکویٹی ڈیٹا پڑھا جاتا ہے تو ، حکمت عملی ان اعداد و شمار کے ساتھ چلتی رہے گی۔
بنیادی منطق ابتدائی کام مکمل ہونے کے بعد، آخر کار ہم حکمت عملی کے بنیادی منطقی حصے میں پہنچ گئے۔ وضاحت کی سہولت کے لئے، میں نے ہدایات کو براہ راست کوڈ کے تبصروں پر لکھا۔
while (1) { // The main logic of the strategy is designed as an infinite loop
var ticker = _C(exchange.GetTicker) // Read the current market information first, mainly using the latest transaction price
var pos = _C(exchange.GetPosition) // Read current position data
if (pos.length > 1) { // Judging the position data, because of the logic of this strategy, it is unlikely that long and short positions will appear at the same time, so if there are long and short positions at the same time, an error will be thrown
Log(pos)
throw "Simultaneous long and short positions" // Throw an error to stop the strategy
}
//Depends on status
if (pos.length == 0) { // Make different operations according to the position status, when there is no position, pos.length == 0
// If you have not held a position, count the profit once
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "current total equity:", currTotalEq)
}
}
buyOrderId = openLong(ticker.Last - targetProfit, amount) // Open a buy order for a long position
sellOrderId = openShort(ticker.Last + targetProfit, amount) // Open a short sell order
} else if (pos[0].Type == PD_LONG) { // For long positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = openLong(price - targetProfit * n, amount)
sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
} else if (pos[0].Type == PD_SHORT) { // For short positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
sellOrderId = openShort(price + targetProfit * n, amount)
}
if (!sellOrderId || !buyOrderId) { // If one side of the pending order fails, cancel all pending orders and start over
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) { // The pending order is completed, start monitoring the order
var isFindBuyId = false
var isFindSellId = false
var orders = _C(exchange.GetOrders)
for (var i = 0 ; i < orders.length ; i++) {
if (buyOrderId == orders[i].Id) {
isFindBuyId = true
}
if (sellOrderId == orders[i].Id) {
isFindSellId = true
}
}
if (!isFindSellId && !isFindBuyId) { // Detected that both buy and sell orders have been filled
cancelAll()
break
} else if (!isFindBuyId) { // Detected buy order closing
Log("buy order closing")
cancelAll()
break
} else if (!isFindSellId) { // Detected sell order closing
Log("sell order closing")
cancelAll()
break
}
LogStatus(_D())
Sleep(3000)
}
Sleep(500)
}
پوری منطق اور ڈیزائن کی وضاحت کی گئی ہے۔
اسٹریٹجی کو 19 مئی کے بازار سے گزرنے دیں۔
یہ دیکھا جا سکتا ہے کہ مارٹنگیل حکمت عملی میں ابھی بھی کچھ خطرات ہیں۔
اصلی بوٹ OKEX V5 تخروپن بوٹ کے ساتھ چلایا جا سکتا ہے
حکمت عملی کا پتہ:https://www.fmz.com/strategy/294957
حکمت عملی بنیادی طور پر سیکھنے کے لیے استعمال کی جاتی ہے، اور حقیقی پیسے کو احتیاط سے استعمال کیا جانا چاہئے~!