[TOC]
কোয়ালিফাইড লেনদেন এবং অটোমেশন কৌশল বিকাশের জন্য কখনও কখনও এইচটিপি পরিষেবা ব্যবহার করা হয়।_Serve()
ফাংশন, যা ব্যবহারকারীদের HTTP, HTTPS এবং TCP পরিষেবা তৈরি করার জন্য নমনীয় ক্ষমতা প্রদান করে। এই বৈশিষ্ট্যটির মাধ্যমে, ডেভেলপাররা পরিষেবা কনফিগারেশন প্রক্রিয়াটি সহজতর করতে পারে এবং পরিমাণগত পরিবেশে আরও কাস্টমাইজড পরিষেবাগুলি বাস্তবায়ন করতে পারে, যা নীতি নকশা আরও মসৃণ এবং সুবিধাজনক করে তোলে।_Serve()
ফাংশন ব্যবহারের দৃশ্য এবং মৌলিক অপারেশনগুলি আপনাকে দ্রুত এবং দক্ষভাবে এই নতুন বৈশিষ্ট্যটি পরিমাণগত করতে সহায়তা করে।
সম্পর্কে_Serve()
এপিআই ডকুমেন্টেশন আপডেট করা হয়েছেঃ
প্ল্যাটফর্ম আপগ্রেড_Serve()
ফাংশন (যেহেতু পূর্ববর্তী জাভাস্ক্রিপ্ট ভাষায় পরিষেবা তৈরি করার বৈশিষ্ট্য ছিল না, এই ফাংশনটি শুধুমাত্র জাভাস্ক্রিপ্ট ভাষার নীতিগুলিকে সমর্থন করেছিল) সহজভাবে বলতে গেলে নীতিগুলিকে নেটওয়ার্ক পরিষেবা তৈরি করার ক্ষমতা দেওয়া হয়েছিল। এই বৈশিষ্ট্যটির ভিত্তিতে আমরা অনেকগুলি বৈশিষ্ট্য বিকাশ করতে পারি এবং অনেকগুলি চাহিদা সমাধান করতে পারি। উদাহরণস্বরূপ, নীতিগুলিকে বাহ্যিক ইন্টারফেস, ডেটা ফরোয়ার্ডিং, প্ল্যাটফর্ম সমর্থনকারী সাধারণ প্রোটোকল বৈশিষ্ট্য সহ একটি এক্সচেঞ্জের সাথে সামঞ্জস্যপূর্ণভাবে আবৃত করা যা এফএমজেড প্ল্যাটফর্মগুলি সমর্থন করে না ইত্যাদি।
এফএমজেড প্ল্যাটফর্মের সাথে সহযোগিতা করে এমন সাধারণ প্রোটোকলগুলির সাথে একত্রিত হওয়া এক্সচেঞ্জগুলিকে এমএফজেড প্ল্যাটফর্ম দ্বারা সমর্থিত নয়।"জেনারেল প্রোটোকল গাইড"আমরা পাইথন ভাষা ব্যবহার করি OKX লেনদেনের জন্য, তাই অবিলম্বে মোডটি এপিআই প্যাকেজ করা ((যেহেতু FMZ নিজেই OKX সমর্থন করে, এখানে OKX ব্যবহার করা কেবল একটি উদাহরণ, যা অন্যান্য FMZ প্ল্যাটফর্মের অ্যাক্সেস নেই এমন এক্সচেঞ্জগুলির জন্য প্রযোজ্য) ।_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("启动通用协议服务,address:", address, ",port:", port, "#FF0000")
if (proxyConfig != "") {
Log("设置代理:", proxyConfig, "#FF0000")
}
}
এখানে সব ইন্টারফেস বাস্তবায়ন করা হয় নি, শুধু বাস্তবায়ন করা হয়মামলার তদন্ত、সম্পদ অনুসন্ধান、আইও কল, আগ্রহী শিক্ষার্থীরা সমস্ত ইন্টারফেস বাস্তবায়ন করতে পারে; নকশা সম্পন্ন, টেমপ্লেট কোড সংরক্ষণ করুন, টেমপ্লেট নাম সংরক্ষণ করুনঃ
OKX এক্সচেঞ্জের Apkey, Secretkey, Passphrase ইত্যাদির কনফিগারেশন সম্পন্ন করার পর, আমরা একটি পরীক্ষার নীতি লিখতে পারি।
এই কৌশলটি আমাদের ডিজাইন করা টেমপ্লেট ক্যাটাগরি নির্বাচন করেঃ
পরীক্ষার কৌশল কোডঃ
function main() {
// 测试GetTicker
Log(`exchange.GetTicker():`, exchange.GetTicker())
// 测试GetAccount
Log(`exchange.GetAccount():`, exchange.GetAccount())
// 测试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"))
// 输出通用协议添加的交易所名称
Log(`exchange.GetName():`, exchange.GetName())
// 输出通用协议添加的交易所标签
Log(`exchange.GetLabel():`, exchange.GetLabel())
}
আপনি দেখতে পাচ্ছেন যে কৌশলটি কেবলমাত্র একটি টেমপ্লেট নির্বাচন করে OKX এক্সচেঞ্জের (যদিও OKX এক্সচেঞ্জগুলি ইতিমধ্যে সমর্থন করে, উদাহরণস্বরূপ এখানে OKX একটি FMZ এর পরিবর্তে একটি এক্সচেঞ্জ যা এখনও অ্যাক্সেস করা হয়নি) বিজোড় অ্যাক্সেস অর্জন করে।