[TOC] I wrote an article in 2020 about high-frequency strategies, and I'm sure you've heard about them.https://www.fmz.com/digest-topic/6228Although it has received a lot of attention, it is not very in-depth. More than two years have passed, and the market has changed. After the publication of the article, my high-frequency strategy has been able to make a steady profit for a long time, but the slow profit has gradually decreased or even stopped.
The current maker returns a commission of one hundred thousandth of 5 if the daily trading volume is 100 million U, and the commission is 5000 U. Of course, the taker is still based on the VIP rate, so if the strategy does not need to be paid, the VIP level does not have much effect on the high-frequency strategy. Generally, different levels of exchanges have different return rates, which need to maintain a high transaction rate.
Speed. The high-frequency policy is called high-frequency because it is fast. Joining an exchange colo server to get the lowest latency and the most stable connection is also one of the conditions for the internal volume. The internal time of the policy should also be as low as possible.
The right market. High-frequency trading is known as the pearl of quantitative trading. I believe that many programmatic traders have tried, but most people should stop because they do not make money and can not find a way to improve, the main reason should be to find the wrong trading market. The initial stage of the strategy should find a relatively easy market to make money to trade, so that the advantage is also improved feedback, which favors the progress of the strategy.
Facing competition. Any trading market is dynamically changing, no trading strategy can be done once and for all, high-frequency trading is more obvious, entering this market is directly competing with a group of the smartest, most diligent traders. In a zero-sum market, you earn more than others earn less.
High-frequency strategies are divided into several types:
My strategy is a combination of trends and marketers, first determining trends, then listing orders, immediately listing and selling after the transaction, without holding stock positions, below is a combination of strategy code introduction.
The following code is an architecture based on the Binance Perpetual Contract, which mainly subscribes to the websocket deep-depth order flow trades market, and position position information. Since market and account information are separate subscriptions, it is necessary to constantly use read ((-1) to determine whether to get the latest information, here the EventLoop ((1000) is used, avoiding direct dead loops, reducing the system load.
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)
}
}
As mentioned earlier, my high-frequency strategy requires the trend to be judged and then to execute a trade. Judging short-term trends is mainly based on transaction-by-transaction data, i.e. aggTrade in the subscription, which includes transaction direction, price, quantity, transaction time, etc. The main reference for buying and selling is depth and volume.
//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;
If the latest sell price is higher than the average price of the sale order, the latest buy price is higher than the average price of the purchase order, and the value of the fixed interval buy is higher than the value of the sale order, then the short-term bullishness is judged.
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]
}
Here, the old idea is to iterate the depth to the required amount, assuming a payment of 10 coins can be made within 1s, without taking into account the new order, the selling price is set to the position of the 10 coins.
let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time
Ratio represents a fixed ratio, where the quantity ordered represents a fixed proportion of the number of orders sold most recently. This strategy adapts itself to the size of the order based on the current activity.
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)
}
where avg_diff is the difference in the average discount, only when the current order buy/sell difference is greater than a certain multiple of this value and the buyer will only pay when the buyer is looking, if the empty order is held, this time will also be flat, avoiding long-term receipts. The buyer can place only-maker orders, ensuring that the order is transacted.
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()]})
*/
mztcoinAsk Grasshopper, what is the logic of selling? Hang the order immediately after the transaction, do not hold the stock warehouse, that is, hang the order in the same for cycle, hang what price, do not transact?
mztcoinGod of the Grass
DANGOUGod of the Grass
77924998Which AWS server does Grasshopper use?
xukittyI'm not going to lie.
bwxiaokGrasshopper has a paid high-frequency program
My heart is still.Do you think this strategy works if you can make a copy?
Written by TradeManCalling Grasshopper, hoping to teach more, learn how to get into high-frequency trading
~ A wave in the wind ~Bully
fmzeroThe grass is greasy!
Orc quantifiedBully
The grassIt's too hard, it doesn't make much sense.