ایف ایم زیڈ پر مبنی آرڈر سنکرون مینجمنٹ سسٹم ڈیزائن (1)

مصنف:نینا باداس, تخلیق: 2022-04-06 15:08:26, تازہ کاری: 2022-04-24 18:00:51

ایف ایم زیڈ پر مبنی آرڈر سنکرون مینجمنٹ سسٹم ڈیزائن (1)

ایف ایم زیڈ ڈائجسٹ پر پچھلے مضامین میں، ہم نے کئی آرڈر اور پوزیشن مطابقت پذیر حکمت عملی ڈیزائن کیا ہے.

یہ ڈیزائن حوالہ اکاؤنٹ اور ہم وقت ساز اکاؤنٹ کو ایک ہی حکمت عملی میں لے جاتے ہیں تاکہ احکامات اور پوزیشنوں کی ہم وقت سازی کا احساس کرنے کے لئے ان کا انتظام کیا جاسکے۔ آج ، ہم ایک مختلف ڈیزائن آزما سکتے ہیں۔ ایف ایم زیڈ کے طاقتور توسیعی API انٹرفیس کی بنیاد پر ، یہاں ہم آرڈر ہم وقت ساز مینجمنٹ سسٹم ڈیزائن کرتے ہیں۔

ڈیزائن سوچنا

