High-frequency market maker strategy

High liquidity and there is no commission fee or very low

The principle of this strategy is extremely simple. It can be understood as a high-frequency market-making strategy. almost anyone could write it.

Like all high frequency strategies, this strategy is based on orderbook. The following picture shows the order distribution of a typical bitcoin exchange.

Buying list BuyingPrice SellingPrice Selling list

You can see the buying order list on the left, the number of pending orders for different prices, and the selling order list on the right. if a person wants to buy Bitcoin and does not want to wait for a pending orders, he can directly send the market price order. This kind of order will automatic inquiry the next price no matter the price gap between the buy and sell price.

Image that he has send a large market order, which will impact the price, but the impact will not last forever, there are always people who want to do the opposite trading. Therefore, the price is most likely to recover to pervious price in a very short time.

It is the same mechanism that someone who want sell their coins.

Take the pending order in the picture above for example. If you want to buy 5 coins directly, the price will reach 10377. If someone wants to sell 5 coins directly, the price will reach 10348. This price gap is your profit margin.

The strategy will send a buying order at a price slightly higher than 10,348, such as 10,348.01(0.01 higher than 10348 is for the safety and make sure the order can be executed). At the same time, it will send a selling order at 10376.99(0.01 lesser than 10377, same reason as above).

If this situation happened, it will obviously earn the profit between this price gap. Although it will not perfectly happen every time, the probability of making profit is actually very high.

Someone may ask, what if the price gap is very narrow? Especially in those low liquidity markets

It also works, say if the price gap is less than 1.5, we can look the price gap opposite way, which doing it by add 10 at the selling price and minus 10 at the buying price, after we adding 10 to expand this small price gap, we get a new large price gap, then we keep the same trading method we discussed above, another round of price gap searching and trading.

More explanation:

What if I don't have enough money or coins?

This kind of situation is very common in the small-scale funds. which is that the money only enough for sending buying or selling order, this is not a big problem. In fact, you can join the logical judgment strategy of the currency-coins balance. but in the process of balancing the currency-coins, you may loss the probability of making profit.

脉冲, 频率, 心跳, 心脏, 曲线, 活, 线程, Seidener 线程, 健康, 疾病, 医疗, 生病

After all, every trading in this strategy is a probabilistic chance. I prefer to keep waiting for the buying or selling action complete. Thus, this also means that wasting potential trading chance.

How is the position managed?

At the beginning, they all bought and sold at full positions. Later, with the profit you earned, they will be divided into different groups according to different parameters, and they would not be completely trading at one time.

No stop loss?

This strategy has a complete logic for buying and selling pending orders. I don't think there is a need for a stop loss (which can be discussed), you can image an account’s burst as a stop lost (which means that you can’t put too much money in at one time)

How to adjust the strategy for making coins?

The parameters are symmetrical so far, for example, the selling order list of 8 coins upwards, and the buying order list of 8 coins downwards, let’s make it slightly unbalanced, the upward change to the selling order list of 15 coins makes the coin-selling action harder to executed. Also, a greater chance to buy it back at a lower price.

This will earn coins. The opposite way is earning money. In fact, the strategy is so effective, in the long run, both coins and money are increasing.

How to deal with floating losses?

A single transaction will have a loss for sure. Such as the price rises after the selling, the price of the coin falls after the buying. Such floating loss does not need to be dealt with, because this is a high frequency trading strategy that the order-sending is very frequent. it will have executed thousands of times every day. Floating losses are normal, as long as the probability of making profit is large.

How to prevent the “black swan” situation?

Cryptocurrency has a lot of black swan situation, sometimes the price will suddenly drop down, there is no chance of selling at all. This situation does not have to worry too much, because the “black swan” time often brings high volatility, and this strategy is specific designed to earn this part of profit, the loss can also be earned back very soon.

Also note that this strategy is only related to the current depth of pending order list, does not care about historical market and its own historical transactions, this strategy does not have the concept of a single loss, in fact, a single winning rate is very high.

Code explanation:

