Recently, I read babyquant's (Analysis of Arbitrage Strategies in the Cryptocurrency Space) and wrote about various arbitrage strategies. I will also discuss my own cryptocurrency arbitrage strategy that I ran in practice for about 2 years.
The reason for making this public is twofold: first, I no longer run these strategies, so writing about them allows me to summarize my experiences; second, the logic behind arbitrage strategies is not mysterious. This field competes on execution ability, which is essentially coding skills, particularly in high-frequency trading. The trading frequency may not be very high, but the response time must be fast. When volatility arises, one must enter the market immediately. Additionally, there is a need for in-depth understanding of the subject, as competition in arbitrage is quite fierce, and the competition will only intensify in the future. One must also possess a certain ability to raise funds, as the profit margins from arbitrage are limited. Having sufficient capital can lead to more substantial profits, at least enough to surpass a regular job's income, making it worthwhile to pursue full-time. Of course, joining an institutional team is also a viable option.
The fact that these strategies are public doesn’t mean they are completely ineffective now; they might still be effective, just with possibly lower efficiency. This means the risks are high but the profits might not be much, along with the fierce competition mentioned earlier, with more and more people participating, and team collaborations.
More importantly, compared to other strategies, pure arbitrage is not very attractive, although it may be relatively stable. Ultimately, strategies that have risk exposure can make more money, although the risks are also greater; profit and loss come from the same source. In the past, when the market was moving, although I was also making money, compared to others with holding strategies, they were feasting, while I was just managing to sip a bit of soup. Of course, when holding strategy directions went wrong, I also didn’t get hit, so I could only comfort myself like this.
Let me first talk about one of my most stable and profitable arbitrage strategies, commonly known as 'brick-moving'.
Brick-moving arbitrage is the most suitable strategy for the crypto space. Because these coins are digital, they all exist on the blockchain; the big coin and that big coin are completely homogeneous (if they were heterogeneous, they would become NFTs). This makes it naturally suitable for brick-moving arbitrage between different exchanges. Unlike other physical commodities, like agricultural products, even though they may have the same name, such as wheat, they come with transportation hassles and have to factor in storage costs; furthermore, wheat from different countries or regions may differ in protein content or other qualities, leading to different pricing and making them prone to reverse arbitrage.
With more uncontrollable factors, the risk increases.
The so-called 'brick-moving' refers to the fact that there are many exchanges in the crypto space, and the prices of coins on each exchange are actually the result of the competition among accounts within that exchange, leading to differences between exchanges. Ordinary users feel that the prices on each exchange are almost synchronized; this is the contribution of arbitrage strategies, and of course, market maker strategies also play a role.
In short, arbitrageurs are the biggest contributors to flattening the price differences between exchanges.
Specific strategies
The strategy logic is very simple.
It was so simple that back when I didn't even know the English words for buying and selling in trading were bid and ask, I could still make money with the code I wrote. I remember searching everywhere in the API documentation for buy and sell and finding nothing; I still vividly remember that I could only find bid, ask, long, and short. So, working in different industries is like crossing mountains. One of the barriers is the 'jargon' that each industry comes with.
The general logic of the strategy is that if the selling price at one exchange is lower than the buying price at another exchange, then the conditions are satisfied. This indicates that someone is selling at a low price while another is buying at a high price. You buy the agreed quantity of orders at the first exchange and then sell it at the other; it's that simple! If you're aggressive, you can eat all of it and then slowly sell the remainder.
If you take on both sides as takers and only do soft brick-moving (that is, both exchanges have funds or coins without actually buying the coins and moving them to sell at another exchange—this is too slow; doing it this way is a lost cause), there is almost no holding position, and profits come immediately. There is no simpler or more stable strategy than this.
However, in reality, things are definitely not that easy. The gap between knowing and actually doing is often a chasm. Practical operations often encounter unexpected situations.
Next, I'll talk about the issues I faced back then and the responses I had, which might inspire those who come after.
Problem one: no price difference.
The response to this problem is very simple: just wait. Don't act recklessly.
Later on, I added a bit of maker logic, actively waiting on the order book, making it similar to being a market maker, which made the logic a bit more complex.
In short, you have to wait. If you don't want to wait, then you have to change strategies as mentioned above. The crypto space previously had many opportunities, with sufficient volatility; there were almost a few small opportunities each day and a few large ones each week. Being a taker means waiting for opportunities to arise.
What you really need to worry about is the rain; do you have enough buckets to collect the water, and are they big enough? But you will only understand this once you truly experience it.
Problem two: can't grab orders.
This is the biggest problem.
Your code monitors the sell and buy price differences for profit, but they are fleeting. The usual situation is either someone cancels their order or someone gets ahead of you. If you haven't placed an order, that's fine; you're just a spectator. Or if you placed an order but it didn't execute and is hanging on the order book, that's also fine; at worst, you just cancel the order. (Back then, there were no IOC, FOK algorithms, which would cancel orders immediately if not executed; we only had ordinary limit and market orders, especially at smaller exchanges). The trouble is if one leg executes; we can discuss that later.
Response to not being able to grab orders.
Because it's arbitrage between two (or even multiple) exchanges, the reaction speed of a single exchange isn't that important. Back then, there weren't facilities like colo, let alone FPGA killers; things were relatively fair, and arbitrage algorithms were extremely simple with no speed requirements. So the key lies in the overall speed between the two exchanges.
The servers of mainstream exchanges back then were mainly located in Tokyo (B-Exchange), Hong Kong (OK), and also in Dublin, Frankfurt, Switzerland, and so on in Europe.
So you can't possibly run your real trading code on a server in North America.
The image below is a simple diagram of undersea cables. You can look for the approximate locations where your arbitrage exchanges can reach each other quickly. This is particularly important for cross-continental arbitrage, as a signal takes hundreds of milliseconds to make a single run along the cable.
The trick here is to first consider exchanges with lower liquidity, which are smaller exchanges. It's best if you have your code on the same cloud server provider and in the same region. This way, you can quickly grab the orders at the small exchange and then go to a liquidity-rich exchange to sell.
Lead-lag; act first on the lagging side. This is the so-called take-slow-mover strategy, eating the orders that haven't realized that prices are changing rapidly.
One of the key points of brick-moving arbitrage is that it's best to connect a large exchange with a small one, as this makes it easier to profit. The competition between two large exchanges has long been fierce.
Another tip is to ignore everything and set up your code on both sides, and possibly even in the middle; this increases the chances of grabbing orders. In the end, you might find that you are actually competing with your own trading bot, which is ideal.
Back in those days, as long as your code was asynchronous and you used websocket to get market data, it was fast enough to get to the table and compete.
Problem three: only grabbing one leg.
What’s feared is that one leg has executed, while the other is still hanging, leaving you exposed. In these situations, you often face adverse selection. That is, when prices are rising, you sold, and no one bought on the other side to hedge; when prices plummet, congratulations, you've successfully got the goods, but your sell order hasn’t executed.
At this point, it depends on your strategy. If it's coin-to-coin arbitrage, meaning both quote and base are coins, such as the ETH/BTC trading pair, then it's not a big problem since they are all coins, and the price fluctuations are generally not too large.
However, if it’s USDT, the price fluctuations may be larger. At this point, you can wait and see, or you can acknowledge the loss and exit, or check to see if you’re in a dangerous zone outside the Bollinger Bands on the hourly chart; it’s best to stop losses early.
I previously had a 6-second holding limit; generally, if a single leg exceeds 6 seconds, I would close the position. Fortunately, the win rate is usually quite high, so such situations are limited.
In summary, it depends on your risk appetite. Arbitrage can sometimes result in losses, although those who do it well can avoid this most of the time.
Problem four: full positions at one exchange.
In a significant market, you sell everything on the slower side for USDT, while on the side that drops sharply at a lower price, you should have received the corresponding coins. This isn't truly a full position because the number of coins and money in your hands hasn't changed; only the exchanges they are on have changed, and the quantity has increased a little.
If the market continues and price differences persist, you essentially only have mutual coin transfers, which is the true 'brick-moving'. Of course, you can also wait for a rebound. Sometimes when prices rebound, the price difference can invert, allowing for another trading wave. Going back and forth, if you have many coins, you could potentially earn 1% in a day or even more because switching between coin markets increases capital utilization. Naturally, your strategy must also be well-designed; this is one of the challenges. For instance, using cross-exchange triangular arbitrage to softly transfer coins without losing money.
By the time I reached the later stages of my arbitrage, there were more arbitrageurs, and such opportunities to be fully invested only occurred during significant market movements. With more people, more capital, and liquidity increased, especially after institutions like SBF entered the market and controlled major opportunities, many Degen traders switched to other strategies.
Now there are more and more market makers, arbitrageurs, and institutions entering, along with an increase in options trading, making it really hard to see an epic market like 312 again. That day was truly a celebration, still vivid in my memory.
Other techniques
I remember the largest single order I had was around 1.5 million (calculated in RMB).
I designed two modes: one with supervision and one without.
It's simple: when there's no supervision, like at night while you're sleeping, keep a low profile, place smaller orders, and limit your trades; slowly eat the orders. Make sure that you complete one trade before executing the next. Control your position well. If you miss an opportunity, then it's gone. Moreover, you need to control the total position across all trading pairs and manage overall account risk.
When there's supervision, you can switch to the cannon mode, swallowing the orders on the low liquidity side in one go, or even directly taking large orders, then slowly releasing at a few exchanges with good liquidity. If there’s a sudden change, intervene manually.
I remember when the (Silicon Valley) American TV series was released, I used the music that the Canadian programmer used in it as a reminder for large orders, and every time I heard it, I was very excited and rushed to check the situation to avoid any mistakes.
Another technique for dealing with competition is to monopolize some trading pairs at a small exchange. The transaction fees for spot trading are generally around 0.1%, so one in and one out would be around 0.2% (with a bit of coin transfer cost; if the capital is small, that needs to be factored in too). Therefore, you need at least a price difference of 0.2% to have profit.
If the trading pair at this small exchange, such as EOS/ETH, only has you trading, you can wait for the price difference to reach 0.3% before acting, or even a little higher. Of course, if it gets too high, that's not good, as it might attract competitors. Market participants are constantly scanning and monitoring the price differences across exchanges. If they see a trading pair with such a high price difference, they will come and try to get in. However, if they see the price difference is not large and quickly disappears, competitors will know someone has claimed it, and it would require more effort to get involved, potentially leading to a hard confrontation, and they might not come.
If there really is a headstrong competitor trying to stir things up, then you have to respond.
It doesn't matter if the maker comes; this strategy only works with takers, and the maker's strategy complements it perfectly. If they are a novice, with a slow code reaction, you can just eat their orders.
How to respond? It's to eat the orders right when the market starts; previously, it was at 0.3%, and when competitors come in, they might jump in at around 0.25%. If you miss a few orders in a row, you'll realize someone else is doing the same thing. At this point, you’ll have to sacrifice profits; you might have to jump in at 0.2% even though everyone is still making a profit. This is because with high trading volume, transaction fees are discounted, so everyone will continuously test down to around the 0.1% range. At this point, you have to make a decisive move, foregoing profit, even to the point of losing a little to enter, perhaps around 0.05%.
This is a psychological game. Because the opponent is new here, their mentality is to just come and try, swinging a bat to see if they hit anything; if they see they’re not making money, they will quickly withdraw. As I mentioned about this type of arbitrage, if you want to do well, you need to deploy servers in multiple locations and fund the operations. You also need dedicated monitoring. In other words, there are costs involved. Once it stops being profitable, newcomers will pull out. Generally, this lasts for about a week. The other party may report to their boss that this trading pair isn't making money, and they may shift to other areas. When faced with tough competition, you would have to spend half a month’s profit to outlast them; newcomers generally can't hold out.
I have also been treated this way when I went elsewhere. Others will not hesitate to fight you to defend their territory. So everyone understands the logic.
Finally, when the competitor leaves, you just keep raising the price and only act when it's at a 0.3% difference. This is actually similar to the strategies of those vendors in offline markets. After all, it's all trading; no one is inherently superior.
Thus, this line of work can be quite exhausting, with everyone constantly guarding against each other. Sometimes there are specialized trading bots that harvest arbitrage strategies, prompting you to trade. This complicates things, and I won't elaborate further here. In short, there are a lot of things to be wary of, and you must remain vigilant. Monitoring the market is common; if you don't check the market for a few days, review the order book changes, modify configuration parameters, or even the source code, your profits will decline.
In short, it's all hard-earned money.
Potential risks
Arbitrage strategies aren't entirely without risk. The risk of the strategy itself isn't too high. If you get stuck on one leg, just exit promptly; at worst, you'll earn a little less.
Risk refers to structural risks in the crypto space. One is the exchange running away, shutting down, and being unable to withdraw coins. For instance, if CZ were to be apprehended by the FBI/CIA, you might not be able to get your coins. The second risk is if USDT or other coins suddenly crash.
Back then, the head effect between exchanges wasn't very pronounced, and smaller exchanges still had people trading. Unlike now, after experiencing a few exchanges running away and the FTX fund misappropriation crash, everyone only trades at the top exchanges.
Therefore, ordinary arbitrage isn't necessarily a good strategy. If you know other trading methods, such as CTA, they are generally stronger than arbitrage, with higher capital utilization. Those adept at arbitrage have mostly transitioned to high-frequency market making and trend trading.
Finally
It truly was a good era back then, with so many opportunities. Sometimes when the market moved, you could earn arbitrage just by placing an order. In really big markets, you could continuously transfer coins between exchanges due to ongoing price differences. I heard there were even people manually moving bricks to Korea for arbitrage, but I missed that market.
My initial version of the code was written in JavaScript. The testing code was mainly just a few dozen lines. I thought I would spend a few days and some capital to test it out, and if it made money, I would continue; otherwise, I would quickly move on to something else. I didn’t expect to start making money on the first day of testing. I adjusted the initial code in just a few days; I thought as long as I made enough to cover my lunch on the first day, I would continue because I only had a few dozen dollars in capital. In the end, I started making enough for lunch and coffee, and then I couldn't stop, continuously modifying the code, updating the model, and leveling up.
Unfortunately, my arbitrage was so smooth that I had no motivation to upgrade to other more profitable strategies. Mainly, other strategies have drawdowns, and I'm used to arbitrage, so I really can't stand the situation where I earn money and then lose it back. My mindset can't accept it, so I haven't succeeded. Moreover, other profitable strategies are actually more difficult. In contrast, those who didn't make money from arbitrage early on, like some Degen traders, successfully transitioned to high-frequency or CTA strategies, catching up with the previous bull market and hitting a wave of success.
In short, the logic of arbitrage is simple; it doesn't require great intelligence, just a collection of many small cleverness and ideas, and doing it better than others with more dedication, focusing on execution. But to do real trading well, with exposure and positions, one must understand the essence of trading: strategy design, backtesting, and execution in real-time; every step cannot be omitted.
That's all for now.
One tree cannot form a boat; a lonely sail won't go far! In the crypto circle, if you don't have a good circle and don't have first-hand news from the crypto space, then I suggest you follow Lao Wang, who will help you profit without any cost; welcome to join the team!!!