سب سے پہلے ، ہمیں کچھ اچھی تجاویز اور تقاضوں کی ضرورت ہے۔ مذکورہ بالا دو سابقہ احکامات اور پوزیشنوں کی ہم وقت سازی کی حکمت عملیوں میں کئی واضح نقصانات ہیں۔ آئیے ان پر ایک ساتھ تبادلہ خیال کریں:

  • 1.وہ صارفین جو حکمت عملی بوٹ ہم وقت سازی کو نافذ کرتے ہیں ان کے پاس حوالہ اکاؤنٹ پلیٹ فارم کی API KEY اور ہم وقت سازی اکاؤنٹ کی API KEY ہونی چاہئے۔ استعمال کے منظر نامے کے ل the ، مسئلہ یہ ہے کہ: آپ کے دوسرے پلیٹ فارم اکاؤنٹس کے ل your آپ کے اپنے اکاؤنٹس میں سے کسی ایک کی پیروی کرنا ٹھیک ہے۔ لیکن اس منظر نامے کے لئے یہ پریشان کن ہوسکتا ہے جہاں حوالہ اکاؤنٹ اور ہم وقت سازی کے اکاؤنٹ کا ایک ہی مالک نہیں ہے۔ ہم وقت سازی کے اکاؤنٹ کا مالک بعض اوقات سیکیورٹی کے خدشات کی وجہ سے اپنے پلیٹ فارم اکاؤنٹ کی API KEY فراہم کرنے سے انکار کرتا ہے۔ لیکن API KEY فراہم کیے بغیر ہم وقت سازی کے لئے آرڈر کیسے دیا جائے؟

    حل: ایف ایم زیڈ توسیع شدہ API کا استعمال کریں ، ہم آہنگی اکاؤنٹ کے مالک (آرڈر سپروائزر) کو صرف ایف ایم زیڈ کوانٹ ٹریڈنگ پلیٹ فارم کو رجسٹر کرنے کی ضرورت ہے ، اور پھر ایک حکمت عملی چلائیں (اس مضمون میں ڈیزائن کردہ نظام میں:Order Synchronous Management System (Synchronous Server)اس کے بعد ، ایف ایم زیڈ کی توسیع شدہ API KEY (نوٹ کریں کہ یہ پلیٹ فارم اکاؤنٹ کی API KEY نہیں ہے) اور آرڈر ہم وقت سازی مینجمنٹ سسٹم (ہم وقت ساز سرور) کی بوٹ ID حوالہ اکاؤنٹ کے مالک (آرڈر کے مالک) کو فراہم کی جائے گی۔ جب ریفرنس اکاؤنٹ کے مالک (آرڈر کے مالک) کے بوٹ (Order Synchronous Management System Library (Single Server)آرٹیکل میں ڈیزائن کردہ نظام میں) ایک سگنل بھیجتا ہے، مطابقت پذیری اکاؤنٹ کے مالک کے بوٹ کو تجارتی سگنل ملے گا.

  • 2.بہت سے ڈویلپرز کے پاس بہتر حکمت عملی ہے اور وہ اوپر بیان کردہ دو سابقہ آرڈر اور پوزیشن سنکرونائزیشن حکمت عملیوں کا استعمال نہیں کرسکتے ہیں۔ کیونکہ اس کے ل their ان کی اپنی حکمت عملیوں کو ان سنکرونائزیشن حکمت عملیوں کے ساتھ ضم کرنے کی ضرورت ہے ، اور ان کی حکمت عملیوں کو بہت زیادہ ترمیم کرنے کی ضرورت ہوسکتی ہے ، جو وقت طلب اور مزدوری سے زیادہ ہے۔ کیا آپ کی کچھ پختہ حکمت عملیوں کو براہ راست ان میں اپ گریڈ کرنے کا کوئی اچھا طریقہ ہے جو آرڈر سنکرونائزیشن فنکشن کے ساتھ ہیں۔

    حل: آپ کو ایک آرڈر ہم وقت ساز ٹیمپلیٹ لائبریری (کے ڈیزائن کر سکتے ہیںOrder Synchronous Management System Library (Single Server)آرٹیکل میں ڈیزائن کردہ نظام میں حکمت عملی) ، تاکہ حوالہ اکاؤنٹ کے مالک (آرڈر کے مالک) براہ راست آرڈر اور پوزیشن مطابقت پذیری کو حاصل کرنے کے لئے اپنی حکمت عملی میں اس ٹیمپلیٹ لائبریری کو داخل کرسکیں.

  • 3.ایک اضافی بوٹ کو کم کریں آخری نقصان یہ ہے کہ اگر آپ مندرجہ بالا بیان کردہ دو پچھلے احکامات اور پوزیشن مطابقت پذیری کی حکمت عملی استعمال کرتے ہیں تو ، بوٹ مانیٹرنگ کے لئے حوالہ اکاؤنٹ (حساب کے ساتھ احکامات) کی ایک اضافی پوزیشن کھولنا ضروری ہے۔ حل: حوالہ اکاؤنٹ کی حکمت عملی میں فنکشن ایمبیڈ کرنے کے لئے ٹیمپلیٹ لائبریری کا استعمال کریں.

لہذا نظام دو حصوں پر مشتمل ہے: آرڈر سنکرونس مینجمنٹ سسٹم لائبریری (سنگل سرور) آرڈر سنکرونس مینجمنٹ سسٹم (سنکرونس سرور)

ایک بار جب ہم اپنے مطالبات کو یقینی بناتے ہیں، چلو ڈیزائن شروع کرتے ہیں!

ڈیزائن 1: آرڈر سنکرونس مینجمنٹ سسٹم لائبریری (واحد سرور)

توجہ دیں کہ یہاں یہ ایک حکمت عملی نہیں ہے، لیکن ایک FMZ ٹیمپلیٹ لائبریری، FMZ API دستاویزات میں تلاش کیا جا سکتا ہے اور ہم یہاں بحث نہیں کریں گے.

ماڈل کا کوڈ:

// Global variable
var keyName_label = "label"
var keyName_robotId = "robotId"
var keyName_extendAccessKey = "extendAccessKey"
var keyName_extendSecretKey = "extendSecretKey"
var fmzExtendApis = parseConfigs([config1, config2, config3, config4, config5])
var mapInitRefPosAmount = {}

function parseConfigs(configs) {
    var arr = []
    _.each(configs, function(config) {
        if (config == "") {
            return 
        }
        var strArr = config.split(",")
        if (strArr.length != 4) {
            throw "configs error!"
        }
        var obj = {}
        obj[keyName_label] = strArr[0]
        obj[keyName_robotId] = strArr[1]
        obj[keyName_extendAccessKey] = strArr[2]
        obj[keyName_extendSecretKey] = strArr[3]
        arr.push(obj)
    })
    return arr 
}

function getPosAmount(pos, ct) {
    var longPosAmount = 0
    var shortPosAmount = 0
    _.each(pos, function(ele) {
        if (ele.ContractType == ct && ele.Type == PD_LONG) {
            longPosAmount = ele.Amount
        } else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
            shortPosAmount = ele.Amount
        }
    })
    var timestamp = new Date().getTime()
    return {ts: timestamp, long: longPosAmount, short: shortPosAmount}
}

