Pada artikel sebelumnya, kami telah membuat strategi grid yang sederhana, dan dalam artikel ini kami telah meningkatkan dan memperluas strategi ini menjadi strategi grid langsung multi-varietas, dan menguji strategi ini secara praktis. Tujuan kami bukan untuk menemukan "cawan suci", tetapi untuk membahas berbagai masalah dan solusi dari desain strategi. Artikel ini akan menjelaskan beberapa pengalaman saya dalam merancang strategi ini.
Artikel ini, seperti artikel sebelumnya, masih berdasarkan kuantitas penemu.FMZ.COMSaya tidak tahu apa yang akan terjadi.
Varietas
Saya ingin mengatakan bahwa strategi grid ini tidak hanya melakukanBTC_USDT
Dan bisa juga.LTC_USDT
/EOS_USDT
/DOGE_USDT
/ETC_USDT
/ETH_USDT
◎ Sebaliknya, pasangan transaksi langsung, dan varietas yang ingin berlari juga melakukan transaksi grid.
"Mengambil gambar dari berbagai jenis gempa yang terjadi, rasanya bagus. Permintaan terdengar sederhana, tetapi masalah muncul saat merancang.
Pertama, akuisisi berbagai jenis pasar. Ini adalah masalah pertama yang harus diselesaikan. Setelah melihat dokumen API dari bursa, saya menemukan bahwa bursa umum menawarkan antarmuka pasar agregat. OK, kita bisa mendapatkan data dengan menggunakan antarmuka pasar agregat.
Masalah kedua yang saya hadapi adalah aset akun. Karena ini adalah strategi multi-varietas, maka saya harus mempertimbangkan setiap transaksi untuk mengelola aset secara terpisah. Dan saya ingin mendapatkan semua data aset sekaligus. Mengapa saya ingin mendapatkan data aset akun? Karena Anda perlu menilai aset yang tersedia saat Anda memesan, atau apakah Anda ingin mendapatkannya dan menilai lagi? Atau apakah Anda perlu menghitung keuntungan, apakah Anda harus mencatat data aset akun awal, lalu mengambil data aset akun saat ini dan menghitung keuntungan dan kerugian dari perbandingan awal? Untungnya, antarmuka akun aset di bursa juga biasanya mengembalikan data aset semua mata uang, yang hanya kita dapatkan sekali dan kemudian memproses data.
3, Desain parameter strategi. Desain parameter multi-varietas dan desain parameter tunggal varietas jauh berbeda, karena meskipun logika perdagangan berbagai varietas yang sama, namun mungkin parameter saat perdagangan yang berbeda. Sebagai contoh, strategi grid, mungkin melakukan BTC_USDT perdagangan pasangan ketika ingin setiap perdagangan 0.01 BTC, tetapi ketika melakukan DOGE_USDT jika masih parameter ini ((perdagangan 0.01 koin) jelas tidak cocok, tentu saja Anda juga dapat memproses dengan jumlah USDT. Tapi masih akan ada masalah, jika BTC_USDT perdagangan 1000UU, DOGE_USDT perdagangan 10UU? kebutuhan selalu tidak dapat dipenuhi. Mungkin teman-teman yang lain akan berpikir tentang hal ini dan kemudian berkata: Saya bisa mengatur beberapa set parameter lebih banyak, untuk mengendalikan parameter yang berbeda dari pasangan transaksi yang harus dilakukan secara terpisah. Apakah ini masih tidak dapat fleksibel untuk memenuhi kebutuhan, dengan beberapa set parameter yang baik? dengan tiga set parameter, bagaimana jika saya akan melakukan empat varietas? sulit untuk mengubah strategi, menambahkan parameter... Oleh karena itu, ketika mendesain parameter untuk kebijakan multi-varietas, perlu mempertimbangkan kebutuhan parameter diferensiasi ini. Salah satu solusi adalah dengan mendesain parameter sebagai string biasa atau string JSON. Misalnya:
ETHUSDT:100:0.002|LTCUSDT:20:0.1
Di sini, perkalian yang terbagi menjadi data untuk setiap varietas, yang berartiETHUSDT:100:0.002
Ini adalah salah satu cara yang paling efektif untuk mengontrol transaksi ETH_USDT.LTCUSDT:20:0.1
Hal ini dikarenakan bahwa para trader yang menggunakan LTC-USDT untuk melakukan transaksi di pasar Forex tidak memiliki hak untuk melakukan transaksi di pasar forex.ETHUSDT:100:0.002
, dimana ETHUSDT menunjukkan pasangan transaksi yang akan Anda lakukan, 100 adalah interval grid, 0.002 adalah jumlah koin ETH yang diperdagangkan per grid, dan o: nickname adalah pembagian data ini ((Tentu saja, aturan parameter ini dibuat oleh desainer strategi, Anda dapat merancang apa pun sesuai dengan kebutuhan Anda)).
String-string ini berisi informasi parameter dari setiap varietas yang akan Anda lakukan, dan Anda dapat menganalisis string-string ini di dalam strategi, memberikan nilai variabel tertentu pada strategi, dan mengendalikan logika transaksi dari setiap varietas. Bagaimana cara mengulasnya? atau menggunakan contoh di atas.
function main() {
var net = [] // 记录的网格参数,具体运行到网格交易逻辑时,使用这里面的数据
var params = "ETHUSDT:100:0.002|LTCUSDT:20:0.1"
var arrPair = params.split("|")
_.each(arrPair, function(pair) {
var arr = pair.split(":")
var symbol = arr[0] // 交易对名称
var diff = parseFloat(arr[1]) // 网格间距
var amount = parseFloat(arr[2]) // 网格下单量
net.push({symbol : symbol, diff : diff, amount : amount})
})
Log("网格参数数据:", net)
}
Dengan cara ini, parameter akan diuraikan, dan tentu saja Anda juga bisa langsung menggunakan string JSON, yang lebih sederhana.
function main() {
var params = '[{"symbol":"ETHUSDT","diff":100,"amount":0.002},{"symbol":"LTCUSDT","diff":20,"amount":0.1}]'
var net = JSON.parse(params) // 记录的网格参数,具体运行到网格交易逻辑时,使用这里面的数据
_.each(net, function(pair) {
Log("交易对:", pair.symbol, pair)
})
}
4. Data permanen
Strategi yang dapat digunakan dalam pertempuran nyata dan strategi pengajaran juga berbeda, strategi pengajaran di atas hanyalah uji coba awal. Strategi logika, desain, dan masalah yang lebih banyak untuk dipertimbangkan saat pertempuran nyata. Pada saat pertempuran nyata, mungkin membuka, menghentikan disk nyata. Saat ini, semua data saat disk nyata berjalan hilang.
Di sini, Anda perlu menyimpan data penting saat disk berjalan secara permanen, sehingga data tersebut dapat dibaca saat di-boot kembali dan terus berjalan.
Ini bisa digunakan di inventor Quantum Trading Platform._G()
Fungsi, atau menggunakan fungsi operasi databaseDBExec()
Untuk informasi lebih lanjut, lihat dokumen FMZ API.
Jadi, contohnya, kita merancang fungsi sweeptail, dan kita menggunakan_G()
Fungsi menyimpan data grid.
var net = null
function main() { // 策略主函数
// 首先读取储存的net
net = _G("net")
// ...
}
function onExit() {
_G("net", net)
Log("执行扫尾处理,保存数据", "#FF0000")
}
function onexit() { // 平台系统定义的退出扫尾函数,在点击实盘停止时触发执行
onExit()
}
function onerror() { // 平台系统定义的异常退出函数,在程序发生异常时触发执行
onExit()
}
5. Pengurangan kuantitas pesanan, harga pesanan, jumlah pesanan minimum, jumlah pesanan minimum
Dalam sistem retesting tidak ada batasan yang ketat untuk jumlah pesanan, akurasi pesanan, dll, tetapi pada saat nyata, setiap bursa dapat memiliki standar yang ketat untuk harga saat pesanan, jumlah pesanan, dan setiap pasangan transaksi tidak sama. Jadi sering ada yang baru dalam sistem retesting.
Untuk situasi multi-varietas, kebutuhan ini lebih rumit. Untuk kebijakan tunggal varietas, Anda dapat merancang sebuah parameter untuk menentukan informasi seperti presisi, tetapi ketika Anda merancang kebijakan multi-varietas, jelas bahwa informasi yang ditulis dalam parameter akan tampak sangat rumit.
Pada saat ini, Anda perlu melihat dokumen API bursa untuk melihat apakah ada antarmuka transaksi untuk informasi yang relevan. Jika ada antarmuka ini, Anda dapat merancang kebijakan untuk mendapatkan informasi seperti presisi antarmuka akses otomatis, dan mengkonfigurasi ke informasi transaksi yang terlibat dalam perdagangan (dengan kata sederhana, apa yang tepat untuk permintaan akses otomatis dari bursa, kemudian disesuaikan dengan variabel yang terkait dengan parameter kebijakan).
6. Beradaptasi dengan berbagai bursa Mengapa pertanyaan ini ditempatkan di akhir? Karena solusi yang telah kami sebutkan di atas akan menimbulkan masalah terakhir ini, karena strategi kami adalah untuk menggunakan antarmuka pasar agregat, akses ke pertukaran untuk menyesuaikan data, akurasi transaksi, akses ke informasi akun untuk menangani setiap transaksi secara terpisah, dan sebagainya. Ada perbedaan pada panggilan antarmuka, perbedaan pada mekanisme. Untuk bursa langsung, perbedaan masih sedikit jika kebijakan grid ini diperluas ke versi berjangka. Perbedaan pada mekanisme masing-masing bursa lebih besar. Salah satu solusi adalah dengan merancang perpustakaan template FMZ. Implementasi dari diferensiasi ini ditulis dalam perpustakaan kelas. Mengurangi perpaduan antara kebijakan itu sendiri dan bursa. Kelemahan dari melakukan hal ini adalah bahwa Anda perlu menulis perpustakaan kelas template, dan dalam template ini dapat dilakukan secara khusus untuk setiap perbedaan bursa.
Berdasarkan analisis di atas, sebuah perpustakaan template dirancang untuk mengurangi keterpaduan antara strategi dan mekanisme dan antarmuka bursa.
Kita dapat merancang perpustakaan kelas template ini seperti ini (dihilangkan sebagian kode):
function createBaseEx(e, funcConfigure) {
var self = {}
self.e = e
self.funcConfigure = funcConfigure
self.name = e.GetName()
self.type = self.name.includes("Futures_") ? "Futures" : "Spot"
self.label = e.GetLabel()
// 需要实现的接口
self.interfaceGetTickers = null // 创建异步获取聚合行情数据线程的函数
self.interfaceGetAcc = null // 创建异步获取账户数据线程的函数
self.interfaceGetPos = null // 获取持仓
self.interfaceTrade = null // 创建并发下单
self.waitTickers = null // 等待并发行情数据
self.waitAcc = null // 等待账户并发数据
self.waitTrade = null // 等待下单并发数据
self.calcAmount = null // 根据交易对精度等数据计算下单量
self.init = null // 初始化工作,获取精度等数据
// 执行配置函数,给对象配置
funcConfigure(self)
// 检测configList约定的接口是否都实现
_.each(configList, function(funcName) {
if (!self[funcName]) {
throw "接口" + funcName + "未实现"
}
})
return self
}
$.createBaseEx = createBaseEx
$.getConfigureFunc = function(exName) {
dicRegister = {
"Futures_OKCoin" : funcConfigure_Futures_OKCoin, // OK期货的实现
"Huobi" : funcConfigure_Huobi,
"Futures_Binance" : funcConfigure_Futures_Binance,
"Binance" : funcConfigure_Binance,
"WexApp" : funcConfigure_WexApp, // wexApp的实现
}
return dicRegister
}
Dalam template, penerbitan dapat dilakukan untuk pertukaran tertentu, misalnya dengan WexApp analog FMZ:
function funcConfigure_WexApp(self) {
var formatSymbol = function(originalSymbol) {
// BTC_USDT
var arr = originalSymbol.split("_")
var baseCurrency = arr[0]
var quoteCurrency = arr[1]
return [originalSymbol, baseCurrency, quoteCurrency]
}
self.interfaceGetTickers = function interfaceGetTickers() {
self.routineGetTicker = HttpQuery_Go("https://api.wex.app/api/v1/public/tickers")
}
self.waitTickers = function waitTickers() {
var ret = []
var arr = JSON.parse(self.routineGetTicker.wait()).data
_.each(arr, function(ele) {
ret.push({
bid1: parseFloat(ele.buy),
bid1Vol: parseFloat(-1),
ask1: parseFloat(ele.sell),
ask1Vol: parseFloat(-1),
symbol: formatSymbol(ele.market)[0],
type: "Spot",
originalSymbol: ele.market
})
})
return ret
}
self.interfaceGetAcc = function interfaceGetAcc(symbol, updateTS) {
if (self.updateAccsTS != updateTS) {
self.routineGetAcc = self.e.Go("GetAccount")
}
}
self.waitAcc = function waitAcc(symbol, updateTS) {
var arr = formatSymbol(symbol)
var ret = null
if (self.updateAccsTS != updateTS) {
ret = self.routineGetAcc.wait().Info
self.bufferGetAccRet = ret
} else {
ret = self.bufferGetAccRet
}
if (!ret) {
return null
}
var acc = {symbol: symbol, Stocks: 0, FrozenStocks: 0, Balance: 0, FrozenBalance: 0, originalInfo: ret}
_.each(ret.exchange, function(ele) {
if (ele.currency == arr[1]) {
// baseCurrency
acc.Stocks = parseFloat(ele.free)
acc.FrozenStocks = parseFloat(ele.frozen)
} else if (ele.currency == arr[2]) {
// quoteCurrency
acc.Balance = parseFloat(ele.free)
acc.FrozenBalance = parseFloat(ele.frozen)
}
})
return acc
}
self.interfaceGetPos = function interfaceGetPos(symbol, price, initSpAcc, nowSpAcc) {
var symbolInfo = self.getSymbolInfo(symbol)
var sumInitStocks = initSpAcc.Stocks + initSpAcc.FrozenStocks
var sumNowStocks = nowSpAcc.Stocks + nowSpAcc.FrozenStocks
var diffStocks = _N(sumNowStocks - sumInitStocks, symbolInfo.amountPrecision)
if (Math.abs(diffStocks) < symbolInfo.min / price) {
return []
}
return [{symbol: symbol, amount: diffStocks, price: null, originalInfo: {}}]
}
self.interfaceTrade = function interfaceTrade(symbol, type, price, amount) {
var tradeType = ""
if (type == self.OPEN_LONG || type == self.COVER_SHORT) {
tradeType = "bid"
} else {
tradeType = "ask"
}
var params = {
"market": symbol,
"side": tradeType,
"amount": String(amount),
"price" : String(-1),
"type" : "market"
}
self.routineTrade = self.e.Go("IO", "api", "POST", "/api/v1/private/order", self.encodeParams(params))
}
self.waitTrade = function waitTrade() {
return self.routineTrade.wait()
}
self.calcAmount = function calcAmount(symbol, type, price, amount) {
// 获取交易对信息
var symbolInfo = self.getSymbolInfo(symbol)
if (!symbol) {
throw symbol + ",交易对信息查询不到"
}
var tradeAmount = null
var equalAmount = null // 记录币数
if (type == self.OPEN_LONG || type == self.COVER_SHORT) {
tradeAmount = _N(amount * price, parseFloat(symbolInfo.pricePrecision))
// 检查最小交易量
if (tradeAmount < symbolInfo.min) {
Log(self.name, " tradeAmount:", tradeAmount, "小于", symbolInfo.min)
return false
}
equalAmount = tradeAmount / price
} else {
tradeAmount = _N(amount, parseFloat(symbolInfo.amountPrecision))
// 检查最小交易量
if (tradeAmount < symbolInfo.min / price) {
Log(self.name, " tradeAmount:", tradeAmount, "小于", symbolInfo.min / price)
return false
}
equalAmount = tradeAmount
}
return [tradeAmount, equalAmount]
}
self.init = function init() { // 自动处理精度等条件的函数
var ret = JSON.parse(HttpQuery("https://api.wex.app/api/v1/public/markets"))
_.each(ret.data, function(symbolInfo) {
self.symbolsInfo.push({
symbol: symbolInfo.pair,
amountPrecision: parseFloat(symbolInfo.basePrecision),
pricePrecision: parseFloat(symbolInfo.quotePrecision),
multiplier: 1,
min: parseFloat(symbolInfo.minQty),
originalInfo: symbolInfo
})
})
}
}
Dan kemudian, menggunakan template ini dalam strategi sangat sederhana:
function main() {
var fuExName = exchange.GetName()
var fuConfigureFunc = $.getConfigureFunc()[fuExName]
var ex = $.createBaseEx(exchange, fuConfigureFunc)
var arrTestSymbol = ["LTC_USDT", "ETH_USDT", "EOS_USDT"]
var ts = new Date().getTime()
// 测试获取行情
ex.goGetTickers()
var tickers = ex.getTickers()
Log("tickers:", tickers)
// 测试获取账户信息
ex.goGetAcc(symbol, ts)
_.each(arrTestSymbol, function(symbol) {
_.each(tickers, function(ticker) {
if (symbol == ticker.originalSymbol) {
// 打印行情数据
Log(symbol, ticker)
}
})
// 打印资产数据
var acc = ex.getAcc(symbol, ts)
Log("acc:", acc.symbol, acc)
})
}
Strategi menulis berdasarkan template di atas sangat sederhana, seluruhnya sekitar 300+ baris, yang mewujudkan strategi grid multi-varietas mata uang digital.
Saat ini, mereka kehilangan uang.T_T
Jika Anda tidak bisa mengaksesnya, maka Anda tidak akan dapat mengaksesnya.
Jika Anda ingin bermain dengan WexApp, kirimkan beberapa kode pendaftaran:
购买地址: https://www.fmz.com/m/s/284507
注册码:
adc7a2e0a2cfde542e3ace405d216731
f5db29d05f57266165ce92dc18fd0a30
1735dca92794943ddaf277828ee04c27
0281ea107935015491cda2b372a0997d
1d0d8ef1ea0ea1415eeee40404ed09cc
Dengan lebih dari 200 U, segera setelah berlari, Anda akan bertemu dengan satu sisi yang besar, darah mengalir perlahan-lahan. Keuntungan terbesar dari jaring langsung adalah: Anda bisa tidur! Stabilitas juga berkumpul, tidak bergerak sejak 27 Mei, dan grid berjangka sementara belum berani mencoba.
Kuantitas KecilTerima kasih, Quantify, ada lampu menyala di jalan.
Sembilan MatahariMeng Wei Wu!
Makhluk di lintasanTerima kasih.
Penemu Kuantitas - Mimpi KecilTerima kasih atas dukungannya!
Penemu Kuantitas - Mimpi KecilTerima kasih atas dukungannya!