[TOC]
Layanan http kadang-kadang digunakan dalam pengembangan transaksi kuantitatif dan strategi otomatisasi._Serve()
Fungsi ini memberikan pengguna kemampuan untuk membuat layanan HTTP, HTTPS, dan TCP yang fleksibel. Dengan fitur ini, pengembang dapat menyederhanakan proses konfigurasi layanan dan menerapkan lebih banyak layanan kustomisasi di lingkungan kuantitatif, sehingga desain kebijakan lebih mulus dan mudah._Serve()
Skenario penggunaan fungsi dan operasi dasar untuk membantu Anda mengkualifikasi fitur baru ini dengan cepat.
Tentang_Serve()
Setelah itu, Anda dapat mengunduh aplikasi ini secara gratis.
Platform ditingkatkan_Serve()
Fungsi (karena sebelumnya bahasa JavaScript tidak memiliki fungsi untuk membuat layanan, fungsi ini hanya mendukung kebijakan bahasa JavaScript), secara sederhana adalah membuat kebijakan memiliki kemampuan untuk membuat layanan jaringan. Berdasarkan fungsi ini, kita dapat mengembangkan banyak fungsi untuk memecahkan banyak kebutuhan.
Dalam artikel ini, kami akan memberikan contoh tentang kebutuhan untuk "memperlengkapi fungsi protokol umum yang mendukung platform FMZ tanpa membungkus bursa yang tidak didukung"."Panduan Protokol Umum"Di sini kita menggunakan bahasa Python untuk transaksi OKX sehingga mode langsung terbungkus API ((karena FMZ sendiri mendukung OKX, menggunakan OKX di sini hanya sebagai contoh, berlaku untuk bursa lain yang tidak memiliki akses ke platform FMZ)); dalam teks, program protokol umum Python perlu berjalan secara terpisah, ketika bahasa JavaScript didukung_Serve()
Setelah fungsi, strategi bahasa JavaScript untuk mengakses protokol umum menjadi lebih sederhana.
Kami akan langsung mengintegrasikan protokol umum dari antarmuka bursa yang akan dibungkus sebagai "Library Template" ke dalam kebijakan, sehingga kebijakan ini dapat mengakses secara mulus bursa yang tidak didukung di FMZ. Untuk lebih lanjut tentang cara mengkonfigurasi objek bursa "protokol umum", lihat artikel:
Di platform ini, pertukaran protokol umum diatur sebagai berikut:
Anda dapat menggunakan template yang telah Anda buat./OKX
Untuk mengidentifikasi objek pertukaran protokol umum yang dikonfigurasi, pilihlah bursa mana yang menjadi miliknya.
Pertama, pencipta membuat strategi baru di platform perdagangan kuantitatif, dengan tipe kebijakan ditetapkan sebagai perpustakaan template, dan bahasa strategi adalah bahasa JavaScript.
Untuk membuat template strategi yang bagus, kami menambahkan tiga parameter:
Setelah itu, Anda dapat mulai merancang dan menulis kode untuk template protokol umum.
Kode ini ditulis dalam gaya TS.$.startService()
Fungsi adalah fungsi antarmuka template yang digunakan untuk memulai layanan 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 menginstal aplikasi ini, Anda harus menginstal aplikasi yang lebih kecil, tetapi tidak semua antarmuka yang diimplementasikan.Penyelidikan、Pencarian Aset、IO panggilan, Siswa yang tertarik dapat menerapkan semua antarmuka; desain selesai, menyimpan kode template, nama template disimpan sebagai:
Setelah konfigurasi OKX, seperti apkey, secretkey, passphrase, dan lain-lain selesai, kita dapat menulis kebijakan pengujian untuk pengujian.
Strategi memilih template yang kami rancang:
Kode strategi pengujian:
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 template yang memungkinkan akses lancar ke OKX (meskipun OKX sudah mendukung, misalnya OKX menggantikan FMZ sebagai pertukaran yang belum terhubung).