Pada artikel sebelumnya, kami menjelaskan analisis logika transaksi dari strategi grid sederhana, dan di artikel ini kami melanjutkan untuk menyelesaikan desain strategi pengajaran ini.
Analisis Logika Perdagangan Pada artikel sebelumnya, kami mengatakan bahwa hanya dengan menjelajahi setiap garis grid, menilai harga saat ini melalui garis grid maka dapat memicu tindakan perdagangan. Tetapi sebenarnya masih banyak detail logika, yang seringkali tidak memahami strategi yang ditulis pemula mudah terbentuk sebuah persepsi yang salah adalah bahwa logika yang dibuat sangat sederhana, kode juga harus dalam beberapa baris saja, sebenarnya ditulis menemukan banyak detail.
Pertama-tama, detail pertama yang harus kita pertimbangkan adalah desain dari segi grid tak terbatas.createNet
Jadi? Fungsi ini menghasilkan struktur data grid yang memiliki garis grid yang memiliki jumlah yang terbatas. Lalu bagaimana jika harga melampaui batas struktur data grid ini (lebih dari garis grid teratas adalah harga tertinggi, terbawah adalah harga terendah)?
Jadi yang pertama kita lakukan adalah menambahkan ekstensi pada struktur data grid.
Anda mulai menulis fungsi utama, yang merupakan kode yang akan memulai pelaksanaan kebijakan.
var diff = 50 // 全局变量,网格间距,可以设计成参数,方便讲解,我们把这个参数写死在代码里。
function main() {
// 实盘开始运行后,从这里开始执行策略代码
var ticker = _C(exchange.GetTicker) // 获取市场最新的行情数据ticker,ticker这个数据的结构参看FMZ API文档:https://www.fmz.com/api#ticker
var net = createNet(ticker.Last, diff) // 我们上篇设计的初始构造网格数据结构的函数,这里构造一个网格数据结构net
while (true) { // 然后程序逻辑就进入了这个while死循环,策略执行到此将不停的循环执行这里{}符号之内的代码
ticker = _C(exchange.GetTicker) // 死循环代码部分的第一行,获取最新的行情数据,更新给ticker变量
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 还有其它代码...
}
}
Untuk memperpanjang struktur data grid, kode ini (dipilih dari kode di atas):
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) { // 如果价格超过网格最高价格的网格线
net.push({ // 就在网格最高价格的网格线之后加入一个新的网格线
buy : false, // 初始化卖出标记
sell : false, // 初始化买入标记
price : net[net.length - 1].price + diff, // 在之前最高价格的基础上再加一个网格间距
})
}
while (ticker.Last <= net[0].price) { // 如果价格低于网格最低价格的网格线
var price = net[0].price - diff // 区别于向上添加,要注意向下添加新网格线的价格不能小于等于0,所以这里要判断
if (price <= 0) { // 小于等于0就不添加了,跳出这层循环
break
}
net.unshift({ // 就在网格最低价格的网格线之前添加一个新的网格线
buy : false,
sell : false,
price : price,
})
}
Di sini, kita akan membahas bagaimana kita dapat melakukan pemicu transaksi secara spesifik.
var diff = 50
var amount = 0.002 // 增加一个全局变量,也可以设计成参数,当然为了简便讲解,我们也写死在策略代码,
// 这个参数控制每次网格线上触发交易时的交易量
function main() {
var ticker = _C(exchange.GetTicker)
var net = createNet(ticker.Last, diff)
var preTicker = ticker // 在主循环(死循环)开始前,设置一个变量,记录上一次的行情数据
while (true) {
ticker = _C(exchange.GetTicker)
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 检索网格
for (var i = 0 ; i < net.length ; i++) { // 遍历网格数据结构中的所有网格线
var p = net[i]
if (preTicker.Last < p.price && ticker.Last > p.price) { // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
if (i != 0) {
var downP = net[i - 1]
if (downP.buy) {
exchange.Sell(-1, amount, ticker)
downP.buy = false
p.sell = false
continue
}
}
if (!p.sell && !p.buy) {
exchange.Sell(-1, amount, ticker)
p.sell = true
}
} else if (preTicker.Last > p.price && ticker.Last < p.price) { // 下穿,买入
if (i != net.length - 1) {
var upP = net[i + 1]
if (upP.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
upP.sell = false
p.buy = false
continue
}
}
if (!p.buy && !p.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
p.buy = true
}
}
}
preTicker = ticker // 把当前的行情数据记录在preTicker中,在下一次循环中,作为“上一次”行情数据和最新的对比,判断上穿下穿
Sleep(500)
}
}
Anda dapat melihat:
preTicker.Last < p.price && ticker.Last > p.price
preTicker.Last > p.price && ticker.Last < p.price
Dia mengatakan, "Saya tidak tahu apa yang akan terjadi.
Menggunakan cara ini hanya merupakan langkah pertama dalam menentukan apakah transaksi dapat dilakukan, termasuk menentukan tanda-tanda dalam data grid.
Jika naik, maka harga dinilai lebih rendah dari garis current grid dan tanda buy pada garis net terbaru, jika nilai tanda buy adalah benar, maka tanda buy pada garis net sebelumnya telah dibeli, maka tanda buy pada garis net sebelumnya disetel kembali menjadi false, dan tanda sell pada garis net saat ini disetel kembali menjadi false.
Setelah menilai kondisi yang baru saja terjadi, jika tidak ada pemicu, terus menilai, jika tanda beli / jual pada garis grid saat ini adalah palsu, maka ini berarti bahwa garis grid saat ini dapat diperdagangkan, karena itu adalah memakai, kita di sini melakukan operasi jual, setelah melakukan tanda jaringan saat ini sell tanda benar.
Di sini kita akan membahas beberapa hal yang sangat penting tentang bagaimana cara mengobati penyakit ini.
Untuk melihat beberapa data saat re-test, saya menuliskan sebuah fungsi.showTbl
Menampilkan data.
function showTbl(arr) {
var tbl = {
type : "table",
title : "网格",
cols : ["网格信息"],
rows : []
}
var arrReverse = arr.slice(0).reverse()
_.each(arrReverse, function(ele) {
var color = ""
if (ele.buy) {
color = "#FF0000"
} else if (ele.sell) {
color = "#00FF00"
}
tbl.rows.push([JSON.stringify(ele) + color])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}
Kode strategi lengkap:
/*backtest
start: 2021-04-01 22:00:00
end: 2021-05-22 00:00:00
period: 1d
basePeriod: 1m
exchanges: [{"eid":"OKEX","currency":"ETH_USDT","balance":100000}]
*/
var diff = 50
var amount = 0.002
function createNet(begin, diff) {
var oneSideNums = 10
var up = []
var down = []
for (var i = 0 ; i < oneSideNums ; i++) {
var upObj = {
buy : false,
sell : false,
price : begin + diff / 2 + i * diff,
}
up.push(upObj)
var j = (oneSideNums - 1) - i
var downObj = {
buy : false,
sell : false,
price : begin - diff / 2 - j * diff,
}
if (downObj.price <= 0) { // 价格不能小于等于0
continue
}
down.push(downObj)
}
return down.concat(up)
}
function showTbl(arr) {
var tbl = {
type : "table",
title : "网格",
cols : ["网格信息"],
rows : []
}
var arrReverse = arr.slice(0).reverse()
_.each(arrReverse, function(ele) {
var color = ""
if (ele.buy) {
color = "#FF0000"
} else if (ele.sell) {
color = "#00FF00"
}
tbl.rows.push([JSON.stringify(ele) + color])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}
function main() {
var ticker = _C(exchange.GetTicker)
var net = createNet(ticker.Last, diff)
var preTicker = ticker
while (true) {
ticker = _C(exchange.GetTicker)
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 检索网格
for (var i = 0 ; i < net.length ; i++) {
var p = net[i]
if (preTicker.Last < p.price && ticker.Last > p.price) { // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
if (i != 0) {
var downP = net[i - 1]
if (downP.buy) {
exchange.Sell(-1, amount, ticker)
downP.buy = false
p.sell = false
continue
}
}
if (!p.sell && !p.buy) {
exchange.Sell(-1, amount, ticker)
p.sell = true
}
} else if (preTicker.Last > p.price && ticker.Last < p.price) { // 下穿,买入
if (i != net.length - 1) {
var upP = net[i + 1]
if (upP.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
upP.sell = false
p.buy = false
continue
}
}
if (!p.buy && !p.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
p.buy = true
}
}
}
showTbl(net)
preTicker = ticker
Sleep(500)
}
}
"Saya tidak tahu apa yang akan terjadi.
Anda dapat melihat ciri-ciri strategi grid, ketika pasar sedang mengalami tren, akan ada kerugian besar, dan pendapatan akan pulih setelah pasar bergolak. Jadi strategi grid tidak tanpa risiko, strategi spot masih bisa berbaring di atas tanah yang biasa-biasa saja, strategi grid kontrak berjangka lebih berisiko, dan perlu pengaturan yang terlalu konservatif untuk parameter grid.
husr12345Ini adalah bahasa C++.
Tony233Apakah tidak seharusnya ketika memakai dan menjual harus melewati garis yang lebih tinggi dari harga saat ini? Ada juga exchange.Sell ((-1, amount, ticker) bagaimana fungsi ini berbeda dengan yang ada di dokumen api, saya melihat dokumen api mengatakan exchange.Sell ((Price, Amount), mengapa Anda memiliki tiga parameter, saya tidak mengerti, sangat rumit, saya juga gila
Tony233Sungguh sulit.
halSaat naik dan turun, exchange.Buy ((-1, amount * ticker.Last, ticker), amount * ticker.Last adalah hal yang aneh, mengapa tidak ada seller?
CYZWXhttps://www.fmz.com/strategy/291160 last_tick = [] garis = [] grid_buy_list = [] def net ((now_price): garis global print ((now_price) baris = [now_price*(1+0.003*i) untuk i dalam kisaran ((-1000,1000) ] Log (garis) Aku tidak tahu. def ontick ((): global last_tick garis global global grid_buy_list akun = pertukaran.GetAccount() Tick = pertukaran.GetTicker() last_tick.append ((ticker['Last']) jika len ((last_tick) == 1:kembali elif len ((last_tick) == 100:del last_tick[1] untuk i dalam rentang ((len)) garis): jika last_tick[-1] > line[i] dan last_tick[-2] < line[i] dan len(grid_buy_list)!= 0 dan i > min(grid_buy_list) dan akun['Stock'] >= 0,001: pertukaran.Menjual ((last_tick[-1],0.01) del grid_buy_list[grid_buy_list.index(min(grid_buy_list))] Log (bertukar.MendapatkanAkun) elif last_tick[-1] < line[i] dan last_tick[-2] > line[i] dan i tidak dalam grid_buy_list: tukar.Buy ((last_tick[-1],0.01) grid_buy_list.append (i) Log (bertukar.MendapatkanAkun) Definisi utama: net ((exchange.GetTicker() ['Terakhir']) Log (bertukar.MendapatkanAkun) sementara (benar): pada tanda tanda (() Tidur ((1000)
CYZWXTerima kasih kepada Dream God, sangat rinci, untuk membeli kembali semuanya dijelaskan, seolah-olah menulis versi py.
Penemu Kuantitas - Mimpi KecilStrategi ini adalah bahasa ```JavaScript ```.
Tony233Apakah kontrak permanen yang tercantum dalam artikel tidak dianggap sebagai kontrak berjangka?
Penemu Kuantitas - Mimpi KecilFutures adalah jumlah kontrak, dan harga pasar saat ini adalah jumlah pesanan.
Tony233Ya, saya ingin bertanya lagi, apa arti dari ini. Perhatikan: Anda memerlukan antarmuka pesanan bawah dari bursa yang mendukung daftar harga pasar ((tipe pesanan adalah pembayaran, parameter jumlah pesanan adalah jumlah dalam satuan mata uang) ). Cara pesanan pasar mata uang berjangka digital, unit parameter jumlah pesanan adalah jumlah kontrak. Saya melihat posting Anda mengevaluasi kontrak permanen USDT di etokex, yang tidak menghitung metode pesanan tiket pasar berjangka?
Tony233Oh, aku mengerti.
Penemu Kuantitas - Mimpi KecilFungsi API FMZ dapat menghasilkan fungsi output log seperti: Log ((...) ; exchange.Buy ((Price, Amount) ; exchange.CancelOrder ((Id) dan lain-lain dengan beberapa parameter output tambahan setelah parameter yang diperlukan.