avatar of 发明者量化-小小梦 发明者量化-小小梦
پر توجہ دیں نجی پیغام
4
پر توجہ دیں
1271
پیروکار

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

میں تخلیق کیا: 2022-02-14 19:46:30, تازہ کاری: 2025-05-16 16:36:53
comments   11
hits   1939

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

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

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

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

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

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

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

حل: FMZ کے توسیعی API انٹرفیس کا استعمال کرتے ہوئے، مطابقت پذیری اکاؤنٹ کے مالک (فالوور) کو صرف FMZ مقداری تجارتی پلیٹ فارم کو رجسٹر کرنے اور پھر حکمت عملی چلانے کی ضرورت ہوتی ہے (اس مضمون میں ڈیزائن کردہ نظام میں:订单同步管理系统(Synchronous Server)حکمت عملی حقیقی مارکیٹ)۔ پھر FMZ توسیع شدہ API KEY (نوٹ کریں، ایکسچینج اکاؤنٹ کی API KEY نہیں) اور آرڈر سنکرونائزیشن مینجمنٹ سسٹم (Synchronous Server) کی ریئل ٹائم ID حوالہ اکاؤنٹ کے مالک (وہ شخص جو آرڈر لاتا ہے) کو فراہم کریں۔ . اکاؤنٹ کے مالک کے حقیقی آرڈر کا حوالہ دیتے ہوئے (جس کا آرڈر ہے) (اس مضمون میں ڈیزائن کردہ سسٹم میں)订单同步管理系统类库(Single Server)) ایک سگنل بھیجتا ہے، مطابقت پذیر اکاؤنٹ کے مالک کا حقیقی اکاؤنٹ تجارتی سگنل وصول کرے گا اور اس کے بعد خود بخود آرڈر دے گا۔

    1. بہت سے ڈویلپرز کے پاس بہتر حکمت عملی ہے، لیکن وہ اوپر بیان کی گئی دو ماضی کی ترتیب اور پوزیشن کی مطابقت پذیری کی حکمت عملیوں کو استعمال نہیں کر سکتے۔ کیونکہ اس کے لیے اپنی حکمت عملی کو ان ہم آہنگی کی حکمت عملیوں کے ساتھ مربوط کرنے کی ضرورت ہوگی، اور حکمت عملی کو از سر نو ترتیب دینے کی ضرورت پڑسکتی ہے، جو کہ وقت طلب اور محنت طلب ہوگی۔ کیا میری کچھ بالغ حکمت عملیوں کو براہ راست آرڈر سنکرونائزیشن فنکشن میں اپ گریڈ کرنے کا کوئی اچھا طریقہ ہے؟ حل: آپ آرڈر سنکرونائزیشن ٹیمپلیٹ لائبریری ڈیزائن کرسکتے ہیں (اس مضمون میں ڈیزائن کیا گیا نظام订单同步管理系统类库(Single Server)حکمت عملی)، حوالہ اکاؤنٹ کے مالک (وہ شخص جو آرڈر لیتا ہے) کو آرڈر اور پوزیشن سنکرونائزیشن فنکشن کو حاصل کرنے کے لیے اس ٹیمپلیٹ لائبریری کو براہ راست اپنی حکمت عملی میں شامل کرنے کی اجازت دیتا ہے۔
    1. ایک اضافی اصلی آرڈر کو کم کریں۔ آخری درد کا نقطہ یہ ہے کہ اگر آپ اوپر بیان کردہ دو ماضی کی ترتیب اور پوزیشن کی مطابقت پذیری کی حکمت عملیوں کو استعمال کرتے ہیں۔ ریفرنس اکاؤنٹ (ایک اکاؤنٹ کے ساتھ) کی پوزیشنوں کی نگرانی کے لیے ایک اضافی اصلی اکاؤنٹ کھولنا ضروری ہے۔ حل: ریفرنس اکاؤنٹ کی حکمت عملیوں میں فعالیت کو سرایت کرنے کے لیے ٹیمپلیٹ لائبریری کا استعمال کریں۔

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

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

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

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

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

