Saya menulis artikel pada tahun 2020 memperkenalkan strategi frekuensi tinggi,https://www.fmz.com/bbs-topic/9750. Walaupun ia mendapat perhatian yang agak sedikit, ia tidak sangat mendalam. Lebih dari dua tahun telah berlalu sejak itu, dan pasaran telah berubah. Selepas artikel itu diterbitkan, strategi frekuensi tinggi saya boleh membuat keuntungan stabil untuk masa yang lama, tetapi secara beransur-ansur, keuntungan menurun dan bahkan berhenti pada satu ketika. Dalam beberapa bulan kebelakangan ini saya telah menghabiskan beberapa usaha untuk memperbaharui, dan sekarang ia masih boleh membuat beberapa keuntungan. Dalam artikel ini, saya akan memberikan pengenalan yang lebih terperinci kepada idea strategi frekuensi tinggi saya dan beberapa kod yang dipermudah sebagai titik permulaan untuk perbincangan komunikasi; dan maklum balas dialu-alukan.
Rekod diskaun, mengambil Binance sebagai contoh, ia mempunyai diskaun pembuat sebanyak 0.0005% pada masa ini. Jika jumlah transaksi harian adalah 100 juta U, diskaun akan menjadi 5000 U. Sudah tentu, yuran pengambil masih berdasarkan kadar VIP, jadi jika strategi tidak memerlukan pengambil, tahap VIP mempunyai sedikit kesan pada strategi frekuensi tinggi. Pertukaran peringkat yang berbeza umumnya mempunyai kadar diskaun yang berbeza dan memerlukan mengekalkan jumlah transaksi yang tinggi. Pada zaman awal ketika beberapa pasaran mata wang turun naik sangat, terdapat keuntungan walaupun tanpa diskaun.
Kelajuan. Sebab mengapa strategi frekuensi tinggi dipanggil frekuensi tinggi adalah kerana mereka sangat cepat. Bergabung dengan pelayan colo pertukaran, mendapatkan latensi terendah dan sambungan paling stabil juga menjadi salah satu syarat untuk persaingan dalaman. Masa penggunaan dalaman strategi harus seminimal mungkin, dan artikel ini akan memperkenalkan kerangka websocket yang saya gunakan, yang menggunakan pelaksanaan serentak.
Pasaran yang sesuai. Perdagangan frekuensi tinggi dikenali sebagai mutiara perdagangan kuantitatif, dan banyak peniaga programatik telah mencubanya, tetapi kebanyakan orang berhenti kerana mereka tidak dapat membuat keuntungan dan tidak dapat mencari arah untuk peningkatan. Alasan utama adalah bahawa mereka memilih pasaran perdagangan yang salah. Pada peringkat awal pembangunan strategi, pasaran yang agak mudah harus dipilih untuk membuat keuntungan dalam perdagangan supaya terdapat keuntungan dan maklum balas untuk peningkatan, yang kondusif untuk kemajuan strategi. Jika anda mula bersaing di pasaran yang paling kompetitif dengan banyak lawan berpotensi, tidak kira seberapa keras anda cuba, anda akan kehilangan wang dan menyerah. Saya mengesyorkan pasangan perdagangan kontrak kekal baru yang disenaraikan apabila tidak banyak pesaing, terutama yang mempunyai jumlah transaksi yang agak besar; ini adalah ketika keuntungan paling mudah. BTC dan ETH mempunyai jumlah transaksi terbesar dan paling aktif dalam transaksi tetapi juga paling sukar untuk bertahan.
Berhadapan dengan persaingan. Pasaran untuk mana-mana transaksi sentiasa berubah, dan tiada strategi perdagangan yang boleh bertahan selama-lamanya, terutamanya dalam perdagangan frekuensi tinggi. Masuk ke pasaran ini bermakna bersaing dengan peniaga yang paling pintar dan paling rajin secara langsung. Dalam pasaran permainan jumlah sifar, semakin banyak anda memperoleh, semakin sedikit yang lain akan memperoleh. Semakin lambat anda memasuki, semakin tinggi kesukaran; mereka yang sudah berada di pasaran juga mesti terus meningkat. 3-4 tahun yang lalu mungkin merupakan peluang terbaik; baru-baru ini, aktiviti keseluruhan di pasaran mata wang digital telah menurun, menjadikannya sangat sukar bagi pendatang baru untuk memulakan perdagangan frekuensi tinggi sekarang.
Terdapat pelbagai strategi frekuensi tinggi:
Kod berikut adalah berdasarkan rangka kerja asas kontrak kekal Binance, terutamanya melanggan kedalaman websocket, data pasaran perdagangan aliran pesanan kedalaman, dan maklumat kedudukan. Oleh kerana data pasaran dan maklumat akaun dilabel secara berasingan, adalah perlu untuk menggunakan read ((-1) secara berterusan untuk menentukan sama ada maklumat terkini telah diperoleh. Di sini EventLoop ((1000) digunakan untuk mengelakkan gelung tanpa akhir langsung dan mengurangkan beban sistem. EventLoop ((1000) akan menyekat sehingga terdapat wss atau kembalinya tugas serentak dengan masa tamat 1000ms.
var datastream = null
var tickerstream = null
var update_listenKey_time = 0
function ConncetWss(){
if (Date.now() - update_listenKey_time < 50*60*1000) {
return
}
if(datastream || tickerstream){
datastream.close()
tickerstream.close()
}
//Need APIKEY
let req = HttpQuery(Base+'/fapi/v1/listenKey', {method: 'POST',data: ''}, null, 'X-MBX-APIKEY:' + APIKEY)
let listenKey = JSON.parse(req).listenKey
datastream = Dial("wss://fstream.binance.com/ws/" + listenKey + '|reconnect=true', 60)
//Symbols are the set trading pairs
let trade_symbols_string = Symbols.toLowerCase().split(',')
let wss_url = "wss://fstream.binance.com/stream?streams="+trade_symbols_string.join(Quote.toLowerCase()+"@aggTrade/")+Quote.toLowerCase()+"@aggTrade/"+trade_symbols_string.join(Quote.toLowerCase()+"@depth20@100ms/")+Quote.toLowerCase()+"@depth20@100ms"
tickerstream = Dial(wss_url+"|reconnect=true", 60)
update_listenKey_time = Date.now()
}
function ReadWss(){
let data = datastream.read(-1)
let ticker = tickerstream.read(-1)
while(data){
data = JSON.parse(data)
if (data.e == 'ACCOUNT_UPDATE') {
updateWsPosition(data)
}
if (data.e == 'ORDER_TRADE_UPDATE'){
updateWsOrder(data)
}
data = datastream.read(-1)
}
while(ticker){
ticker = JSON.parse(ticker).data
if(ticker.e == 'aggTrade'){
updateWsTrades(ticker)
}
if(ticker.e == 'depthUpdate'){
updateWsDepth(ticker)
}
ticker = tickerstream.read(-1)
}
makerOrder()
}
function main() {
while(true){
ConncetWss()
ReadWss()
worker()
updateStatus()
EventLoop(1000)
}
}
Seperti yang disebutkan sebelumnya, strategi frekuensi tinggi saya memerlukan penentuan trend sebelum melaksanakan pembelian dan penjualan. Trend jangka pendek terutamanya dinilai berdasarkan data transaksi tik-by-tick, iaitu aggTrade dalam langganan, yang merangkumi arah transaksi, harga, kuantiti, masa transaksi, dll. Membeli dan menjual terutamanya merujuk kepada kedalaman dan jumlah perdagangan. Berikut adalah pengenalan terperinci mengenai penunjuk yang perlu dibimbangkan; kebanyakannya dibahagikan kepada kumpulan membeli dan menjual dan dikira secara dinamik dalam jangka masa tertentu. Jendela masa strategi saya adalah dalam tempoh 10 saat.
//bull represents short-term bullish, bear represents short-term bearish
let bull = last_sell_price > avg_sell_price && last_buy_price > avg_buy_price &&
avg_buy_amount / avg_buy_time > avg_sell_amount / avg_sell_time;
let bear = last_sell_price < avg_sell_price && last_buy_price < avg_buy_price &&
avg_buy_amount / avg_buy_time < avg_sell_amount / avg_sell_time;
Jika harga jual terkini lebih tinggi daripada harga jualan purata, harga beli terkini lebih tinggi daripada harga pembelian purata, dan nilai pesanan pembelian selang masa tetap lebih besar daripada nilai pesanan jualan, maka ia dinilai bullish jangka pendek. Sebaliknya, ia bearish.
function updatePrice(depth, bid_amount, ask_amount) {
let buy_price = 0
let sell_price = 0
let acc_bid_amount = 0
let acc_ask_amount = 0
for (let i = 0; i < Math.min(depth.asks.length, depth.bids.length); i++) {
acc_bid_amount += parseFloat(depth.bids[i][1])
acc_ask_amount += parseFloat(depth.asks[i][1])
if (acc_bid_amount > bid_amount && buy_price == 0) {
buy_price = parseFloat(depth.bids[i][0]) + tick_size
}
if (acc_ask_amount > ask_amount && sell_price == 0) {
sell_price = parseFloat(depth.asks[i][0]) - tick_size
}
if (buy_price > 0 && sell_price > 0) {
break
}
}
return [buy_price, sell_price]
}
Di sini, kita masih mengamalkan pendekatan lama, mengulangi kedalaman yang diperlukan. Dengan mengandaikan bahawa 10 syiling boleh didagangkan dalam 1 saat, tanpa mempertimbangkan pesanan terhad baru, harga jualan ditetapkan di kedudukan di mana 10 syiling dibeli. Saiz tertentu jendela masa perlu ditetapkan oleh anda sendiri.
let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time
Ratio mewakili perkadaran tetap, yang bermaksud bahawa kuantiti pesanan beli adalah perkadaran tetap daripada kuantiti pesanan jual baru-baru ini.
if(bull && (sell_price-buy_price) > N * avg_diff) {
trade('buy', buy_price, buy_amount)
}else if(position.amount < 0){
trade('buy', buy_price, -position.amount)
}
if(bear && (sell_price-buy_price) > N * avg_diff) {
trade('sell', sell_price, sell_amount)
}else if(position.amount > 0){
trade('sell', sell_price, position.amount)
}
Di mana avg_diff adalah perbezaan harga pasaran purata, dan pesanan beli hanya akan diletakkan apabila spread tawaran-tanyakan lebih besar daripada kelipatan tertentu dari nilai ini dan ia bullish. Jika memegang kedudukan pendek, ia juga akan menutup kedudukan untuk mengelakkan memegang untuk tempoh yang panjang. Perintah boleh diletakkan sebagai pesanan pembuat tunggal untuk memastikan mereka dilaksanakan. Di samping itu, ID pesanan tersuai Binance
var tasks = []
var jobs = []
function worker(){
let new_jobs = []
for(let i=0; i<tasks.length; i++){
let task = tasks[i]
jobs.push(exchange.Go.apply(this, task.param))
}
_.each(jobs, function(t){
let ret = t.wait(-1)
if(ret === undefined){
new_jobs.push(t)//Unreturned tasks will continue to wait next time
}
})
jobs = new_jobs
tasks = []
}
/*
Write the required task parameters in param
tasks.push({'type':'order','param': ["IO", "api", "POST","/fapi/v1/order",
"symbol="+symbol+Quote+"&side="+side+"&type=LIMIT&timeInForce=GTX&quantity="+
amount+"&price="+price+"&newClientOrderId=" + UUID() +"×tamp="+Date.now()]})
*/