[TOC]
Perkhidmatan http kadang-kadang digunakan dalam pengembangan transaksi kuantitatif dan strategi automasi._Serve()
Fungsi yang memberi pengguna keupayaan untuk membuat perkhidmatan HTTP, HTTPS dan TCP yang fleksibel. Dengan ciri ini, pemaju dapat menyederhanakan proses konfigurasi perkhidmatan dan melaksanakan lebih banyak perkhidmatan kustom dalam persekitaran kuantitatif, menjadikan reka bentuk dasar lebih lancar dan mudah._Serve()
Senario kegunaan dan operasi asas fungsi untuk membantu anda mengukur fungsi baru ini dengan cepat.
Mengenai_Serve()
Di laman web ini, anda boleh melihat beberapa gambar yang menarik.
Platform ditingkatkan_Serve()
Fungsi (kerana sebelum ini bahasa JavaScript tidak mempunyai fungsi untuk membuat perkhidmatan, fungsi ini hanya menyokong dasar bahasa JavaScript), secara ringkasnya adalah untuk menjadikan dasar mempunyai keupayaan untuk membuat perkhidmatan rangkaian. Berdasarkan fungsi ini, kita boleh membangunkan banyak fungsi untuk menyelesaikan banyak keperluan. Contohnya, menjadikan dasar mempunyai antara muka luar, pemindahan data, fungsi protokol umum yang menyokong platform tanpa membungkus pertukaran yang tidak disokong oleh platform FMZ.
Dalam artikel ini, kita akan memberi contoh keperluan: "Pertandingan yang tidak disokong oleh platform FMZ yang mempunyai fungsi protokol umum yang berfungsi dengan lancar".Buku Panduan Protokol UmumDalam bahasa Python, kami menggunakan OKX untuk berdagang, jadi mod langsung terbungkus API ((kerana FMZ sendiri menyokong OKX, OKX digunakan di sini hanya sebagai contoh, untuk pertukaran lain yang tidak mempunyai akses ke platform FMZ). Dalam teks, program protokol umum Python perlu dijalankan secara berasingan, apabila bahasa JavaScript disokong._Serve()
Selepas fungsi, strategi bahasa JavaScript untuk mengakses protokol umum menjadi lebih mudah.
Kami akan menggabungkan protokol umum antara muka pertukaran yang akan dibungkus sebagai "Layanan Templat" secara langsung ke dalam dasar, yang membolehkan akses lancar ke pertukaran yang tidak disokong di FMZ. Untuk mengkonfigurasi objek pertukaran protokol umum, lihat artikel:
Pertukaran protokol umum di platform ini disusun seperti berikut:
Ia boleh digunakan untuk membuat template./OKX
Pertukaran yang diiktiraf sebagai objek pertukaran protokol am yang diiktiraf.
Pertama, pencipta membuat strategi baru di platform dagangan kuantitatif pencipta, dengan jenis strategi ditetapkan sebagai perpustakaan templat, dan bahasa strategi adalah bahasa JavaScript.
Terdapat tiga parameter yang ditambah kepada templat strategi yang baik:
Kemudian anda boleh mula merancang, menulis kod untuk templat protokol umum.
Kod ini ditulis dengan gaya TS.$.startService()
Fungsi adalah fungsi antara muka templat yang digunakan untuk memulakan perkhidmatan protokol umum.
// @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")
}
}
Jika anda ingin melihat lebih banyak, anda perlu melihat lebih banyak, tetapi anda tidak boleh melihat lebih banyak.Siasatan、Soalan aset、panggilan IOPelajar yang berminat boleh melaksanakan semua antara muka; reka bentuk selesai, menyimpan kod templat, nama templat disimpan sebagai:
Setelah konfigurasi OKX diperbaiki, seperti apikey, secretkey, passphrase, dan lain-lain, kita boleh menulis satu strategi ujian untuk menguji.
Rancangan yang kami buat untuk perpustakaan templat kami:
Kode teknik ujian:
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())
}
Seperti yang dapat dilihat, strategi hanya memilih satu templat untuk mencapai akses lancar kepada bursa OKX (walaupun OKX telah menyokong, contohnya OKX menggantikan bursa FMZ yang belum disambungkan).