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

مصنف:لیدیہ, تخلیق: 2022-11-07 10:20:01, تازہ کاری: 2023-09-15 20:45:23

img

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

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

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

ڈیزائن کے خیالات

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

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

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

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

تو نظام 2 حصوں پر مشتمل ہے:

  1. آرڈر سنکرونائزیشن مینجمنٹ سسٹم کلاس لائبریری (سنگل سرور)
  2. آرڈر سنکرونائزیشن مینجمنٹ سسٹم (سنکرونس سرور)

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

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

نوٹ کریں کہ یہ کوئی حکمت عملی نہیں ہے۔ یہ ایف ایم زیڈ کی ٹیمپلیٹ کلاس لائبریری ہے۔ ٹیمپلیٹ کلاس لائبریری کا تصور ایف ایم زیڈ اے پی آئی دستاویزات میں تلاش کیا جاسکتا ہے اور ہم اسے دوبارہ نہیں دہرائیں گے۔

ٹیمپلیٹ کلاس لائبریری کا کوڈ:

// Global variables
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 the position
        var tradeDirection = type == PD_LONG ? "buy" : "sell"
        // send signals
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)        
    } else if (delta < 0) {
        // close the position
        var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
        if (nowAmount <= 0) {
            Log("no positions found")
            return 
        }
        // send signals
        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 the 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 future-following is supported"
    }

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

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

        // monitor positions
        var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct    // refPos-exIndex-symbol-contractType
        var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        if (!initRefPosAmount) {
            // no initialization data, initialize it
            mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
            initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        }

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

        // detect changes
        if (!(longPosDelta == 0 && shortPosDelta == 0)) {
            // Perform long positions
            if (longPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform long position-following, changes in volume:", longPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
            }
            // Perform short positions
            if (shortPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "Perform short position-following, changes in volume:", shortPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
            }

            // Update after performing the order-following operation
            mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
        }

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

$.getTbl = function() {
    var tbl = {
        "type" : "table", 
        "title" : "synchronization of data", 
        "cols" : [], 
        "rows" : []
    }
    // construct the table headers
    tbl.cols.push("monitor the account: refPos-exIndex-symbol-contractType")
    tbl.cols.push(`monitor the position: {"timestamp":xxx,"long positions":xxx,"short positions":xxx}`)
    _.each(fmzExtendApis, function(extendApiData, index) {
        tbl.cols.push(keyName_robotId + "-" + index)
    })
    
    // Write data in
    _.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
}

// Example of the strategy call that references the template class library
function main() {
    // Clear all logs
    LogReset(1)

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

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

    // Timed trading interval
    var tradeInterval = 1000 * 60 * 3        // Trade for every three minutes to observe the order-following signals
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strategy...

        // Simulated trading triggers for testing
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Interface functions that use templates
        $.PosMonitor(0, "ETH_USDT", "swap")    // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy  
        var tbl = $.getTbl()
        
        // Display status bar
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

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

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

  • $.getTbl نگرانی کی مطابقت پذیری کے اعداد و شمار پر واپس جائیں.

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

// Example of the strategy call that references the template class library
function main() {
    // Clear all logs
    LogReset(1)

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

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

    // Timed trading interval
    var tradeInterval = 1000 * 60 * 3        // Trade for every three minutes to observe the order-following signals
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // Other logic of the strategy...

        // Simulated trading triggers for testing
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("Trade the simulation order-leading strategies, position changes", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // Interface functions by using templates
        $.PosMonitor(0, "ETH_USDT", "swap")    // Multiple monitors can be set up to monitor different exchange objects on the order-following strategy  
        var tbl = $.getTbl()
        
        // Display status bar
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

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

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

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

ٹیسٹنگ سے پہلے، ہم حکمت عملی پیرامیٹرز ڈیزائن کی وضاحت کریں گےOrder Synchronization Management System Class Library (Single Server). ہم نے ابھی بات کی ہے کہ کس طرح ایک ٹیمپلیٹ کے انٹرفیس فنکشن کو استعمال کرنے کے لئے ایک حکمت عملی کو اپ گریڈ کرنے کے لئے آرڈر کی قیادت کرنے کا فنکشن حاصل کرنے کے لئے. پوزیشن تبدیل ہونے پر بھیجا سگنل کے بارے میں کیا، یہ کس کو بھیجا جائے گا؟ کس کو بھیجنے کا سوال پیرامیٹرز کی طرف سے تشکیل کیا جاتا ہےOrder Synchronization Management System Class Library (Single Server).

img

ہم دیکھ سکتے ہیں کہ 5 پیرامیٹرز ہیں، 5 تک کی حمایت کرتے ہیں دھکا (یہ اضافہ کرنے کی ضرورت ہے تو خود کی طرف سے توسیع کی جا سکتی ہے) ، ڈیفالٹ پیرامیٹرز خالی ڈور ہیں، یعنی، عملدرآمد نہیں کر رہے ہیں. ترتیب ڈور کی شکل: لیبل,robotId,accessKey,secretKey

  • لیبل ہم آہنگی اکاؤنٹ کے لئے ایک لیبل ، یہ ایک اکاؤنٹ کے لئے ایک لیبل ترتیب دینے کے لئے استعمال کیا جاتا ہے جس کا نام اپنی مرضی سے ترتیب دیا جاسکتا ہے۔

  • روبوٹ روبوٹ ID، کی شناختOrder Synchronous Serverاصلی بوٹ جو ہم وقت ساز اکاؤنٹ کے مالک نے بنایا ہے۔

  • رسائیKey ایف ایم زیڈ کا توسیع شدہ اے پی آئی رسائی کلید

  • خفیہ چابی ایف ایم زیڈ کی توسیع شدہ API خفیہ کلید

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

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 Synchronization Management System (Synchronous Server)عارضی کوڈ ہے، ہم اگلے شمارہ میں اس کے ڈیزائن کی تلاش جاری رکھیں گے.


متعلقہ

مزید