Adventures in Spot Market Making

9 min read Original article ↗

The Aster mania captured a lot of mindshare over the weekend, and while there were great returns for those max long, it presented a really interesting opportunity for anyone looking to get more into the weeds on market making. Since it caught my attention, I spent my weekend building out a strategy and trading it, turning over 250x my inventory and doing $6.5m+ volume all from around 500 lines of Python.

Before I started building trading systems, I was always on the lookout for articles exploring potential opportunities I could be trading. I want this to serve as an example of the types of dynamics you should look at as an individual seeking opportunities in the market. The trade isn't complex, the system is simple, but with a few important assumptions, there is money to be made.

Screenshot 2025-09-24 at 1

Part 1: The Opportunity

Most of my prior experience has been in secondary market making / arbitrage - having a price from a primary exchange (eg. Binance) and trading around that price on secondary exchanges (eg. Uniswap). This game is about speed and pricing. You remain delta neutral by hedging using the primary exchange, and are just aiming to profit on the price difference between the venues.

Aster presented a completely different opportunity. Here was a token that as of the day I started, only had a single spot listing on its own exchange, that was doing quite significant volume. I could tell from the start there would be a lot of demand, mostly due to CZ shilling and it being seen as Binances' indirect answer to Hyperliquid. I needed to figure out the best path forward other than just being long. Time to become a spot market marker.

Before I walk through the strategies I used, its worth noting the assumptions I made:

  • There would be no (or very little) professional market makers here. The mania started on Friday, not enough time for a professional shop to really setup & get compliance checks to trade on the DEX.
  • The token will probably pump. I should have a long bias even with my market making strategies. This also meant that I could simply not hedge any of my delta - keep it simple, stupid.
  • There will be a lot of uniformed retail demand hitting market orders, and I can provide a useful service to them.
  • I may get rugged and end up bagholding if I don’t manage my risk and inventory properly.

All of the techniques I am presenting here are not new. There is a great paper High Frequency Trading in a Limit Order Book which a lot of what I've implemented is loosely based off.

With that in mind, lets build a primary market making strategy.

Part 2: Integration and Naivety

I started this mission with a single goal in mind, get trading as fast as possible. First order of business is hook up to the exchange, be able to place limit orders, pull my current orders and cancel any open orders. Once this was done, the next thing was to figure out what pricing information I would need.

The aster docs were surprisingly decent, and they have a stream @bookTicker that gives you the best bid and offer streamed continuously. Sounds like a good place to start.

The initial strategy I deployed with was simply to quote uniformly some fixed width around the mid price. Looking at the market fees, I went with 50bps to start - which in hindsight was way too tight, but it was good to generate some volume and validate the strategy was working.

The overall strategy at this stage looked something like this: subscribe to the stream of prices, if the mid price changes by some amount, cancel all your orders, place new orders - probably the most simple strategy you could build. No inventory management, no sizing of orders, no skewing, don’t even bother checking when or if your orders get filled. Just plain old uniform quoting.

Armed with a tiny amount of capital, my bot set off and in the first two hours traded $4000 volume for a profit of $10.48 - coffee for the day sorted.

bbo = subscribe_bbo_stream()
new_mid = midprice(bbo)
if abs(new_mid - old_mid) > 0.001: // Check if mid has changed by more than 10bps
	cancel_open_orders()
	place_new_orders()

Part 3: Naive++

Not much changed for my second iteration, besides the realization that I was quoting way too tight (leaving money on the table), and that I should probably skew my quotes to be bullish. To do this, I changed the default quoting width from 50bps to 100bps, and skewed up 25 bps, meaning my bid was 75bps under mid, and my ask was 125bps above ask, so ideally I’ll be buying inventory as this thing trends upwards and offloading on any spikes.

Part 4: Let's get serious

So until now this strategy has been very basic and while its making some money and benefitting from the trend, it needs improving - it needs to account for its own inventory. With strategy 1 & 2, the strategy acquires way too much inventory on down ticks, and then offloads all of it as soon as things uptick, dampening any return it could be making both from the volatility and the trend. The strategy was also trading constant fixed sizes, rather than sizing based on its position and capital. This makes it harder to manage inventory but also easier for my bot to be spotted in the book by others.