function sendCommandRobotMsg (robotId, accessKey, secretKey, msg) {
    // https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"]
    var url = "https://www.fmz.com/api/v1?access_key=" + accessKey + "&secret_key=" + secretKey + "&method=CommandRobot&args=[" + robotId + ',"' + msg + '"]'
    Log(url)
    var ret = HttpQuery(url)
    return ret 
}

function follow(nowPosAmount, symbol, ct, type, delta) {
    var msg = ""
    var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
    if (delta > 0) {
        // Open position
        var tradeDirection = type == PD_LONG ? "buy" : "sell"
        // Send signal
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)        
    } else if (delta < 0) {
        // Open position 
        var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
        if (nowAmount <= 0) {
            Log("No position detected")
            return 
        }
        // Send signal 
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
    } else {
        throw "error"
    }
    if (msg) {
        _.each(fmzExtendApis, function(extendApiConfig) {
            var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
            Log("Call CommandRobot interface,", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
            Sleep(1000)
        })
    }
}

$.PosMonitor = function(exIndex, symbol, ct) {    
    var ts = new Date().getTime()
    var ex = exchanges[exIndex]
    // Judge the type of ex
    var exName = ex.GetName()
    var isFutures = exName.includes("Futures_")
    var exType = isFutures ? "futures" : "spot"
    if (!isFutures) {
        throw "Only support futures order supervising"
    }

    if (exType == "futures") {
        // Cache symbol ct
        var buffSymbol = ex.GetCurrency()
        var buffCt = ex.GetContractType()

        // Switch to the corresponding trading pair and contract code 
        ex.SetCurrency(symbol)
        if (!ex.SetContractType(ct)) {
            throw "SetContractType failed"
        }

        // Monitor position 
        var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct    // refPos-exIndex-symbol-contractType
        var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        if (!initRefPosAmount) {
            // The data is not initialized; initialize it          
            mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
            initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        }

        // Monitor
        var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
        // Calculate position changes 
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // Detect changes 
        if (!(longPosDelta == 0 && shortPosDelta == 0)) {
            // Execute long position action 
            if (longPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Execute long position order supervision, change volume:", longPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
            }
            // Execute short position action 
            if (shortPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Execute short position order supervision, change volume:", shortPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
            }

            // After executing the order supervision operation, update  
            mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
        }

        // Recover symbol ct
        ex.SetCurrency(buffSymbol)
        ex.SetContractType(buffCt)
    } else if (exType == "spot") {
        // Spot 
    }
}

$.getTbl = function() {
    var tbl = {
        "type" : "table", 
        "title" : "Synchrodata", 
        "cols" : [], 
        "rows" : []
    }
    // Construct the table title 
    tbl.cols.push("Monitoring account:refPos-exIndex-symbol-contractType")
    tbl.cols.push(`Mintoring position:{"timestamp":xxx,"long position volume":xxx,"short position volume":xxx}`)
    _.each(fmzExtendApis, function(extendApiData, index) {
        tbl.cols.push(keyName_robotId + "-" + index)
    })
    
    // Write in the data 
    _.each(mapInitRefPosAmount, function(initRefPosAmount, key) {
        var arr = [key, JSON.stringify(initRefPosAmount)]
        _.each(fmzExtendApis, function(extendApiData) {
            arr.push(extendApiData[keyName_robotId])
        })
        tbl.rows.push(arr)
    })

    return tbl
}

