مقداری تجارت اور خودکار حکمت عملی کی ترقی میں ، http خدمات کا کبھی کبھی استعمال کیا جاتا ہے۔ ایف ایم زیڈ کوانٹ ٹریڈنگ پلیٹ فارم نے ایک فنکشن شامل کیا ہے_Serve()
حال ہی میں ، جو صارفین کو لچکدار HTTP ، HTTPS اور TCP سروس تخلیق کی صلاحیتوں کے ساتھ فراہم کرتا ہے۔ اس فنکشن کے ذریعہ ڈویلپرز سروس کی تشکیل کے عمل کو آسان بنا سکتے ہیں اور مقداری ماحول میں زیادہ اپنی مرضی کے مطابق خدمات کو نافذ کرسکتے ہیں ، جس سے حکمت عملی کا ڈیزائن ہموار اور زیادہ آسان ہوجاتا ہے۔ یہ مضمون فنکشن کے استعمال کے منظرنامے اور بنیادی آپریشن متعارف کرائے گا۔_Serve()
FMZ Quant کے اس نئے فنکشن کے ساتھ جلدی شروع کرنے میں آپ کی مدد کرنے کے لئے.
کے لئے پلیٹ فارم API دستاویزات_Serve()
کو اپ ڈیٹ کیا گیا ہے:
پلیٹ فارم نے فنکشن کو اپ گریڈ کیا ہے_Serve()
(چونکہ جاوا اسکرپٹ زبان میں پہلے خدمات بنانے کا فنکشن نہیں تھا ، لہذا یہ فنکشن صرف جاوا اسکرپٹ زبان میں حکمت عملیوں کی حمایت کرتا ہے۔ آسان الفاظ میں ، یہ حکمت عملیوں کو نیٹ ورک کی خدمات بنانے کی صلاحیت رکھنے کے قابل بناتا ہے۔ اس فنکشن کی بنیاد پر ، ہم بہت سارے افعال تیار کرسکتے ہیں اور بہت سارے مسائل حل کرسکتے ہیں۔ مثال کے طور پر ، حکمت عملیوں میں بیرونی انٹرفیس ، ڈیٹا فارورڈنگ ہوسکتی ہے ، اور پلیٹ فارم کے کسٹم پروٹوکول فنکشن کے ساتھ تعاون کرسکتے ہیں تاکہ ایف ایم زیڈ پلیٹ فارم کے ذریعہ تعاون نہیں کیے جانے والے تبادلے کو بغیر کسی رکاوٹ کے احاطہ کیا جاسکے۔
اس مضمون میں ، ہم ایک مثال کے طور پر _Serve()
، یہ اپنی مرضی کے مطابق پروٹوکول تک رسائی کے لئے جاوا اسکرپٹ زبان کی حکمت عملی کے لئے آسان ہے.
ہم تبادلہ انٹرفیس کے کسٹم پروٹوکول کو
ایک ٹیمپلیٹ ڈیزائن کرتے وقت، ہم استعمال کر سکتے ہیں/OKX
شناخت کرنے کے لئے کہ کون سا تبادلہ تشکیل شدہ کسٹم پروٹوکول ایکسچینج آبجیکٹ سے تعلق رکھتا ہے۔
سب سے پہلے، ایف ایم زیڈ کوانٹ ٹریڈنگ پلیٹ فارم میں ایک نئی حکمت عملی بنائیں، حکمت عملی کی قسم کو ٹیمپلیٹ لائبریری اور حکمت عملی کی زبان کو جاوا اسکرپٹ میں مقرر کریں.
تخلیق کردہ حکمت عملی ٹیمپلیٹ میں 3 پیرامیٹرز شامل کریں:
پھر ہم اپنی مرضی کے مطابق پروٹوکول ٹیمپلیٹ کے لئے ڈیزائن اور کوڈ لکھنا شروع کر سکتے ہیں.
کوڈ TS انداز میں لکھا گیا ہے.$.startService()
فنکشن ایک ٹیمپلیٹ انٹرفیس فنکشن ہے جو اپنی مرضی کے مطابق پروٹوکول سروس شروع کرنے کے لئے استعمال ہوتا ہے۔
// @ts-check
$.startService = function (address, port, proxyConfig) {
__Serve(`http://${address}:${port}`, function (ctx, proxyConfig) {
// interface
interface IData {
data: object
raw: object
}
interface IError {
error: any
}
// custom protocol for OKX
class CustomProtocolOKX {
apiBase: string = "https://www.okx.com"
accessKey: string
secretKey: string
passphrase: string
proxyConfig: string = ""
simulate: boolean = false
constructor(accessKey: string, secretKey: string, passphrase: string, simulate?: boolean, proxyConfig?: string) {
this.accessKey = accessKey
this.secretKey = secretKey
this.passphrase = passphrase
if (typeof(simulate) == "boolean") {
this.simulate = simulate
}
this.proxyConfig = proxyConfig
}
httpReq(method: string, path: string, query: string = "", params: {[key: string]: any} = {}, headers: {key: string, value: string | ArrayBuffer}[] = []): {[key: string]: any} {
let ret = null
let options = {
method: method,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6',
'Content-Type': 'application/json; charset=UTF-8',
'x-simulated-trading': this.simulate ? "1" : "0"
},
}
// headers
if (Array.isArray(headers) && headers.length > 0) {
for (var pair of headers) {
options.headers[pair.key] = pair.value
}
}
let url = ""
if (method == "GET") {
if (typeof(query) == "string" && query.length > 0) {
url = `${this.apiBase}${path}?${query}`
} else {
url = `${this.apiBase}${path}`
}
} else {
url = `${this.apiBase}${path}`
options.body = JSON.stringify(params)
}
// request
try {
if (this.proxyConfig != "") {
url = `${this.proxyConfig}${url}`
}
ret = JSON.parse(HttpQuery(url, options))
} catch(e) {
return null
}
return ret
}
callSignedAPI(method: string, path: string, query: string = "", params: {[key: string]: any} = {}): {[key: string]: any} {
const strTime = new Date().toISOString().slice(0, -5) + 'Z'
let jsonStr = ""
if (method == "GET") {
jsonStr = Object.keys(params).length > 0 ? JSON.stringify(params) : ""
} else {
jsonStr = Object.keys(params).length > 0 ? JSON.stringify(params) : "{}"
}
let message = `${strTime}${method}${path}${jsonStr}`
if (method === "GET" && query !== "") {
message = `${strTime}${method}${path}?${query}${jsonStr}`
}
const signature = Encode("sha256", "string", "base64", message, "string", this.secretKey)
let headers = []
headers.push({key: "OK-ACCESS-KEY", value: this.accessKey})
headers.push({key: "OK-ACCESS-PASSPHRASE", value: this.passphrase})
headers.push({key: "OK-ACCESS-TIMESTAMP", value: strTime})
headers.push({key: "OK-ACCESS-SIGN", value: signature})
return this.httpReq(method, path, query, params, headers)
}
urlEncode(params: {[key: string]: string | number}): string {
let encodeParams: string[] = []
for (const [key, value] of Object.entries(params)) {
encodeParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
}
return encodeParams.join("&")
}
symbol2Inst(symbol: string): string {
let arr = symbol.split("_")
if (arr.length >= 2) {
return `${arr[0]}-${arr[1]}`.toUpperCase()
} else {
return `${arr[0]}-USDT`.toUpperCase()
}
}
getSymbol(inst: string): string {
let arr = inst.split("-")
if (arr.length >= 2) {
return `${arr[0]}_${arr[1]}`.toUpperCase()
} else {
return `${arr[0]}-USDT`.toUpperCase()
}
}
// The following code encapsulates OKX's interface
GetTicker(symbol: string): IData | IError {
// GET /api/v5/market/ticker , param: instId
let inst = this.symbol2Inst(symbol)
let ret = this.httpReq("GET", "/api/v5/market/ticker", `instId=${inst}`)
let retData = {}
for (var ele of ret["data"]) {
retData["symbol"] = this.getSymbol(ele["instId"])
retData["buy"] = ele["bidPx"]
retData["sell"] = ele["askPx"]
retData["high"] = ele["high24h"]
retData["low"] = ele["low24h"]
retData["open"] = ele["open24h"]
retData["last"] = ele["last"]
retData["vol"] = ele["vol24h"]
retData["time"] = ele["ts"]
}
return {data: retData, raw: ret}
}
GetAccount(): IData | IError {
// GET /api/v5/account/balance
let ret = this.callSignedAPI("GET", "/api/v5/account/balance")
let retData = []
for (var ele of ret["data"]) {
for (var detail of ele["details"]) {
let asset = {"currency": detail["ccy"], "free": detail["availEq"], "frozen": detail["ordFrozen"]}
if (detail["availEq"] == "") {
asset["free"] = detail["availBal"]
}
retData.push(asset)
}
}
return {data: retData, raw: ret}
}
IO(method: string, path: string, params: {[key: string]: any}): {[key: string]: any} {
let ret = null
if (method == "GET") {
ret = this.callSignedAPI(method, path, this.urlEncode(params))
} else {
ret = this.callSignedAPI(method, path, "", params)
}
return {data: ret}
}
}
// protocol factory
class ProtocolFactory {
static createExWrapper(accessKey: string, secretKey: string, exName: string): any {
let protocol = null
if (exName == "/OKX") {
try {
let passphrase = ""
let simulate = false
let arrSecretKey = secretKey.split(",")
if (arrSecretKey.length == 2) {
secretKey = arrSecretKey[0]
passphrase = arrSecretKey[1]
} else if (arrSecretKey.length == 3) {
secretKey = arrSecretKey[0]
passphrase = arrSecretKey[1]
simulate = arrSecretKey[2] == "simulate" ? true : false
} else {
return null
}
protocol = new CustomProtocolOKX(accessKey, secretKey, passphrase, simulate, proxyConfig)
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
return null
}
}
return protocol
}
}
// http service
let resp = {}
let reqMethod = ctx.method()
let reqPath = ctx.path()
let httpMethod = ctx.header("Http-Method")
let reqBody = null
try {
reqBody = JSON.parse(ctx.body())
} catch(e) {
resp = {error: {name: e.name, stack: e.stack, message: e.message, errDesc: "JSON parse error."}}
}
// onPost
if (reqMethod == "POST") {
if (!["access_key", "secret_key", "method", "params"].every(key=> key in reqBody)) {
resp = {error: {reqBody: reqBody, errDesc: "reqBody error."}}
}
if ("error" in resp) {
ctx.write(JSON.stringify(resp))
return
}
let accessKey = reqBody["access_key"]
let secretKey = reqBody["secret_key"]
let method = reqBody["method"]
let params = reqBody["params"]
let protocol = ProtocolFactory.createExWrapper(accessKey, secretKey, reqPath)
if (!protocol) {
ctx.write(JSON.stringify({error: {errDesc: "createExWrapper error."}}))
return
}
// process GetTicker / GetAccount ...
if (method == "ticker") {
if (!["symbol"].every(key=> key in params)) {
resp = {error: {params: params, errDesc: "params error."}}
} else {
let symbol = params["symbol"]
resp = protocol.GetTicker(symbol)
}
} else if (method == "accounts") {
resp = protocol.GetAccount()
} else if (method.slice(0, 6) == "__api_") {
resp = protocol.IO(httpMethod, method.slice(6), params)
} else {
ctx.write(JSON.stringify({error: {method: method, errDesc: "method not support."}}))
return
}
ctx.write(JSON.stringify(resp))
}
}, proxyConfig)
}
function init() {
$.startService(address, port, proxyConfig)
Log("Start the custom protocol service, address:", address, ",port:", port, "#FF0000")
if (proxyConfig != "") {
Log("Setting up the proxy:", proxyConfig, "#FF0000")
}
}
محدود جگہ کی وجہ سے، تمام انٹرفیس یہاں لاگو نہیں ہیں.مارکیٹ کی تلاش , اثاثہ استفسار، اورآئی او کالانٹرفیسز پر عملدرآمد کیا جاتا ہے۔ دلچسپی رکھنے والے صارفین تمام انٹرفیسز پر عمل درآمد کرسکتے ہیں۔ ڈیزائن مکمل ہونے کے بعد ، ٹیمپلیٹ کوڈ کو محفوظ کریں اور ٹیمپلیٹ کا نام بطور محفوظ کریں:
OKX تبادلہ
حکمت عملی ہماری ڈیزائن ٹیمپلیٹ لائبریری کی جانچ پڑتال کرتا ہے:
ٹیسٹ کی حکمت عملی کا کوڈ:
function main() {
// Test GetTicker
Log(`exchange.GetTicker():`, exchange.GetTicker())
// Test GetAccount
Log(`exchange.GetAccount():`, exchange.GetAccount())
// Test exchange.IO
Log(`exchange.IO("api", "POST", "/api/v5/trade/cancel-all-after", "timeOut=0"):`, exchange.IO("api", "POST", "/api/v5/trade/cancel-all-after", "timeOut=0"))
// Output the exchange name added by the custom protocol
Log(`exchange.GetName():`, exchange.GetName())
// Output exchange tags added by the custom protocol
Log(`exchange.GetLabel():`, exchange.GetLabel())
}
جیسا کہ ہم دیکھ سکتے ہیں ، حکمت عملی کو صرف ایک ٹیمپلیٹ کی جانچ پڑتال کرنے کی ضرورت ہے تاکہ او کے ایکس ایکس ایکسچینج تک ہموار رسائی حاصل کی جاسکے (اگرچہ او کے ایکس ایکس ایکسچینج پہلے ہی اس کی حمایت کرتا ہے ، مثال کے طور پر ، او کے ایکس کو یہاں ایک تبادلے سے تبدیل کیا گیا ہے جس سے ایف ایم زیڈ نے ابھی تک رابطہ نہیں کیا ہے) ۔