[TOC]
Tutorial ini mengandungi pengetahuan asas mengenai penulisan strategi, termasuk pengenalan API, backtest, carta dan banyak lagi. Selepas mempelajari tutorial asas ini, pengguna akan dapat menggunakan API asas dengan cekap dan menulis strategi bot yang stabil. Sebelum mempelajari tutorial, anda perlu belajar cara menggunakanMulakan Platform FMZ Quant.
Tutorial versi lama:FMZ Quant (FMZ.COM) Manual Penulisan Strategi 2.0 (Tutorial); terdapat banyak indeks jawatan dalam tutorial, yang disyorkan untuk dibaca.
Perdagangan program adalah menggunakan program untuk menyambung dengan platform melalui API untuk mencapai pembelian dan penjualan automatik atau fungsi lain mengikut niat reka bentuk.
Pada masa ini, terdapat dua protokol antara muka utama untuk platform mata wang kripto: REST dan Websocket. Setiap kali protokol REST memperoleh data, ia perlu diakses sekali. Mari kita ambil API platform simulasi
{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}
Dengan cara ini, anda dapat melihat bahawa dagangan yang mengikuti sebut harga pasaran terbaru pasangan dagangan BTC_USDT, akan berubah setiap kali ia diperbaharui;
Platform perdagangan FMZ Quant merangkumi antara muka REST setiap platform, dan menggunakan cara seragam untuk memanggil dan format data seragam, menjadikan penulisan strategi lebih mudah dan lebih umum. Websocket boleh dengan mudah disokong pada platform FMZ, yang akan diperkenalkan secara terperinci dalam tutorial seterusnya.
Kebanyakan bahagian dokumen API platform FMZ menggunakan JavaScript sebagai contoh, tetapi kerana pencapsulan, hampir tidak ada perbezaan antara bahasa yang berbeza, dan anda hanya perlu memberi perhatian kepada isu sintaks.
Oleh kerana Python mempunyai versi yang berbeza, ia boleh ditentukan pada awal program, seperti#!Python2
dan#!Python3
. Perhatikan bahawa JavaScript baru-baru ini telah menaik taraf sintaks ES6nya, dan mereka yang berminat boleh belajar mengenainya. Kod Python dan Javascript dengan fungsi yang sama ditunjukkan di bawah.
#python code
def main():
while True:
Log(exchange.GetAccount().Balance)
Sleep(2000)
#the corresponding Js code
function main(){
while(true){
Log(exchange.GetAccount().Balance)
Sleep(2000)
}
}
Platform FMZ Quant menyediakan
Program strategi adalah sama seperti program biasa, yang dijalankan dalam perintah kod. Bahagian khasnya adalah bahawa mesti ada fungsi
Fungsi lain dengan tindakan khas ditunjukkan seperti berikut:
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
while(true){
onTick()
Sleep(6000)
}
}
Dalam contoh sebelumnya, jika terdapat ralat dalam akses rangkaian, strategi boleh berhenti secara langsung. Jika anda mahu strategi yang serupa dengan permulaan semula automatik dan tidak akan berhenti, anda boleh menggunakan gelung utama
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//write the strategy logic here, and it will be called ever 6 seconds
}
function main(){
try{
while(true){
onTick()
Sleep(6000)
}
}catch(err){
Log(err)
}
}
Apabila memanggil mana-mana API yang berkaitan dengan platform, anda perlu menentukan platform dan pasangan dagangan.exchange
untuk mewakili objek ini. Sebagai contoh, apaexchange.GetTicker()
akan mendapat adalah ticker pasaran ini
Platform FMZ Quant menyokong penambahan beberapa objek exchanges
array untuk mewakili mereka, iaituexchanges[0]
danexchanges[1]
...dan seterusnya, mengikut susunan penjumlahan apabila bot dicipta.BTC_USDT
, bekas
Sudah tentu, jika kita mengoperasikan banyak pasangan dagangan, kaedah ini akan menjadi sangat tidak selesa.exchange.SetCurrency("BTC_USDT")
; maka, pasangan dagangan terikat kepadaexchange
menjadiBTC_USDT
, yang akan kekal sah sehingga panggilan seterusnya untuk menukar pasangan dagangan.Perhatikan bahawa backtest menyokong menukar pasangan dagangan baru-baru iniBerikut adalah contoh spesifik:
var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
for(var i=0;i<symbols.length;i++){
exchange.SetCurrency(symbols[i])
var ticker = exchange.GetTicker()
var amount = _N(buyValue/ticker.Sell, 3)
exchange.Buy(ticker.Sell, amount)
Sleep(1000)
}
}
Seperti yang disebutkan dalam contoh sebelumnya, antara muka pasaran umumnya adalah antara muka awam, yang boleh diakses oleh semua orang. Antara muka pasaran yang biasa adalah: GetTicker, GetDepth, GetRecords dan GetTrades. Kutipan pasaran adalah asas untuk strategi untuk membuat penilaian perdagangan. Kemudian, saya akan memperkenalkan mereka satu demi satu. Lebih baik mencuba mereka dalam
Setiap antara muka umumnya mempunyaiInfo
medan, yang mewakili rentetan data asal yang dikembalikan oleh platform, dan yang boleh digunakan untuk menambah maklumat tambahan. Ia perlu dianalisis sebelum digunakan. JavaScript menggunakanJSON.parse()
, manakala Python menggunakan perpustakaan json.Time
medan menunjukkan stempel masa permintaan, yang boleh digunakan untuk menilai kelewatan.
apabila menggunakan API dalam bot, akses mungkin gagal dan kembalinull
, dan Python mengembalikanNone
. Pada masa ini, data yang digunakan akan melaporkan ralat dan menyebabkan bot berhenti, jadi toleransi ralat adalah sangat penting. Tutorial ini akan memperkenalkan toleransi ralat khusus.
GetTicker mungkin antara muka yang paling biasa digunakan. Anda boleh mencari harga terakhir yang dilaksanakan, harga beli1 dan harga jual1, dan jumlah dagangan terkini. Sebelum meletakkan pesanan, harga yang dilaksanakan boleh ditentukan mengikut maklumat ticker. Contoh bot pulangan:{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}
.
function main() {
var ticker = exchange.GetTicker()
Log(ticker) //return ticker in the debugging tool, and you can see the specific result
Log('Last time executed price:',ticker.Last, 'Buy1 price:', ticker.Buy)
}
GetDepth untuk mendapatkan maklumat mendalam mengenai pesanan tertunda. Walaupun GetTicker termasuk harga beli 1 dan jual 1, jika anda ingin menyoal lebih dalam pesanan tertunda, anda boleh menggunakan antara muka ini, untuk memeriksa ke atas dan ke bawah 200 pesanan tertunda. Harga kejutan boleh dikira dengan menggunakan antara muka ini. Di bawah ini adalah hasil pulangan sebenar. Di antara mereka,
{
"Info":null,
"Asks":[
{"Price":5866.38,"Amount":0.068644},
{"Price":5866.39,"Amount":0.263985},
......
]
"Bids":[
{"Price":5865.13,"Amount":0.001898},
{"Price":5865,"Amount":0.085575},
......
],
"Time":1530241857399
}
Contoh menggunakan GetDepth untuk Ask & Bids:
function main() {
var depth = exchange.GetDepth()
Log('Buy 1 price:', depth.Bids[0].Price, 'Sell 1 price:', depth.Asks[0].Price)
}
GetRecords adalah salah satu antara muka yang paling biasa digunakan, boleh mengembalikan maklumat harga dalam tempoh yang panjang pada satu masa, yang merupakan asas pengiraan pelbagai penunjuk. Jika tempoh K-garis tidak ditentukan, ia bermakna menggunakan tempoh lalai apabila menambah bot. Panjang K-garis tidak boleh ditentukan, dan ia akan terus meningkat dari masa ke masa. Bilangan maksimum adalah 2000, dan dalam panggilan pertama jumlahnya adalah kira-kira 200 (platform yang berbeza mengembalikan nombor yang berbeza). K-garis terakhir adalah K-garis terkini, jadi data akan berubah apabila sebut harga pasaran berubah; K-garis pertama adalah data tertua.
exchange.SetMaxBarLen(Len)
boleh menetapkan bilangan K-line yang diperoleh untuk kali pertama (dikendalikan oleh beberapa platform), dan menetapkan bilangan maksimum K-line.Seperti:exchange.SetMaxBarLen(500)
.
GetRecords boleh menentukan tempoh seperti PERIOD_M1: 1 minit, PERIOD_M5: 5 minit, PERIOD_M15: 15 minit, PERIOD_M30: 30 minit, PERIOD_H1: 1 jam dan PERIOD_D1: 1 hari. Penggunaan khusus adalahexchange.GetRecords(PERIOD_M1)
. Selepas menaik taraf docker terkini, ia akan menyokong tempoh penyesuaian, yang hanya lulus nombor kedua tempoh sebagai parameter. penyesuaian peringkat minit akan disintesis mengikut garis K 1 minit, garis K di bawah 1 minit akan disintesis melalui GetTrades ((), dan niaga hadapan komoditi akan disintesis mengikut tik.Perhatikan bahawa terdapat juga pembolehubah huruf besar yang lain sepertiPERIOD_M1
Dalam tutorial. Mereka adalah pembolehubah global lalai FMZ. Jika anda berminat, anda boleh
Contoh data pulangan:
[
{"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
{"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
{"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
......
]
Contoh K-line berulang:
function main(){
var close = []
var records = exchange.GetRecords(PERIOD_H1)
Log('total bars: ', records.length)
for(var i=0;i<records.length;i++){
close.push(records[i].Close)
}
return close
}
GetTrades memperoleh data dagangan dalam jangka masa tertentu (bukan data dagangan anda sendiri), yang tidak disokong oleh beberapa platform.
Antara muka tersebut berkaitan dengan akaun, jadi mereka tidak boleh diperoleh secara langsung. Untuk mendapatkannya, anda perlu menggunakan API-KEY untuk menandatangani. Selepas pemprosesan latar belakang automatik terpadu platform FMZ, anda boleh menggunakannya secara langsung.
GetAccount untuk mendapatkan maklumat akaun. Sebagai salah satu antara muka yang paling biasa digunakan, ia perlu dipanggil sebelum meletakkan pesanan, untuk mengelakkan baki yang tidak mencukupi. Hasil pulangan adalah seperti:{"Stocks":0.38594816,"FrozenStocks":0,"Balance":542.858308,"FrozenBalance":0,"Info":{}}
Di mana BTC_USDT
,
Perhatikan bahawa hasil pulangan adalah hasil pasangan dagangan yang ditentukan, dan maklumat mata wang lain dalam akaun dagangan adalah dalam medan
Bot sentiasa mencetak nilai keseluruhan pasangan dagangan semasa:
function main(){
while(true){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
var price = ticker.Buy
var stocks = account.Stocks + account.FrozenStocks
var balance = account.Balance + account.FrozenBalance
var value = stocks*price + balance
Log('Account value is: ', value)
LogProfit(value)
Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
//when run in debug tool, add a break here
}
}
Membeli pesanan. kaedah panggilan termasukexchange.Buy(Price, Amount)
danexchange.Buy(Price, Amount, Msg)
, di mana null
akan dikembalikan jika pesanan tidak berjaya, yang digunakan untuk menyoal status pesanan.
Jika anda ingin meletakkan pesanan beli pada harga pasaran, exchange.Buy(-1, 0.5)
; jika pasangan dagangan adalahETH_BTC
, yang bermaksud bahawa membeli 0.5BTC ETH pada harga pasaran.
Sesetengah platform mempunyai keperluan ketepatan untuk harga dan jumlah yang boleh dikawal dengan fungsi ketepatan_N()
Untuk perdagangan niaga hadapan,
Contoh pembelian sekali mencapai harga yang sepadan:
function main(){
while(true){
var ticker = exchange.GetTicker()
var price = ticker.Sell
if(price >= 7000){
exchange.Buy(_N(price+5,2), 1, 'BTC-USDT')
break
}
Sleep(3000)//Sleep 3000ms
}
Log('done')
}
Perintah jual. Parameter adalah sama dengan exchange.Sell(-1, 0.2)
, bermaksud menjual 0.2ETH pada harga pasaran.
GetOrder mendapatkan maklumat pesanan berdasarkan id pesanan. Apabila antara muka biasa ini memanggil kaedahexchange.GetOrder(OrderId)
, Type
dan nilai sebenar pesananStatus
adalah nombor, yang mewakili makna yang berbeza, tetapi tidak kondusif untuk ingatan. FMZ menggunakan konstanta global untuk mewakili nilai ini.Status
nilai pesanan yang belum selesai adalah 0, yang bersamaan denganORDER_STATE_PENDING
. Semua konstanta global ini boleh dilihat dalam dokumen... Hasil pulangan:
{
"Id":125723661, //Order id
"Amount":0.01, //Order ammount
"Price":7000, //Order price
"DealAmount":0, //Executed amount
"AvgPrice":0, //executed average price
"Status":0, //0: not completely executed; 1: executed; 2: canceled
"Type":1,//Order type; 0: buy order; 1: sell order
"ContractType":"",//contract type, used in futures trading
"Info":{} //the platform returns the raw information
}
}
Strategi untuk membeli sejumlah mata wang tertentu:
function main(){
while(true){
var amount = exchange.GetAccount().Stocks
var ticker = exchange.GetTicker()
var id = null
if(5-amount>0.01){
id = exchange.Buy(ticker.Sell, Math.min(5-amount,0.2))
}else{
Log('Job completed')
return //return the main function, bot will stop
}
Sleep(3000) //Sleep 3000ms
if(id){
var status = exchange.GetOrder(id).Status
if(status == 0){ //Here you can aslo use "status == ORDER_STATE_PENDING" to judge
exchange.CancelOrder(id)
}
}
}
}
GetOrder mendapatkan senarai semua pesanan yang belum selesai dari pasangan dagangan semasa. Jika tidak ada pesanan yang belum selesai, kembalikan array kosong. Hasil khusus senarai pesanan, seperti
Contoh pembatalan semua pesanan pasangan dagangan semasa:
function CancelAll(){
var orders = exchange.GetOrders()
for(var i=0;i<orders.length;i++){
exchange.CancelOrder(orders[i].Id) // cancel order by orderID
}
}
function main(){
CancelAll()
while(true){
//do something
Sleep(10000)
}
}
Menurut ID pesanan, batalkan pesanan.exchange.CancelOrder(OrderId)
. Jika pembatalan berjaya, pulangkan
Untuk cryptocurrency, perdagangan niaga hadapan berbeza dengan perdagangan spot. Fungsi perdagangan spot di atas juga boleh digunakan untuk perdagangan niaga hadapan, dan perdagangan niaga hadapan tunggal mempunyai fungsinya sendiri. Sebelum menjalankan perdagangan program niaga hadapan cryptocurrency, anda harus biasa dengan operasi manual di laman web dan memahami konsep asas, seperti terbuka, dekat, bersilang, terpencil, leverage, keuntungan dan kerugian dekat, pendapatan terapung, margin dan konsep lain, serta formula pengiraan yang sesuai. Tutorial yang sesuai boleh didapati di pelbagai platform niaga hadapan, dan anda perlu mempelajarinya sendiri.
Kontrak kekal serupa dengan kontrak niaga hadapan, tetapi perbezaannya adalah bahawa tidak ada konsep memegang kedudukan panjang dan pendek pada masa yang sama.
Jika platform menyokong kedua-dua niaga hadapan dan spot, seperti niaga hadapan OKEX dan Huobi, anda perlu memilih
Langkah pertama dalam perdagangan niaga hadapan adalah untuk menetapkan kontrak yang akan diperdagangkan. Mengambil niaga hadapan OKEX sebagai contoh, pilih pasangan perdagangan BTC semasa membuat bot atau backtesting, dan anda juga perlu menetapkan kontrak mingguan, minggu depan atau suku dalam kod. Jika tidak ditetapkan, ia akan memintainvalid contract type
. Berbeza dengan pasangan dagangan spot, kontrak niaga hadapan sering menggunakan mata wang dagangan seperti BTC sebagai margin. Menambah BTC ke pasangan dagangan biasanya mewakili pasangan dagangan BTC_USD yang menggunakan BTC sebagai margin. Jika terdapat kontrak niaga hadapan dengan USDT sebagai margin, bot perlu dibuat untuk menambah pasangan dagangan BTC_USDT. Sebagai contoh, kontrak kekal seperti Binance OKEX Futures, dengan kedua-dua kontrak crypto-margined dan USDT-margined.Selepas menetapkan pasangan dagangan, anda juga perlu menetapkan jenis kontrak tertentu, seperti kekal, mingguan, minggu depan, dll. Selepas menetapkan kontrak, anda boleh melakukan operasi seperti mendapatkan sebut harga pasaran, membeli dan menjual.
Binance, OKEX, HuobiDM, dan lain-lain mempunyai kedua-dua kontrak margin crypto dan USDT, yang perlu dibezakan apabila menambah bot dan menetapkan kontrak. tetapan khusus adalah seperti berikut:
//OKEX Futures
exchange.SetContractType("swap") // set to perpetual contract
exchange.SetContractType("this_week") // set to weekly contract
exchange.SetContractType("next_week") // set to next week contract
exchange.SetContractType("quarter") // set to quarterly contract
//HuobiDM
exchange.SetContractType("this_week") // set to weekly contract
exchange.SetContractType("next_week") // set to next week contract
exchange.SetContractType("quarter") // set to quarterly contract
exchange.SetContractType("swap") // set to perpetual contract
//Binance Futures
exchange.SetContractType("swap") // set to perpetual contract, and notice that crypto-margined and USDT-margined contracts are all in the perpetual contract
exchange.SetContractType("quarter") // set to quarterly contract
exchange.SetContractType("next_quarter") // set to next quarter contract
//BitMEX
exchange.SetContractType("XBTUSD") // set to perpetual contract
exchange.SetContractType("XBTM19") // the contract settled at a specific time; for more details, please log in BitMEX to check each contract code
//GateIO
exchange.SetContractType("swap") // set to perpetual contract, and do not set the default as swap perpetual contract
//Deribit
exchange.SetContractType("BTC-27APR18") // the contract settled at a specific time; for more details, please log in Deribit to check out
Untuk mendapatkan senarai maklumat kedudukan semasa, niaga hadapan OKEX (OKCOIN) boleh lulus dalam parameter untuk menentukan jenis kontrak yang akan diperoleh.[]
, jika tidak ada kedudukan. Maklumat kedudukan dikembalikan seperti berikut. Terdapat banyak maklumat khusus, yang perlu dianalisis dalam kombinasi dengan pasangan dagangan.
Jenis data | Nama pembolehubah | Penerangan |
---|---|---|
objek | Maklumat | struktur mentah yang dikembalikan oleh platform |
nombor | MarginLevel | saiz leverage; OKCoin adalah 10 atau 20, dan posisi silang OK niaga hadapan mengembalikan 10 (tetap), untuk API mentah tidak menyokong |
nombor | Jumlah | Jumlah kedudukan; OKCoin menunjukkan kuantiti kontrak (jumlah bulat lebih daripada 1) |
nombor | Beku Jumlah | Jumlah kedudukan beku |
nombor | Harga | harga purata kedudukan |
nombor | Margin | margin beku |
nombor | Keuntungan | komoditi niaga hadapan: keuntungan dan kerugian kedudukan tanda ke pasaran; cryptocurrency: unit cryptocurrency: BTC / LTC, unit niaga hadapan tradisional: RMB (catatan:Dalam hal kedudukan silang niaga hadapan OKCoin, ia merujuk kepada keuntungan dan kerugian yang direalisasikan, bukan keuntungan dan kerugian kedudukan. Di bawah kedudukan yang terpencil, ia merujuk kepada keuntungan dan kerugian kedudukan.) |
const | Jenis | PD_LONG adalah kedudukan panjang (CTP menggunakan |
senar | Jenis Kontrak | Komoditi niaga hadapan adalah kod kontrak, dan stok adalah |
function main(){
exchange.SetContractType("this_week");
var position = exchange.GetPosition();
if(position.length>0){ //especially pay attention to judging the length of position before call, or an error will occur
Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type,"ContractType:", position[0].ContractType)
}
}
Pertama sekali, anda perlu menetapkan saiz leverage; kaedah panggilan:exchange.SetMarginLevel(10)
, di mana exchange.SetDirection(Direction)
, yang sepadan dengan kedudukan terbuka dan ditutup.Tidak seperti niaga hadapan, jika kontrak kekal tidak memegang konsep panjang dan pendek pada masa yang sama, iaitu satu kedudukan tidak dibenarkan.buy
dansell
Jika ia menyokong kedudukan dua hala, anda perlu menetapkanclosebuy
, closesell
.Hubungan khusus:
Operasi | SetDirection Parameter | Fungsi Penempatan Perintah |
---|---|---|
Posisi Long Buka | pertukaran.SetDirection (( |
pertukaran.Beli ((() |
Tutup Posisi Panjang | pertukaran.SetDirection (( |
pertukaran.Menjual ((() |
Posisi Pendek Terbuka | pertukaran.SetDirection (( |
pertukaran.Menjual ((() |
Tutup Posisi Pendek | pertukaran.SetDirection (( |
pertukaran.Beli ((() |
Akhirnya, terdapat kod khusus untuk kedudukan terbuka dan tertutup. Jumlah pesanan yang diletakkan berbeza dari platform ke platform. Sebagai contoh, niaga hadapan Huobi berdasarkan jumlah kontrak, dan satu kontrak adalah 100 dolar AS. Perhatikan bahawa uji balik niaga hadapan tidak menyokong pesanan pasaran.
function main(){
exchange.SetContractType("this_week") // for example, set OKEX futures to weekly contract
price = exchange.GetTicker().Last
exchange.SetMarginLevel(10) // set to 10 times of leverage
exchange.SetDirection("buy") // set the order type as buy long
exchange.Buy(price+10, 20) // set contract quantity as 20 orders
pos = exchange.GetPosition()
Log(pos)
Log(exchange.GetOrders()) // check out if there is any unfinished order
exchange.SetDirection("closebuy"); // if it is a perpetual contract, directly set exchange.SetDirection("sell")
exchange.Sell(price-10, 20)
}
Berikan contoh strategi khusus untuk kedudukan penutupan penuh seperti berikut:
function main(){
while(true){
var pos = exchange.GetPosition()
var ticker = exchange.GetTicekr()
if(!ticker){
Log('not able to obtain ticker')
return
}
if(!pos || pos.length == 0 ){
Log('no position')
return
}
for(var i=0;i<pos.length;i++){
if(pos[i].Type == PD_LONG){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closebuy')
exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
}
if(pos[i].Type == PD_SHORT){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closesell')
exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
}
}
var orders = exchange.Getorders()
Sleep(500)
for(var j=0;j<orders.length;j++){
if(orders[i].Status == ORDER_STATE_PENDING){
exchange.CancelOrder(orders[i].Id)
}
}
}
}
Perdagangan leverage cryptocurrency perlu beralih ke akaun leverage dalam kod, dan bahagian lain adalah sama dengan perdagangan spot.
Penggunaanexchange.IO("trade_margin") untuk beralih ke mod akaun leverage; meletakkan pesanan dan mendapatkan aset akaun akan mengakses antara muka platform leverage. Penggunaanexchange.IO("trade_normal") untuk beralih semula ke mod akaun biasa.
Platform yang disokong:
Perdagangan niaga hadapan komoditi dan perdagangan niaga hadapan cryptocurrency agak berbeza. Pertama sekali, masa perdagangan niaga hadapan komoditi sangat singkat, tetapi cryptocurrency diperdagangkan selama 24 jam; protokol niaga hadapan komoditi bukan REST API yang biasa digunakan; kekerapan perdagangan dan jumlah pesanan menunggu niaga hadapan komoditi terhad, tetapi yang cryptocurrency sangat longgar, dan sebagainya. Oleh itu, terdapat banyak perkara yang memerlukan perhatian khusus ketika berdagang niaga hadapan komoditi, dan disyorkan kepada mereka yang mempunyai pengalaman yang kaya dalam operasi manual. FMZ kini menyokong bot simulasi komoditi masa depan, dan anda boleh merujuk:https://www.fmz.com/bbs-topic/325Untuk menambah syarikat niaga hadapan komoditi:https://www.fmz.com/bbs-topic/371
Komoditi niaga hadapan telah melaksanakan pengawasan tembus pandang pada bulan Jun 2019; untuk program individu, pengguna individu perlu membuka akaun untuk memohon kod kebenaran untuk broker niaga hadapan (templat maklumat permohonan tertentu boleh dihantar ke kumpulan WeChat atau kumpulan QQ), yang biasanya mengambil masa 4-5 hari; prosedurnya agak rumit. Sebagai pembekal perdagangan berprogram, platform FMZ telah memohon kod kebenaran perisian dari pelbagai pembekal perkhidmatan niaga hadapan. Pengguna boleh menggunakannya secara langsung tanpa memohon. Apabila menambah broker niaga hadapan, cari
Oleh kerana kelebihan struktur platform FMZ Quant, pengguna juga boleh menambah beberapa akaun broker niaga hadapan, dan melaksanakan beberapa fungsi yang tidak dapat diselesaikan oleh perisian perdagangan program niaga hadapan komoditi lain, seperti sintesis tik frekuensi tinggi; anda boleh merujuk kepada:https://www.fmz.com/bbs-topic/1184
Pertama sekali, kerana ia bukan perdagangan 24 jam dan memerlukan operasi log masuk, adalah perlu untuk menilai status pautan sebelum perdagangan.exchange.IO("status")
adalahtrue
, yang menunjukkan sambungan yang berjaya ke platform. Jika API dipanggil apabila log masuk tidak berjaya, _C(exchange.SetContractType,"MA888")
, yang akan memastikan log masuk yang berjaya.
Kod perolehan dan perdagangan harga pasaran niaga hadapan komoditi adalah sama dengan niaga hadapan cryptocurrency. Di sini kita akan memperkenalkan perbezaan dan perkara yang perlu diperhatikan.
function main(){
_C(exchange.SetContractType,"MA888") //If you do not log in successfully, you cannot subscribe to the contract, so better to try again
while(true){
if(exchange.IO("status")){
var ticker = exchange.GetTicker()
Log("MA888 ticker:", ticker)
LogStatus(_D(), "Already connected with CTP !")//_D obtain event
} else {
LogStatus(_D(), "Not connected with CTP !")
Sleep(1000)
}
}
}
Adalah disyorkan untuk menggunakan perpustakaan niaga hadapan komoditi untuk perdagangan (yang akan diterangkan kemudian), kodnya akan sangat mudah pada masa ini, dan tidak perlu berurusan dengan butiran yang membosankan.https://www.fmz.com/strategy/57029
function main() {
// Use the CTA strategy framework of commodity futures library
$.CTA(Symbols, function(st) {
var r = st.records
var mp = st.position.amount
var symbol = st.symbol
/*
"r" represents K-line, "mp" indicates the position amount of the current variety; positive number means long position, negative number means short position, and 0 means no position; "symbol" is the variety name
if the return value is n:
n = 0 : full close positions (no matter now they are long or short)
n > 0 : if right now long positions are held, add n long positions; if now they are short positions, close n short posiitons; if n is over the position amount right now, reverse to open long positions
n < 0 : if right now short positions are held, add n short positions; if now they are long positions, close n long posiitons; if -n is over the position amount right now, reverse to open short positions
*/
if (r.length < SlowPeriod) {
return
}
var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod));
if (mp <= 0 && cross > ConfirmPeriod) {
Log(symbol, "Golden Cross Period", cross, "the moment position", mp);
return Lots * (mp < 0 ? 2 : 1)
} else if (mp >= 0 && cross < -ConfirmPeriod) {
Log(symbol, "Death Cross Period", cross, "the moment position", mp);
return -Lots * (mp > 0 ? 2 : 1)
}
});
}
Komoditi niaga hadapan menggunakan protokol CTP, dan semua sebut harga pasaran dan pelaksanaan pesanan hanya akan diberitahu selepas terdapat perubahan, sementara pertanyaan mengenai pesanan, akaun, dan kedudukan adalah pertanyaan aktif.GetTicker
, GetDepth
danGetRecords
, semua perlu menyimpan data cache untuk mendapatkan data terkini. Jika tidak ada data, ia akan menunggu sehingga terdapat data, jadi tidak perlu untuk strategi untuk menggunakan
Jika anda ingin mendapatkan data setiap kali anda mendapatkan sebut harga pasaran, walaupun ia adalah data lama, anda boleh beralih ke mod kemas kini segera sebut harga pasaranexchange.IO("mode", 0)
. Pada masa ini, strategi tidak boleh ditulis sebagai didorong peristiwa, dan peristiwa exchange.IO("mode", 1)
untuk beralih semula ke mod cache lalai.
Apabila menjalankan kontrak tunggal, gunakan mod lalai. Walau bagaimanapun, jika terdapat beberapa kontrak, mungkin salah satu kontrak tidak mengemas kini sebut harga pasaran, mengakibatkan penyumbatan antara muka untuk mendapatkan sebut harga pasaran, dan kemas kini sebut harga kontrak lain tidak dapat diperoleh. Untuk menyelesaikan masalah ini, mod kemas kini segera boleh digunakan, tetapi tidak mudah untuk menulis strategi frekuensi tinggi. Pada masa ini, anda boleh menggunakan mod push acara untuk mendapatkan dorongan pesanan dan sebut harga.exchange.IO("wait")
Jika pelbagai objek pertukaran ditambah, yang jarang berlaku dalam niaga hadapan komoditi, anda boleh menggunakanexchange.IO("wait_any")
, dan
Tekan perubahan pasaran:{Event:"tick", Index: platform index (in the order of the platforms added in the bot), Nano: event of nanosecond-level time, Symbol: contract name}
Arahan dorong:{Event:"order", Index:Exchange index, Nano:Event of nanosecond-level time, Order:Order information (same as GetOrder)}
Pada masa ini, struktur strategi boleh ditulis sebagai:
function on_tick(symbol){
Log("symbol update")
exchange.SetContractType(symbol)
Log(exchange.GetTicker())
}
function on_order(order){
Log("order update", order)
}
function main(){
while(true){
if(exchange.IO("status")){ //Judge the link status
exchange.IO("mode", 0)
_C(exchange.SetContractType, "MA888")//Subscribe to MA; only the subscription request for the first time is ture, and the later ones are program switches, which do not consume time
_C(exchange.SetContractType, "rb888")//Subscribe to rb
while(true){
var e = exchange.IO("wait")
if(e){
if(e.event == "tick"){
on_tick(e.Symbol)
}else if(e.event == "order"){
on_order(e.Order)
}
}
}
}else{
Sleep(10*1000)
}
}
}
Perhatikan juga perbezaan antara niaga hadapan komoditi dan platform mata wang kripto. Sebagai contoh,
exchange.IO("instrumen"): ia mengembalikan senarai semua kontrak di platform {nama kontrak: butiran} dalam bentuk kamus, dan hanya menyokong bot.exchange.IO("produk"): ia mengembalikan senarai semua item di platform {nama kontrak: butiran} dalam bentuk kamus, dan hanya menyokong bot.exchange.IO("langganan"): ia mengembalikan sebut harga pasaran langganan di platform dalam bentuk kamus, dan hanya menyokong bot.
PeraturanContractType
daripada CTP niaga hadapan tradisional merujuk kepada ID kontrak, yang sensitif huruf besar.exchange.SetContractType("au1506")
. Selepas kontrak ditetapkan dengan berjaya, ia akan mengembalikan maklumat terperinci kontrak, seperti jumlah pembelian minimum, yuran perkhidmatan, masa penghantaran, dll. Apabila melanggan beberapa kontrak, hanya kali pertama permintaan langganan sebenarnya dihantar, dan kemudian pasangan dagangan hanya ditukar pada tahap kod, yang tidak memerlukan masa. Kontrak berterusan utama adalah kod 888, seperti MA888, kontrak kadar berterusan adalah 000, seperti MA000; 888 dan 000 adalah perdagangan kontrak maya yang hanya menyokong backtest, dan bot sebenar hanya menyokong sebut harga pasaran.Walau bagaimanapun, Mylanguage boleh mengendalikan kontrak utama, dan program akan menukar kedudukan secara automatik, iaitu, menutup kedudukan bukan utama dan membuka kedudukan baru pada kedudukan utama.
Login yang gagal tidak boleh menetapkan kontrak, tetapi akan kembali dengan segera, jadi anda boleh cuba dengan
SetDirection
boleh mendapatkan empat parameter:buy, closebuy, sell, closesell
Futures komoditi mempunyai lebihclosebuy_today
danclosesell_today
, menunjukkan penutupan kedudukan semasa; lalai adalahclosebuy/ closesell
, yang menunjukkan penutupan kedudukan semalam; hanya jenis Bursa niaga hadapan Shanghai dibahagikan kepada penutupan hari ini dan penutupan semalam, yang mungkin mempengaruhi yuran perkhidmatan, jadi perlu memberi keutamaan kepada penutupan kedudukan semalam. Untuk niaga hadapan CTP tradisional, anda boleh menetapkan parameter kedua sebagai
Operasi | SetDirection Parameter | Fungsi Penempatan Perintah |
---|---|---|
Posisi Long Buka | pertukaran.SetDirection (( |
pertukaran.Beli ((() |
Tutup Posisi Panjang | pertukaran.SetDirection (( |
pertukaran.Menjual ((() |
Posisi Pendek Terbuka | pertukaran.SetDirection (( |
pertukaran.Menjual ((() |
Tutup Posisi Pendek | pertukaran.SetDirection (( |
pertukaran.Beli ((() |
Contoh berikut adalah fungsi kedudukan penutupan tertentu. Perhatikan bahawa contoh ini terlalu mudah. Anda juga harus mempertimbangkan sama ada dalam masa dagangan, bagaimana untuk mencuba semula pesanan yang menunggu jika tidak sepenuhnya diisi, berapa jumlah pesanan maksimum, sama ada kekerapan terlalu tinggi, dan sama ada ia adalah harga bergerak atau harga pasaran dan sebagainya. Hanya untuk rujukan,ia adalah pakej perpustakaan platform yang dicadangkan untuk membuka dan menutup kedudukan dalam bot sebenar:https://www.fmz.com/strategy/12961Terdapat pengenalan khusus di bahagian perpustakaan, dan ia juga disyorkan untuk mempelajari kod sumber perpustakaan.
function Cover(contractType, amount, slide) {
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType != contractType) {
continue;
}
var depth = _C(e.GetDepth);
if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
exchange.Sell(depth.Bids[0]-slide, amount, contractType, positions[i].Type == PD_LONG ? "Close today" : "Close yesterday", 'Bid', depth.Bids[0]);
} else {
exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
exchange.Buy(depth.Asks[0]+slide, amount, contractType, positions[i].Type == PD_SHORT ? "Close today" : "Close yesterday", 'Ask', depth.Asks[0]);
}
}
}
Komoditi niaga hadapan menyokong jenis pesanan tersuai (support untuk bot, tetapi tidak untuk backtest), yang ditentukan oleh akhiran, ditambah kepada
exchange.SetDirection("buy_ioc");
exchange.SetDirection("sell_gtd-20170111")
Sufiks khusus:
Secara lalai, antara muka yang dibuka dalam broker niaga hadapan komoditi adalah semua antara muka CTP. Jika diperlukan, mereka boleh digantikan oleh antara muka Esunny. Melalui penkapselan FMZ, kaedah panggilan adalah sama. Perbezaannya adalah bahawa akaun, pesanan, dan kedudukan semuanya berada dalam mod push, jadi docker akan mengekalkan data ini secara tempatan, dan akan kembali dengan serta-merta apabila antara muka yang sepadan dipanggil, tanpa benar-benar membuat permintaan.
Jenis pesanan khusus adalah:
Apabila log rekod log pada antara muka bot, dan menambah watak Log('Push to WeChat@')
.
Warna log juga boleh disesuaikan, sepertiLog('this is a log in red font #ff0000')
.
#ff0000
adalah hexadecimal warna RGB, menunjukkan bahawa semua fail log disimpan dalam pangkalan data SqLit bot dalam direktori di mana docker terletak, yang boleh dimuat turun dan dibuka dengan perisian pangkalan data, atau boleh digunakan untuk menyalin sandaran dan memulihkan (nama pangkalan data dan id bot adalah sama).
Ia merekod keuntungan, dan melukis lengkung keuntungan pada antara muka bot, yang boleh dikekalkan selepas bot dimulakan semula.LogProfit(1000)
. Perhatikan bahawa parameterLogProfit
tidak semestinya keuntungan, dan ia boleh menjadi mana-mana nombor dan perlu diisi sendiri.
Jika status bot, kerana log akan disimpan terlebih dahulu dan disegerakan secara berterusan, memerlukan maklumat hanya untuk paparan bukan untuk menyimpan, anda boleh menggunakanLogStatus
Parameter fungsiLogStatus
adalah rentetan, yang juga boleh digunakan untuk mewakili maklumat jadual.
Contoh jadual paparan kedudukan bot sebenar tertentu:
var table = {type: 'table', title: 'position information', cols: ['Column1', 'Column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]};
LogStatus('`' + JSON.stringify(table) + '`'); // After serialization, JSON will be added the character "'" on both sides, which is regarded as a comlpex messag format (now supporting tables)
LogStatus('The first line information\n`' + JSON.stringify(table) + '`\nthe third line information'); // the table information can be displayed in multiple lines
LogStatus('`' + JSON.stringify([table, table]) + '`'); // Multiple tables are supported to be displayed at the same time, which will be displayed in one group by TAB
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n