// Invocation example of the strategy in the template
function main() {
    // Clear all logs
    LogReset(1)

    //Switch to OKEX simulated bot test
    exchanges[0].IO("simulate", true)

    // Set contract 
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // Timed trading time interval
    var tradeInterval = 1000 * 60 * 3        // trade every three minutes, to observe the order supervising signal  
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strategy...

        // Used to test the simulated trade trigger  
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Simulated strategy with orders has trades, and positions changed", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Call the interface function in the template 
        $.PosMonitor(0, "ETH_USDT", "swap")    // You can set multiple monitors, to minitor different exchange objects in the strategy with orders
        var tbl = $.getTbl()
        
        // Display the status bar 
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

ڈیزائن بہت سادہ ہے، لائبریری 2 افعال ہیں. جب FMZ پلیٹ فارم پر ایک پروگرام ٹریڈنگ کی حکمت عملیOrder Synchronous Management System Library (Single Server)ٹیمپلیٹ کلاس لائبریری۔ یہ حکمت عملی پھر مندرجہ ذیل افعال استعمال کرسکتی ہے۔

  • $.پوس مانیٹر اس فنکشن کا اثر حکمت عملی میں تبادلے کے اشیاء کی پوزیشن تبدیلیوں کی نگرانی کرنا ہے، اور پھر ٹیمپلیٹ کے پیرامیٹرز میں مقرر کردہ بوٹ کو تجارتی سگنل بھیجنا ہے: آرڈر ہم وقت ساز مینجمنٹ سسٹم لائبریری (واحد سرور).
  • $.getTbl یہ فنکشن مانیٹرڈ سنکرون ڈیٹا واپس کرتا ہے۔

استعمال کی مثال میں ہےmainآرڈر سنکرونس مینجمنٹ سسٹم لائبریری میں فنکشن (واحد سرور):

// Invocation example of the strategy in the template 
function main() {
    // Clear all logs 
    LogReset(1)

    // Switch to OKEX simulated bot test 
    exchanges[0].IO("simulate", true)

    // Set contract 
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // Timed trading time interval
    var tradeInterval = 1000 * 60 * 3        // trade every three minutes, to observe the order supervising signal  
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strateg...

        // Used to test the simulated trade trigger  
        var ts = new Date().getTime()
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Simulated strategy with orders has trades, and positions changed", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Use the interface function of the template 
        $.PosMonitor(0, "ETH_USDT", "swap")    // You can set multiple monitors to monitor different exchange objects on an strategy with orders
        var tbl = $.getTbl()
        
        // Display the status bar
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

ایک ٹیمپلیٹ لائبریری خود بھی ایک حکمت عملی بوٹ تشکیل دے سکتی ہے ، جو عام طور پر ٹیمپلیٹ لائبریری کی جانچ کے لئے استعمال ہوتی ہے۔ مثال کے طور پر اس ٹیمپلیٹ کے لئے ایک ٹیسٹ۔ آپ سمجھ سکتے ہیں کہmainٹیمپلیٹ میں فنکشنmainآپ کی اپنی حکمت عملی میں سے ایک کی تقریب.

ٹیسٹ کوڈ کو ٹیسٹ کرنے کے لئے اوکیکس سمیلیٹڈ بوٹ کا استعمال کرنے کے لئے لکھا گیا ہے ، اور اوکیکس سمیلیٹڈ بوٹ کی API KEY کو ایف ایم زیڈ پر بطور حوالہ اکاؤنٹ (آرڈرز کے ساتھ) تشکیل دینے کی ضرورت ہے ، اور مرکزی فنکشن سمیلیٹڈ بوٹ پر سوئچ کرنا شروع ہوجاتا ہے۔ پھر ٹریڈنگ جوڑی کو ETH_USDT پر سیٹ کریں ، اور معاہدہ کو تبادلہ کرنے کے لئے سیٹ کریں۔ پھر ایک جبکہ لوپ درج کریں۔ لوپ میں ، حکمت عملی کی تجارت کے ٹرگر کا نمونہ بنانے کے لئے ہر 3 منٹ میں ایک آرڈر رکھا جاتا ہے۔$.PosMonitor(0, "ETH_USDT", "swap")جبکہ لوپ میں بلایا جاتا ہے ، اور بلایا فنکشن کا پہلا پیرامیٹر 0 ہے ، جس کا مطلب ہے کہ تبادلہ آبجیکٹ تبادلوں [0] ، تجارتی جوڑی ETH_USDT ، اور تبادلہ معاہدے کی نگرانی کرنا ہے۔ پھر کال کریں$.getTbl()چارٹ کی معلومات حاصل کرنے کے لئے، اور استعمالLogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")اسٹیٹس بار پر دکھائے جانے والے چارٹ ڈیٹا کو بنانے کے لئے۔

تو آپ دیکھتے ہیں، جب تک$.PosMonitor(0, "ETH_USDT", "swap")ایک حکمت عملی میں استعمال کیا جاتا ہے جو ٹیمپلیٹ کو بلاتا ہے، حکمت عملی ایک مخصوص علامت کی پوزیشن کی نگرانی اور پوزیشن تبدیلی پیغام کو دھکا دینے کا کام کرسکتا ہے.

ٹیسٹ سے پہلے، پیرامیٹر ڈیزائن کی وضاحتOrder Synchronous Management System Library (Single Server)حکمت عملی: میں نے ابھی بات کی تھی کہ ٹیمپلیٹ کے انٹرفیس فنکشن کو کس طرح استعمال کیا جائے تاکہ احکامات کو لے جانے کے فنکشن کے ساتھ حکمت عملی کو اپ گریڈ کیا جا سکے۔ تو جب پوزیشن بدل جاتی ہے تو کون سا سگنل بھیجا جاتا ہے؟ کس کو بھیجنے کا سوال پیرامیٹرز کی طرف سے تشکیل کیا جاتا ہےorder synchronous management system library (Single Server).

img

آپ پانچ پیرامیٹرز دیکھ سکتے ہیں ، جو زیادہ سے زیادہ پانچ دھکا کی حمایت کر سکتے ہیں (اگر آپ کو دھکا نمبر بڑھانے کی ضرورت ہے تو ، آپ اسے خود بڑھا سکتے ہیں) ؛ پیرامیٹرز کا ڈیفالٹ ایک خالی تار ہے ، یعنی اس پر کارروائی نہیں کی گئی ہے۔ تشکیل شدہ تار کی شکل میں: لیبل ، روبوٹ آئی ڈی ، رسائی کی ، خفیہ کی

  • لیبل ہم وقت ساز اکاؤنٹ کا لیبل، جس کا استعمال کسی اکاؤنٹ کو لیبل کرنے کے لئے کیا جاتا ہے۔ لیبل کا نام تصادفی طور پر مقرر کیا جاسکتا ہے۔

  • روبوٹ بوٹ آئی ڈی؛ بوٹ آئی ڈیorder synchronous management system (Synchronous Server)ہم وقت ساز اکاؤنٹ کے مالک کی طرف سے پیدا.

  • رسائیKey FMZ توسیع API کے رسائی کلید.

  • خفیہ ایف ایم زیڈ کے خفیہ کلید توسیع API.

پھر، ہم ایک سادہ ٹیسٹ کر سکتے ہیں.

آرڈر سنکرونس مینجمنٹ سسٹم لائبریری (سنگل سرور) بوٹ آپریشن:

img

آرڈر سنکرونس مینجمنٹ سسٹم (سنکرونس سرور) بوٹ نے سگنل موصول کیا: آرڈر سنکرونس مینجمنٹ سسٹم (سنکرونس سرور) اب مکمل طور پر ہمارے ذریعے ڈیزائن نہیں کیا گیا ہے، اور ہم ایک سادہ کوڈ کا استعمال کرتے ہوئے اس کا احساس کرنے کے لئے، ٹریڈنگ کے بغیر، صرف اشارے پرنٹنگ کر سکتے ہیں:

آرڈر سنکرونس مینجمنٹ سسٹم (سنکرونس سرور) عارضی کوڈ:

function main() {
    LogReset(1)
    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            // cmd: ETH_USDT,swap,buy,1
            Log("cmd: ", cmd)
        }
        Sleep(1000)
    }
}

img

جیسا کہ آپ دیکھ سکتے ہیں، ہم آہنگ اکاؤنٹ کے مالک کے بوٹ کو یہ پیغام ملا:ETH_USDT,swap,buy,1. اس طرح، اگلے مرحلے میں، ہم ٹریڈنگ جوڑی، معاہدہ کوڈ، ٹریڈنگ سمت اور حجم کے مطابق، خود کار طریقے سے احکامات کی نگرانی کر سکتے ہیں.

فی الحال،order synchronous management system (Synchronous Server)صرف عارضی کوڈ ہے، اور ہم اس کے ڈیزائن کے بارے میں مزید اگلے مضمون میں بات کر سکتے ہیں.


مزید