var floatAmountBuy = 20;      set the buying price’s lowest range to 20 
var floatAmountSell = 20;     set the selling price’s highest range to 20 
var diffPrice = 3;             set the minimum price gap to 3
var Interval = 3000;           set the interval time to 3 seconds

This function is used to cancel any uncompleted order and any pending order in case of any other situation out of the strategy. Also, we used a for loop to check if current account has any order before the strategy starts. Here is an example of using our API function GetOrder, for more information, please see our API documents.
function CancelPendingOrders() {
    var orders = _C(exchange.GetOrders);
    for (var j = 0; j < orders.length; j++) {
        exchange.CancelOrder(orders[j].Id, orders[j]);}
We use the bid price function GetPrice() for getting the order depth information, pay attention to the different order depth information lengths of different platforms, if you have traversed all the orders, there is still no information that you need (many 0.01 grid orders will be this case), then use GetPrice ('Buy') to get the buying price.

function GetPrice(Type, depth) {
    var amountBids = 0;              Declared variable
var amountAsks = 0;

Calculate the buying price and get the depth of the buying price list.
    if(Type == "Buy"){                  if loop to determine the buying price
        for(var i=0;i<20;i++){        for loop to cycle the depth of the order list
            amountBids += depth.Bids[i].Amount;      self-adding to reach the 20 maximum border 
            if (amountBids > floatAmountBuy){       determine whether the cycle is gathering enough depth
                return depth.Bids[i].Price + 0.01;   return the price and also add 0.01
    if(Type == "Sell"){                      same as above
        for(var j=0; j<20; j++){
            amountAsks += depth.Asks[j].Amount;
            if (amountAsks > floatAmountSell){
                return depth.Asks[j].Price - 0.01;    return the price and also minus 0.01
    return depth.Asks[0].Price     If you traverse the full depth and still do not meet the demand, you return a price to avoid program bugs. 

The main function onTick() will checking the K-line frequently. The cycle time set here is 3 seconds
function onTick() {
    var depth = _C(exchange.GetDepth);     
    var buyPrice = GetPrice("Buy", depth);          
var sellPrice = GetPrice("Sell", depth);
Diffprice is the default price gap, if the current price gap is less or equal than the default price gap, it will start to look the price gap opposite way, which doing it by add 10 at the selling price and minus 10 at the buying price hang a relatively deeper price. Like we discussed above.
    if ((sellPrice - buyPrice) <= diffPrice){
        buyPrice -= 10;
        sellPrice += 10;
    CancelPendingOrders();             Revoke all original orders, this just a safety Measure. In fact, there are often cases where the new price is the same as the pending order price.
    var account = _C(exchange.GetAccount);     Get account information to determine how much money and how many coins are currently in the account
    var amountBuy = _N((account.Balance / buyPrice-0.1), 2);       The amount of bitcoin that can be bought, _N() is the precision function of the FMZ platform, which will keep only two digits after the  decimal points.
    var amountSell = _N((account.Stocks), 2);        The amount of bitcoin that can be sold, noticed that there is no limit on the position, so, put a small Part of your fund in order to test it first.
    if (amountSell > 0.02) {          send the selling order. 0.02 means that some exchange house requires a minimum order amount. You need get this information from the exchange house.
        exchange.Sell(sellPrice, amountSell);
    if (amountBuy > 0.02) {           send the buying order.
        exchange.Buy(buyPrice, amountBuy);

function main() {
    while (true) {
        Sleep(Interval);     Sleep, go to the next cycle, sleep time was set to 3000 milliseconds(3 seconds)

The entire program is less more than 40 lines, it looks very simple and easy, as we mentioned at the beginning, this strategy is only can be used in those markets with high liquidity and low commission fee. Retail traders    provide the space for this high frequency trading strategy. Nowadays, the situation is different, it’s very hard to find a zero-commission fess and high liquidity exchanges house. But there is still a lot of room for quantitative strategy without high frequency.

Visit FMZ Quant to know more trading strategy

Leave a Reply

Your email address will not be published. Required fields are marked *