// 全局变量
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) {
        // 开仓
        var tradeDirection = type == PD_LONG ? "buy" : "sell"
        // 发送信号
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)        
    } else if (delta < 0) {
        // 平仓
        var tradeDirection = type == PD_LONG ? "closebuy" : "closesell"
        if (nowAmount <= 0) {
            Log("未检测到持仓")
            return 
        }
        // 发送信号
        msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta)
    } else {
        throw "错误"
    }
    if (msg) {
        _.each(fmzExtendApis, function(extendApiConfig) {
            var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg)
            Log("调用CommandRobot接口,", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret)
            Sleep(1000)
        })
    }
}

$.PosMonitor = function(exIndex, symbol, ct) {    
    var ts = new Date().getTime()
    var ex = exchanges[exIndex]
    // 判断ex类型
    var exName = ex.GetName()
    var isFutures = exName.includes("Futures_")
    var exType = isFutures ? "futures" : "spot"
    if (!isFutures) {
        throw "仅支持期货跟单"
    }

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

        // 切换到对应的交易对、合约代码
        ex.SetCurrency(symbol)
        if (!ex.SetContractType(ct)) {
            throw "SetContractType failed"
        }

        // 监控持仓
        var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct    // refPos-exIndex-symbol-contractType
        var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        if (!initRefPosAmount) {
            // 没有初始化数据,初始化          
            mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct)
            initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount]
        }

        // 监控
        var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct)
        // 计算仓位变动
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // 检测变动
        if (!(longPosDelta == 0 && shortPosDelta == 0)) {
            // 执行多头动作
            if (longPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行多头跟单,变动量:", longPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta)
            }
            // 执行空头动作
            if (shortPosDelta != 0) {
                Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行空头跟单,变动量:", shortPosDelta)
                follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta)
            }

            // 执行跟单操作后,更新
            mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount
        }

        // 恢复 symbol ct
        ex.SetCurrency(buffSymbol)
        ex.SetContractType(buffCt)
    } else if (exType == "spot") {
        // 现货
    }
}

$.getTbl = function() {
    var tbl = {
        "type" : "table", 
        "title" : "同步数据", 
        "cols" : [], 
        "rows" : []
    }
    // 构造表头
    tbl.cols.push("监控账户:refPos-exIndex-symbol-contractType")
    tbl.cols.push(`监控持仓:{"时间戳":xxx,"多头持仓量":xxx,"空头持仓量":xxx}`)
    _.each(fmzExtendApis, function(extendApiData, index) {
        tbl.cols.push(keyName_robotId + "-" + index)
    })
    
    // 写入数据
    _.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
}