Ideally the strategy would skew its quotes based on inventory so that as it builds up more inventory, the bid widens out to stop acquiring as much and the ask is more aggressive to attempt to offload. A simpler and quicker addition however was to size based on inventory. Instead of a fixed size quote, I started quoting with a fixed percent of the available inventory. If I had more aster inventory, my bid would be smaller than my ask and vice-versa.

I removed the positive skew, and simply started quoting 75bps around mid with variable sizes.

With this improved strategy looking good, I sized up.

I left the bot to do its thing. Even with some overnight downtime, this strategy alone returned 40% overnight, and another 20% in the first 3 hours of being back online in the morning thanks to massive increases in volatility and our newly improved inventory management system. Small improvements for a big increase in return!

Part 5: Endgame

Its now Sunday afternoon, and I was imagining the market would get more competitive come Monday. One final feature to add to the strategy was quote skewing based on inventory. To do this, I used a simple approach of measuring my inventory skew, by computing a skew value between -1 and 1 representing how much of my inventory is in one asset. All my inventory being in aster would give a value of 1, all stables would give -1.

inventory_skew = float(aster_val - stable_val) / float(aster_val + stable_val)

Next, I used this value to compute my offset. By adding a dampening factor and applying this offset to my default quoting width, I could compute an amount of bps to offset my bid/ask by.

offset_bps = dampening_factor * abs(inventory_skew) * default_width_bps

A dampening factor of 1 offsets the bid/ask by up to default_width, essentially being willing to bid/ask at the mid price and potentially crossing the spread, just to rebalance the inventory. Since I wasn’t going for as aggressive a strategy, I started with a dampening factor of 0.3. This means in practice the strategy should more slowly skew out of positions rather than being way too aggressive in a relatively low liquidity book.

For those who are more visual, the following is what the inventory sizing and skewing looks like when applied to the quotes being generated. For this example, imagine the strategy has more stablecoins then aster, so it is wanting to acquire more inventory. It does this by both shifting the bid and ask up, as well as bidding more size and offering less size.

inventory_skew

Performance

I’ve mentioned some numbers above, but how did this strategy actually perform in practice over 4 days of trading?

With a reasonable amount of starting capital, the gross return over was ~108%, trading 6.5m volume over 8990 trades. Screenshot 2025-09-23 at 2

As expected once the weekend mania calmed down and some more sophisticated players got involved, returns compressed, spreads tightened and there was less room for my slow python bot to make money.

Growing the strategy

So, where to from here? While the strategy is still operational almost a week later, its lifetime in its current form is close coming to an end. How would I take this strategy, and make it more competitive?

  1. Add a volatility measure to dynamically adjust the default quote width. Currently I am basing my width using manual inspection coupled with the strategies performance. A more rigorous approach based off historic volatility would allow the strategy to quote more efficiently - widening and tightening as market conditions change.
  2. Improve the mid price to include more microstructure signals. Currently the strategy only uses the best bid and ask - however last trades & top of book depth can be helpful to see where the book is moving. Using this info to skew the bid and ask could improve the quoting and reduce getting caught out.
  3. Include more data sources & signals into the quoting strategy. The aster market grew rapidly over the weekend, and most of the volume now occurs on Binance perps. Factoring in Binance perps as a leading venue would allow me to have a better understanding on the price dynamics.
  4. Rather than having a long view on Aster, now that the market has matured, adding a delta hedging component would allow the strategy to be fully delta-neutral and just profit off spread. As a bonus, this can also be used as a strategy to accumulate more points on the Aster DEX.

Adventures over

I want this post to serve as a reminder of two things. First, you don't need to build the perfect solution from the get-go. My initial strategy involved nothing complex, you just needed to be able to see the opportunity. Second, just get started! Even if you aren't making money, messing around in new launch markets like this and trying things out is how you learn. So give it a go.

If you got this far, thank you! If you have a strategy, idea, or just want to chat trading, feel free to reach out to me on X/Twitter.

Screenshot 2025-09-25 at 9