Pada artikel sebelumnya, kami menjelaskan prinsip dan tes balik dari transaksi yang dipasangkan.https://www.fmz.com/digest-topic/10457 Ini adalah sumber kode praktis yang didasarkan pada platform FMZ, dan strategi yang relatif sederhana dan jelas untuk belajar pemula. Platform FMZ baru-baru ini meng-upgrade beberapa API untuk menjadi lebih ramah untuk strategi multi-transaksi. Artikel ini akan menjelaskan lebih lanjut tentang kode sumber JavaScript untuk kebijakan ini.https://www.fmz.com/strategy/456143Anda dapat meng-copy secara langsung.
Jika Anda belum terbiasa dengan platform FMZ, saya sangat menyarankan Anda membaca tutorial ini:https://www.fmz.com/bbs-topic/4145Di sini, Anda akan menemukan beberapa tips tentang cara menginstal robot dari awal hingga akhir.
Di bawah ini adalah kerangka kebijakan yang paling sederhana, fungsi utama adalah masuk. Kebijakan jaminan siklus mati yang terus-menerus dijalankan, termasuk waktu tidur yang kecil untuk menghindari frekuensi akses yang terlalu cepat melampaui batas bursa.
function main(){
while(true){
//策略内容
Sleep(Interval * 1000) //Sleep
}
}
Robot akan berulang kali dihidupkan kembali karena berbagai alasan, seperti munculnya kesalahan, pembaruan parameter, pembaruan kebijakan, dll. Ini menunjukkan bagaimana menyimpan hak awal untuk menghitung keuntungan. Fungsi G dapat menyimpan berbagai jenis data.
let init_eq = 0 //定义初始权益
if(!_G('init_eq')){ //如果没有储存_G('init_eq')返回null
init_eq = total_eq
_G('init_eq', total_eq) //由于没有储存,初始权益为当前权益,并在这里储存
}else{
init_eq = _G('init_eq') //如果储存,读取初始权益的值
}
Ketika mendapatkan data posisi, pasar, dan lain-lain melalui API, karena berbagai alasan, mungkin akan kembali sebagai kesalahan. Ini akan menyebabkan kebijakan kesalahan berhenti jika data tersebut dipanggil secara langsung, yang membutuhkan mekanisme toleransi kesalahan.
let pos = _C(exchange.GetPosition, pair)
let ticker_A = exchange.GetTicker(pair_a)
let ticker_B = exchange.GetTicker(pair_b)
if(!ticker_A || !ticker_B){
continue //如果数据不可用,就跳出这次循环
}
Fungsi seperti GetPosition, GetTicker, GetRecords dapat menambahkan parameter pasangan transaksi untuk mendapatkan data yang sesuai tanpa harus mengatur pasangan transaksi yang terikat exchange, yang sangat memudahkan kompatibilitas multi-transaksi terhadap kebijakan.https://www.fmz.com/digest-topic/10451◦ Tentu saja, Anda perlu host terbaru untuk mendukung, jika host Anda terlalu tua, Anda perlu upgrade.
Jika Anda masih belum mengerti, Anda dapat menyelesaikan pertanyaan Anda dengan menggunakan dokumentasi API FMZ, alat debugging, dan alat dialog AI yang umum digunakan di pasar.
function GetPosition(pair){
let pos = _C(exchange.GetPosition, pair)
if(pos.length == 0){ //返回为空代表没有持仓
return {amount:0, price:0, profit:0}
}else if(pos.length > 1){ //策略要设置为单向持仓模式
throw '不支持双向持仓'
}else{ //为了方便,多仓持仓量为正,空仓持仓量为负
return {amount:pos[0].Type == 0 ? pos[0].Amount : -pos[0].Amount, price:pos[0].Price, profit:pos[0].Profit}
}
}
function GetRatio(){
let kline_A = exchange.GetRecords(Pair_A+"_"+Quote+".swap", 60*60, N) //小时K线
let kline_B = exchange.GetRecords(Pair_B+"_"+Quote+".swap", 60*60, N)
let total = 0
for(let i= Math.min(kline_A.length,kline_B.length)-1; i >= 0; i--){ //反过来计算,避免K线长度不够
total += kline_A[i].Close / kline_B[i].Close
}
return total / Math.min(kline_A.length,kline_B.length)
}
function GetAccount(){
let account = _C(exchange.GetAccount)
let total_eq = 0
if(exchange.GetName == 'Futures_OKCoin'){ //由于这里的API并不兼容,目前仅OKX期货交易所获取到总权益
total_eq = account.Info.data[0].totalEq //其他交易所的宗权益Info中也包含,可以自己对着交易所API文档找找
}else{
total_eq = account.Balance //其它交易所暂时使用可用余额,会造成计算收益错误,但不影响策略使用
}
let init_eq = 0
if(!_G('init_eq')){
init_eq = total_eq
_G('init_eq', total_eq)
}else{
init_eq = _G('init_eq')
}
LogProfit(total_eq - init_eq)
return total_eq
}
function main(){
var precision = exchange.GetMarkets() //这里获取精度
var last_get_ratio_time = Date.now()
var ratio = GetRatio()
var total_eq = GetAccount()
while(true){
let start_loop_time = Date.now()
if(Date.now() - last_get_ratio_time > 10*60*1000){ //每10分钟更新下均价和账户信息
ratio = GetRatio()
total_eq = GetAccount()
last_get_ratio_time = Date.now()
}
let pair_a = Pair_A+"_"+Quote+".swap" //交易对的设置形如BTC_USDT.swap
let pair_b = Pair_B+"_"+Quote+".swap"
let CtVal_a = "CtVal" in precision[pair_a] ? precision[pair_a].CtVal : 1 //有的交易所用张来代表数量,如一张代表0.01个币,因此需要换算下
let CtVal_b = "CtVal" in precision[pair_b] ? precision[pair_b].CtVal : 1 //不含这个字段的不用张
let position_A = GetPosition(pair_a)
let position_B = GetPosition(pair_b)
let ticker_A = exchange.GetTicker(pair_a)
let ticker_B = exchange.GetTicker(pair_b)
if(!ticker_A || !ticker_B){ //如果返回数据异常,跳出这次循环
continue
}
let diff = (ticker_A.Last / ticker_B.Last - ratio) / ratio //计算偏离的比例
let aim_value = - Trade_Value * diff / Pct //目标持有的仓位
let id_A = null
let id_B = null
//以下是具体的开仓逻辑
if( -aim_value + position_A.amount*CtVal_a*ticker_A.Last > Trade_Value && position_A.amount*CtVal_a*ticker_A.Last > -Max_Value){
id_A = exchange.CreateOrder(pair_a, "sell", ticker_A.Buy, _N(Ice_Value / (ticker_A.Buy * CtVal_a), precision[pair_a].AmountPrecision))
}
if( -aim_value - position_B.amount*CtVal_b*ticker_B.Last > Trade_Value && position_B.amount*CtVal_b*ticker_B.Last < Max_Value){
id_B = exchange.CreateOrder(pair_b, "buy", ticker_B.Sell, _N(Ice_Value / (ticker_B.Sell * CtVal_b), precision[pair_b].AmountPrecision))
}
if( aim_value - position_A.amount*CtVal_a*ticker_A.Last > Trade_Value && position_A.amount*CtVal_a*ticker_A.Last < Max_Value){
id_A = exchange.CreateOrder(pair_a, "buy", ticker_A.Sell, _N(Ice_Value / (ticker_A.Sell * CtVal_a), precision[pair_a].AmountPrecision))
}
if( aim_value + position_B.amount*CtVal_b*ticker_B.Last > Trade_Value && position_B.amount*CtVal_b*ticker_B.Last > -Max_Value){
id_B = exchange.CreateOrder(pair_b, "sell", ticker_B.Buy, _N(Ice_Value / (ticker_B.Buy * CtVal_b), precision[pair_b].AmountPrecision))
}
if(id_A){
exchange.CancelOrder(id_A) //这里直接撤销
}
if(id_B){
exchange.CancelOrder(id_B)
}
let table = {
type: "table",
title: "交易信息",
cols: ["初始权益", "当前权益", Pair_A+"仓位", Pair_B+"仓位", Pair_A+"持仓价", Pair_B+"持仓价", Pair_A+"收益", Pair_B+"收益", Pair_A+"价格", Pair_B+"价格", "当前比价", "平均比价", "偏离均价", "循环延时"],
rows: [[_N(_G('init_eq'),2), _N(total_eq,2), _N(position_A.amount*CtVal_a*ticker_A.Last, 1), _N(position_B.amount*CtVal_b*ticker_B.Last,1),
_N(position_A.price, precision[pair_a].PircePrecision), _N(position_B.price, precision[pair_b].PircePrecision),
_N(position_A.profit, 1), _N(position_B.profit, 1), ticker_A.Last, ticker_B.Last,
_N(ticker_A.Last / ticker_B.Last,6), _N(ratio, 6), _N(diff, 4), (Date.now() - start_loop_time)+"ms"
]]
}
LogStatus("`" + JSON.stringify(table) + "`") //这个函数会在机器人页面显示包含以上信息的表格
Sleep(Interval * 1000) //休眠时间为ms
}
}
SidianshuiaHello, check back exchange.GetMarkets (() hanya mendapatkan data dari satu pasangan transaksi, bagaimana pengaturan dapat mendapatkan data dari beberapa, misalnya dua pasangan transaksi.
77924998Apakah ada versi python?
Kacang 888/upload/asset/21c799a2c667c13fcb0bd.png Sedikit berkerut
Penemu Kuantitas - Mimpi KecilUntuk saat ini, GetMarkets belum didukung oleh retest.
ChaoZhangUpgrade ke host terbaru