Tôi đã viết một bài báo vào năm 2020 giới thiệu các chiến lược tần số cao,https://www.fmz.com/bbs-topic/9750. Mặc dù nó nhận được khá nhiều sự chú ý, nhưng nó không phải là rất sâu sắc. Hơn hai năm đã trôi qua kể từ đó, và thị trường đã thay đổi. Sau khi bài báo đó được xuất bản, chiến lược tần số cao của tôi có thể tạo ra lợi nhuận ổn định trong một thời gian dài, nhưng dần dần, lợi nhuận giảm và thậm chí dừng lại ở một thời điểm. Trong những tháng gần đây tôi đã dành một số nỗ lực để cải tiến nó, và bây giờ nó vẫn có thể tạo ra một số lợi nhuận. Trong bài viết này, tôi sẽ cung cấp một giới thiệu chi tiết hơn về ý tưởng chiến lược tần số cao của tôi và một số mã đơn giản như một điểm khởi đầu cho các cuộc thảo luận; và phản hồi được hoan nghênh.
Binance có mức giảm giá cho các tài khoản giảm giá, ví dụ như Binance, hiện có mức giảm giá cho người tạo 0,0005%. Nếu số tiền giao dịch hàng ngày là 100 triệu U, mức giảm giá sẽ là 5000 U. Tất nhiên, phí người nhận vẫn dựa trên tỷ lệ VIP, vì vậy nếu chiến lược không yêu cầu người nhận, mức VIP có ít tác động đến các chiến lược tần suất cao. Các mức độ giao dịch khác nhau thường có tỷ lệ giảm giá khác nhau và yêu cầu duy trì số tiền giao dịch cao. Trong thời gian đầu khi một số thị trường tiền tệ biến động rất nhiều, thậm chí còn có lợi nhuận mà không cần giảm giá. Khi cạnh tranh tăng cường, giảm giá chiếm tỷ lệ lợi nhuận lớn hơn hoặc thậm chí chỉ dựa vào chúng; các nhà giao dịch tần suất cao theo đuổi phí cấp cao.
Tốc độ. Lý do tại sao các chiến lược tần số cao được gọi là tần số cao là vì chúng rất nhanh. Tham gia máy chủ màu của sàn giao dịch, có được độ trễ thấp nhất và kết nối ổn định nhất cũng đã trở thành một trong những điều kiện cho cạnh tranh nội bộ. Thời gian tiêu thụ nội bộ của chiến lược nên càng ít càng tốt, và bài viết này sẽ giới thiệu khung websocket mà tôi sử dụng, áp dụng thực thi đồng thời.
Thị trường phù hợp. Giao dịch tần số cao được gọi là ngọc trai của giao dịch định lượng, và nhiều nhà giao dịch theo chương trình đã thử nó, nhưng hầu hết mọi người dừng lại vì họ không thể kiếm lợi nhuận và không thể tìm ra một hướng để cải thiện. Lý do chính là họ đã chọn sai thị trường giao dịch. Trong giai đoạn đầu phát triển chiến lược, nên chọn các thị trường tương đối dễ dàng để kiếm lợi nhuận trong giao dịch để có lợi nhuận và phản hồi để cải thiện, điều này có lợi cho sự tiến bộ của chiến lược. Nếu bạn bắt đầu cạnh tranh trong thị trường cạnh tranh nhất với nhiều đối thủ tiềm năng, bất kể bạn cố gắng khó khăn đến mức nào, bạn sẽ mất tiền và bỏ cuộc. Tôi khuyên bạn nên liệt kê các cặp giao dịch hợp đồng vĩnh cửu mới khi không có nhiều đối thủ cạnh tranh, đặc biệt là những đối thủ giao dịch tương đối lớn; đây là khi kiếm lợi nhuận dễ nhất. BTC và ETH có số lượng giao dịch lớn nhất và hoạt động nhiều nhất nhưng cũng khó tồn tại.
Đối mặt với sự cạnh tranh. Thị trường cho bất kỳ giao dịch nào đều đang thay đổi liên tục, và không có chiến lược giao dịch nào có thể tồn tại mãi mãi, đặc biệt là trong giao dịch tần số cao. Nhập vào thị trường này có nghĩa là cạnh tranh trực tiếp với các nhà giao dịch thông minh và siêng năng nhất. Trong thị trường trò chơi tổng bằng không, bạn càng kiếm nhiều, người khác sẽ càng kiếm ít. Bạn càng vào muộn, khó khăn càng cao; những người đã có mặt trên thị trường cũng phải cải thiện liên tục. 3-4 năm trước đây có lẽ là cơ hội tốt nhất; gần đây, hoạt động tổng thể trên thị trường tiền kỹ thuật số đã giảm, khiến người mới bắt đầu giao dịch tần số cao rất khó khăn.
Có nhiều chiến lược tần số cao khác nhau:
Mã sau đây dựa trên khuôn khổ cơ bản của các hợp đồng vĩnh cửu Binance, chủ yếu đăng ký độ sâu websocket, dữ liệu thị trường giao dịch dòng lệnh độ sâu và thông tin vị trí. Vì dữ liệu thị trường và thông tin tài khoản được đăng ký riêng biệt, cần phải sử dụng read ((-1) liên tục để xác định liệu thông tin mới nhất đã được thu thập hay không. Ở đây EventLoop ((1000) được sử dụng để tránh các vòng vô tận trực tiếp và giảm tải hệ thống. EventLoop ((1000) sẽ chặn cho đến khi có wss hoặc đồng thời trả về nhiệm vụ với thời gian hết 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)
}
}
Như đã đề cập trước đây, chiến lược tần số cao của tôi đòi hỏi phải xác định xu hướng trước khi thực hiện mua và bán. Xu hướng ngắn hạn chủ yếu được đánh giá dựa trên dữ liệu giao dịch tick-by-tick, tức là aggTrade trong đăng ký, bao gồm hướng giao dịch, giá, số lượng, thời gian giao dịch, vv. Mua và bán chủ yếu đề cập đến độ sâu và số lượng giao dịch. Sau đây là những giới thiệu chi tiết về các chỉ số cần quan tâm; hầu hết trong số đó được chia thành các nhóm mua và bán và được tính năng động trong một khoảng thời gian nhất định. Cửa sổ thời gian của chiến lược của tôi là trong vòng 10 giây.
//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;
Nếu giá bán gần nhất cao hơn giá bán trung bình, giá mua gần nhất cao hơn giá mua trung bình và giá trị lệnh mua khoảng thời gian cố định lớn hơn giá trị lệnh bán, thì nó được đánh giá là tăng ngắn hạn. Ngược lại, nó giảm.
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]
}
Ở đây, chúng tôi vẫn áp dụng phương pháp cũ, lặp lại đến độ sâu cần thiết. Giả sử rằng 10 đồng xu có thể được giao dịch trong 1 giây, mà không cần xem xét các đơn đặt hàng đang chờ, giá bán được đặt tại vị trí mà 10 đồng xu được mua. Kích thước cụ thể của cửa sổ thời gian cần phải được đặt bởi chính bạn.
let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time
Tỷ lệ đại diện cho một tỷ lệ cố định, có nghĩa là số lượng đơn đặt hàng mua là một tỷ lệ cố định của số lượng đơn đặt hàng bán gần đây. Bằng cách này, chiến lược có thể điều chỉnh kích thước đơn đặt hàng thích nghi theo hoạt động mua và bán hiện tại.
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)
}
Trong đó avg_diff là chênh lệch giá thị trường trung bình, và lệnh mua sẽ chỉ được đặt khi chênh lệch giá thầu - mua lớn hơn một số lần số này và nó tăng. Nếu giữ một vị trí ngắn, nó cũng sẽ đóng vị trí để tránh giữ trong một thời gian dài. Các lệnh có thể được đặt như đơn đặt hàng chỉ có người thực hiện để đảm bảo chúng được thực hiện. Ngoài ra, ID lệnh tùy chỉnh của 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()]})
*/