// 引用该模板类库的策略调用范例
function main() {
    // 清除所有日志
    LogReset(1)

    // 切换到OKEX 模拟盘测试
    exchanges[0].IO("simulate", true)

    // 设置合约
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // 定时交易时间间隔
    var tradeInterval = 1000 * 60 * 3        // 三分钟交易一次,用于观察跟单信号
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // 策略其它逻辑...

        // 用于测试的模拟交易触发
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("模拟带单策略发生交易,持仓变化", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // 使用模板的接口函数
        $.PosMonitor(0, "ETH_USDT", "swap")    // 可以设置多个监控,监控带单策略上的不同的exchange对象  
        var tbl = $.getTbl()
        
        // 显示状态栏
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

ڈیزائن بہت آسان ہے، اس کلاس لائبریری میں 2 فنکشنل فنکشنز ہیں۔ جب FMZ پلیٹ فارم پر ایک پروگرامیٹک تجارتی حکمت عملی کا حوالہ دیا جاتا ہے۔订单同步管理系统类库(Single Server)ٹیمپلیٹ لائبریری کے بعد۔ اس حکمت عملی کو درج ذیل فنکشن کا استعمال کرتے ہوئے لاگو کیا جا سکتا ہے۔

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

  • $.getTbl مانیٹر شدہ مطابقت پذیری ڈیٹا لوٹاتا ہے۔

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

// 引用该模板类库的策略调用范例
function main() {
    // 清除所有日志
    LogReset(1)

    // 切换到OKEX 模拟盘测试
    exchanges[0].IO("simulate", true)

    // 设置合约
    exchanges[0].SetCurrency("ETH_USDT")
    exchanges[0].SetContractType("swap")

    // 定时交易时间间隔
    var tradeInterval = 1000 * 60 * 3        // 三分钟交易一次,用于观察跟单信号
    var lastTradeTS = new Date().getTime()
    
    while (true) {
        // 策略其它逻辑...

        // 用于测试的模拟交易触发
        var ts = new Date().getTime()
        if (ts - lastTradeTS > tradeInterval) {
            Log("模拟带单策略发生交易,持仓变化", "#FF0000")
            exchanges[0].SetDirection("buy")
            exchanges[0].Buy(-1, 1)
            lastTradeTS = ts
        }

        // 使用模板的接口函数
        $.PosMonitor(0, "ETH_USDT", "swap")    // 可以设置多个监控,监控带单策略上的不同的exchange对象  
        var tbl = $.getTbl()
        
        // 显示状态栏
        LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

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

OKEX سمولیشن ڈسک ٹیسٹ کو استعمال کرنے کے لیے ٹیسٹ کوڈ لکھا گیا ہے، یہ ضروری ہے کہ FMZ پر OKEX سمولیشن ڈسک 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")، حکمت عملی کو کسی خاص مصنوعات کی پوزیشنوں کی نگرانی اور پوزیشن کی تبدیلیوں کی بنیاد پر پیغامات بھیجنے کے فنکشن سے لیس کیا جاسکتا ہے۔

جانچ کرنے سے پہلے، براہ کرم وضاحت کریں۔订单同步管理系统类库(Single Server)حکمت عملی پیرامیٹر ڈیزائن: میں نے صرف اس بات کے بارے میں بات کی تھی کہ ٹیمپلیٹ انٹرفیس فنکشن کو کس طرح استعمال کیا جائے تاکہ حکمت عملی کو اپ گریڈ کیا جائے تاکہ ایک فنکشن ہو۔ تو پوزیشن تبدیل ہونے پر سگنل کس کو بھیجا جاتا ہے؟ یہ سوال کس کو بھیجا جاتا ہے اس کا تعین ہوتا ہے۔订单同步管理系统类库(Single Server)ترتیب دینے کے لیے پیرامیٹرز۔

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

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

  • label مطابقت پذیر اکاؤنٹ کا لیبل ایک مخصوص اکاؤنٹ کو نشان زد کرنے کے لیے استعمال کیا جاتا ہے، اور نام اپنی مرضی سے سیٹ کیا جا سکتا ہے۔

  • robotId حقیقی ID، مطابقت پذیری اکاؤنٹ کے مالک کی طرف سے بنائی گئی ہے۔订单同步管理系统(Synchronous Server)اصل لین دین کی ID۔

  • accessKey FMZ کی توسیع شدہ API accessKey

  • secretKey FMZ کی توسیع شدہ API secretKey

اگلا ہم ایک سادہ ٹیسٹ کر سکتے ہیں۔

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

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

آرڈر سنکرونائزیشن منیجمنٹ سسٹم (سنکرونس سرور) کو سگنل موصول ہوا: ہم نے ابھی تک آرڈر سنکرونائزیشن مینجمنٹ سسٹم (Synchronous Server) کا ڈیزائن مکمل نہیں کیا ہے، آئیے پہلے اسے ایک سادہ کوڈ کے ساتھ لاگو کریں جو لین دین نہیں کرتا بلکہ صرف سگنل پرنٹ کرتا ہے:

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

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

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

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

اس وقت订单同步管理系统(Synchronous Server)یہ صرف عارضی کوڈ ہے، ہم اگلے شمارے میں اس کے ڈیزائن کو دریافت کرتے رہیں گے۔