
[TOC] Tôi đã viết một bài viết vào năm 2020 giới thiệu các chiến lược tần suất cao, https://www.fmz.com/digest-topic/6228. Mặc dù nhận được nhiều sự chú ý nhưng bài viết không được viết sâu sắc. Hơn hai năm đã trôi qua và thị trường đã thay đổi. Sau khi bài viết đó được xuất bản, chiến lược tần suất cao của tôi đã có thể kiếm được tiền ổn định trong một thời gian dài, nhưng lợi nhuận dầ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 nhiều công sức để cải tạo và hiện đã có thể kiếm được một số tiền. Bài viết này sẽ giới thiệu ý tưởng của tôi về các chiến lược tần suất cao và một số mã đơn giản hóa chi tiết hơn, có thể dùng làm điểm khởi đầu cho thảo luận. Mọi người đều được chào đón để giao tiếp và đưa ra phản hồi.
Đối với các tài khoản được hoàn tiền, lấy Binance làm ví dụ, khoản hoàn tiền cho người tạo hiện tại là 0,5% của 100.000. Nếu khối lượng giao dịch hàng ngày là 100 triệu U, khoản hoàn tiền sẽ là 5.000 U. Tất nhiên, phí người nhận lệnh vẫn dựa trên mức VIP, vì vậy nếu chiến lược không yêu cầu nhận lệnh thì mức VIP sẽ có tác động nhỏ đến các chiến lược tần suất cao. Nhìn chung, các cấp độ giao dịch khác nhau có tỷ lệ hoàn tiền khác nhau và yêu cầu duy trì khối lượng giao dịch cao hơn. Ngày xưa, khi thị trường một số loại tiền tệ biến động mạnh, vẫn có lợi nhuận ngay cả khi không có chiết khấu. Với sự gia tăng lưu thông nội bộ, chiết khấu chiếm tỷ lệ lớn trong lợi nhuận và thậm chí hoàn toàn dựa vào chiết khấu. Các nhà giao dịch tần suất cao theo đuổi Giá cao nhất.
tốc độ. Lý do tại sao chiến lược tần số cao được gọi là tần số cao là vì nó rất nhanh. Việc tham gia vào máy chủ colo 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 để lưu thông nội bộ. Thời gian tiêu thụ nội bộ của chiến lược cũng phải càng thấp càng tốt. Bài viết này sẽ giới thiệu về khuôn khổ websocket mà tôi sử dụng, sử dụng thực thi đồng thời.
Thị trường phù hợp. Giao dịch tần suất cao được biết đến như là viên ngọc của giao dịch định lượng. Tôi tin rằng nhiều nhà giao dịch theo chương trình đã thử, nhưng hầu hết mọi người có lẽ dừng lại vì họ không kiếm được tiền và không thể tìm ra cách để cải thiện. Lý do chính có lẽ là mà họ đang tìm kiếm theo cách sai lầm. Thị trường giao dịch. Ở giai đoạn đầu của một chiến lược, người ta nên tìm kiếm những thị trường tương đối dễ kiếm tiền bằng cách giao dịch, để có được lợi nhuận và phản hồi về những cải tiến, điều này sẽ có lợi cho sự phát triển của chiến lược. Nếu bạn bắt đầu ở thị trường cạnh tranh nhất và phải cạnh tranh với nhiều đối thủ tiềm năng, bạn sẽ mất tiền dù có cố gắng thế nào và bạn sẽ không thể trụ vững được nữa. Tôi đề xuất các cặp giao dịch hợp đồng vĩnh viễn mới được niêm yết. Vào thời điểm này, không có nhiều đối thủ cạnh tranh, đặc biệt là khi khối lượng giao dịch tương đối lớn. Đây là thời điểm dễ kiếm tiền nhất. BTC và ETH có khối lượng giao dịch lớn nhất và hoạt động tích cực nhất, nhưng chúng cũng khó tồn tại nhất.
Đối mặt trực diện với đối thủ cạnh tranh. Bất kỳ thị trường giao dịch nào cũng đang thay đổi năng động. Không có chiến lược giao dịch nào có thể hiệu quả mãi mãi. Điều này thậm chí còn rõ ràng hơn trong giao dịch tần suất cao. Tham gia thị trường này có nghĩa là trực tiếp cạnh tranh với một nhóm các nhà giao dịch thông minh và siêng năng nhất. Trong một thị trường tổng bằng không, bạn kiếm được càng nhiều thì người khác kiếm được càng ít. Càng vào sau thì càng khó khăn. Những người đã có mặt trên thị trường cũng phải tiếp tục cải thiện vì họ có thể bị loại bất cứ lúc nào. Ba hoặc bốn năm trước hẳn là cơ hội tốt nhất. Gần đây, hoạt động chung của thị trường tiền kỹ thuật số đã giảm và hiện tại rất khó để những người mới tham gia giao dịch tần suất cao.
Có nhiều loại chiến lược tần số cao
Chiến lược của tôi là sự kết hợp giữa xu hướng và nhà tạo lập thị trường. Trước tiên, tôi xác định xu hướng, sau đó đặt lệnh và ngay lập tức đặt lệnh bán sau khi giao dịch hoàn tất. Tôi không nắm giữ vị thế hàng tồn kho. Mã chiến lược được giới thiệu bên dưới.
Đoạn mã sau đây dựa trên kiến trúc cơ bản của hợp đồng vĩnh viễn Binance và chủ yếu đăng ký thông tin thị trường, giao dịch theo luồng lệnh độ sâu websocket và thông tin vị thế. Vì thông tin thị trường và thông tin tài khoản được đăng ký riêng biệt nên cần phải sử dụng read(-1) liên tục để xác định xem thông tin mới nhất có được lấy hay không. EventLoop(1000) được sử dụng ở đây để tránh vòng lặp vô hạn trực tiếp và giảm gánh nặng cho hệ thống. EventLoop(1000) sẽ bị chặn cho đến khi wss hoặc tác vụ đồng thời trả về, với thời gian chờ là 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()
}
//需要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是设定的交易对
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 đó, chiến lược tần suất 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 của từng giao dịch, 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, v.v. Các tham chiếu chính để mua và bán là độ sâu và khối lượng giao dịch. Sau đây là phần giới thiệu chi tiết về các chỉ số cần chú ý. Hầu hết các chỉ số được chia thành hai nhóm: mua và bán, và được tính động trong một khoảng thời gian nhất định. Khoảng thời gian của chiến lược của tôi là trong vòng 10 giây.
//bull代表短期看涨,bear短期看跌
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 mới nhất lớn hơn giá bán trung bình, giá mua mới nhất lớn hơn giá mua trung bình và giá trị lệnh mua theo khoảng thời gian cố định lớn hơn giá trị lệnh bán thì được đánh giá là tăng giá ngắn hạn. . Ngược lại, nó mang tính bi quan.
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 ta vẫn áp dụng ý tưởng cũ và lặp lại độ sâu đến số lượng cần thiết. Ở đây chúng ta giả định rằng lệnh mua 10 coin có thể được thực hiện trong vòng 1 giây. Không xét đến các lệnh chờ mới, giá lệnh bán được đặt ở vị trí mà lệnh mua 10 đồng tiền sẽ trúng. Bạn cần tự thiết lập kích thước khung thời gian cụ thể.
let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time
Tỷ lệ là viết tắt của Fixed Ratio, nghĩa là số lượng lệnh mua là tỷ lệ cố định so với số lượng lệnh bán gần đây nhất. Chiến lược này có thể điều chỉnh quy mô lệnh một cách thích ứng dựa trên 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 số đó, avg_diff là chênh lệch giá thị trường trung bình. Lệnh mua sẽ chỉ được đặt khi chênh lệch giá mua-bán lớn hơn một bội số nhất định của giá trị này và xu hướng là tăng giá. Nếu bạn giữ lệnh bán khống, vị thế cũng sẽ đóng cửa vào thời điểm này để tránh việc giữ đơn hàng trong thời gian dài. Bạn có thể đặt lệnh chỉ tạo để đảm bảo lệnh đang chờ được thực hiện. Và bạn có thể sử dụng ID lệnh tùy chỉnh của Binance để không phải chờ lệnh được trả lại.
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)//未返回的任务下次继续等待
}
})
jobs = new_jobs
tasks = []
}
/*
需要的任务参数写在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()]})
*/