0bps

Strategy vault / Market making

Long Unlocking Strategy on FMEX Starting from 1 BTC Bullish Outlook

FMexUsage instructions for the long version of sorted mining code //The risk in the margin market is huge, and you may face it at any time100%Loss. Potentially unknownbug100%Loss, not responsible under any…

Author
gulishiduan_高频排序
Complexity
Advanced · 311 lines
Parameters
13

FMexUsage instructions for the long version of sorted mining code

//The risk in the margin market is huge, and you may face it at any time100%Loss. Potentially unknownbug100%Loss, not responsible under any circumstances. //(If you consider short positions or shocks, you can flexibly modify the parameters and code levels accordingly.) //Current maximum position(Turn calculation),Suggestion0.5-3Within multiples. If0.1B,3Leverage multiple, switch to position approximately2700,Maximum position3200,Adjust to10Times leverage,Then switch position to9000u,Maximum position10000u,Order quantity can be adjusted to300-500u //Live trading address:https://api.fmex.com Testnethttps://api.fmextest.net//Note: first hold manuallylong1-1000u. //(Contact WeChat:ying5737) Strategy Principle:

Strategy chart Images for reference only https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg

Handicap orders are randomly executed/This strategy tends to hold long positions by default/ Note: Hold position firstlong1u-1000u.// - Detect whether the existing order exceeds the limit, and if it exceeds the limit, cancel the order immediately/ - Check whether the transaction has formed a position. If it is greater than the position xxu, then reduce the position to below the established position./

Several pending order situations:

Global pending orders: In order to distinguish market makers' strategies, the remote sorting is specifically defined as pending orders. Parameters are adjustable, currently around 8 levels.

Market maker (near-end market depth order)): The maximum long position is customized. If it is greater than this position, the position will be reduced approximately every 6 seconds until it is less than the custom parameter.. The maximum short position is customized. If it is greater than this position, the position will be reduced approximately every 6 seconds until it is less than the custom parameter.. If the position is greater than the long position, the long position reduction strategy is initiated, and the pending orders are mainly short: short positions are executed. If the short position is greater than 1u, start the short position reduction strategy, and the pending order is long: it is very easy to execute multiple orders. Normal holding (orders are randomly executed due to market fluctuations))

**//The remarks in the parameters are for reference only. Gears can also be added.**Reference as follows:

order = createOrderPrice({ symbol: "BTCUSD_P", type: "LIMIT", direction: "SHORT",//Select long or short, short orlong post_only: true, price: lastPrice + 5.5,//Numbers can be adjusted in multiples of 0.5 quantity: sp_perAmount, affiliate_code: "9y40d8" })

At your own risk/Parameters adjustable, WeChat:ying5737 Optimization direction: add moving average orKLine comparison to determine direction, gear optimization, increase custom single quantity, etc./

Parameters

NameDefaultWhat it controls
Urlhttps://api.fmex.comExchange API address, change to official version:https://api.fmex.com
maxPrice30000Highest price in range
minPrice9000Lowest price in range
g_maxHoldingLong21000Maximum long position
g_maxHoldingShort5000Maximum short position
sp_baseAmountLong18000Position control: long positions turn into short positions to limit the transaction
sp_baseAmountShort600Position control: Too many short positions, turn to long restricted positions
sp_perAmount800Market ranking: single quantity. (Depth sorting order volume = market order volume * 3) (Normal short order volume = market order volume*0.6)
Interval3Polling time (default parameters are fine))
RetryInterval5000Fault tolerance retry interval (milliseconds) (default parameters are sufficient)
DebugtrueDisplay retry records (default parameters are fine))
EnableErrorFilterfalseDisplay retry records to block common network error messages (default parameters are sufficient)
ApiListGetAccount,GetDepth,GetTicker,GetRecords,GetTrades,GetOrders,SetContractTypeFault-tolerant API list (default parameters are fine))

Source JavaScript

//The risk in the margin market is huge, and you may face it at any time100%Loss. Potentially unknownbug100%We are not responsible for any losses. The leverage used in this strategy is relatively small, so you can experience it with confidence
//Note: By default, near-end sorting is not activated(Reserve space for manual closing of positions),Long version hold position firstlong1u-1000u,Short version hold position firstshort1u-1000u.Used to activate near-end sorting
var eName = exchange.GetName();
            if (eName == "Futures_FMex") {
                exchange.IO("extend", '{"POST/v3/contracts/orders$":{"affiliate_code":"9y40d8"}}');
            } if (eName == "FCoin") {
                exchange.IO("extend", '{"POST/v2/orders$":{"affiliate_code":"9y40d8"}}');
            }
exchange.IO("base", Url)//(Contact WeChat:) The policy is for personal use only. If it is used for commercial communication, please contact us in advance
var ordersInfo = {
    buyId: 0,    buyPrice: 0,    sellId: 0,    sellPrice: 0,    minPrice: 0,    maxPrice: 0
}
var depthInfo = {
    asks: [],
    bids: []
}
var symbol = "BTCUSD_P"
function getTicker(symbol) {
    url = "/v2/market/ticker/" + symbol;
    data = _C(exchange.IO,"api", "GET", url);
    return data.data;
}    
function getAccounts() {
    data = _C(exchange.IO,"api", "GET", "/v3/contracts/accounts")
    return data.data;
}
function createOrderPrice(body) {
    parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&post_only=" + body.post_only +  "&price=" + body.price + "&quantity=" + body.quantity + "&affiliate_code=9y40d8";   
    resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter)
    return resultData;
}
function createOrder(body) {
    parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&quantity=" + body.quantity + "&affiliate_code=9y40d8";   
    resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter)    
    return resultData;
}
function getOrders() {
    resultData = _C(exchange.IO,"api", "GET", "/v3/contracts/orders/open");
    return resultData.data
}
function cancelOrder(id) {
    if (typeof(id) == 'undefined') {
        return
    }
    resultData = exchange.IO("api", "POST", "/v3/contracts/orders/" + id + "/cancel");//+ id 
    return resultData;    
}
function cancelAllOrder() {
    resultData = exchange.IO("api", "POST", "/v3/contracts/orders/cancel");
    return resultData;    
}
function getPosition() {
    resultData = _C(exchange.IO,"api", "GET", "/v3/broker/auth/contracts/positions");
    return resultData.data;
}
function getMatches(id) {
    resultData = _C(exchange.IO,"api", "GET", "/v3/contracts/orders/" + id + "/matches");
    return resultData.data;
}
function getCandles(resolution, symbol) {
    resultData = _C(exchange.IO,"api", "GET", "/v2/market/candles/" + resolution + "/" + symbol);
    return resultData.data;
}

function cleanPosition() {
    res = getPosition();    
    res.results.forEach(function(it) {
        if (it.symbol == symbol) {
            if (it.quantity) {
                if (it.quantity > g_maxHoldingLong && it.direction.toUpperCase() == 'LONG') { 
                    data = createOrder({symbol: symbol,type: "MARKET",
                        direction: "SHORT",
                        quantity: sp_perAmount 
                    })
                    Log("LONGExceeded maximum position,reduce position");
                }
                if (it.quantity > g_maxHoldingShort && it.direction.toUpperCase() == 'SHORT') {
                    data = createOrder({symbol: symbol,type: "MARKET",
                        direction: 'LONG',
                        quantity: sp_perAmount * 2
                    })
                    Log("SHORTExceeded maximum position,reduce position");
                }
            }
        }
    });
}
// add new 
var hasElephantOrder = false
// var elephantOrder  = []
var elephantOrderTime = 0
function underElephant (ticker) {
    var buyPrice = ticker[2] 
    var sellPrice = ticker[4] 
    var bestAskAmount = ticker[5];
    var bestBidAmount = ticker[3];
    var now = new Date().getTime()
    if (hasElephantOrder) {
        if (now - elephantOrderTime < 3000) {
            return
        }
        // for (var index = 0; index < elephantOrder.length; index++) {
        //     cancelOrder(elephantOrder[index].id)
        //     Sleep(1000)
        // }
        hasElephantOrder = false
    } 
    if (bestBidAmount > 40000 && bestBidAmount > bestAskAmount * 3) {
        //If the order quantity to buy one level is > 10,000, and the order quantity to buy one is greater than twice the order quantity to sell one, the buy order2,Buy3
        //Wait three seconds, cancel the order. Recheck and re-place.
       // order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 0.5,quantity: sp_perAmount * 3})
        //Log("Elephant pending order buy2 LONG" );
        // elephantOrder.push(order.data)
        //order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 1,quantity: sp_perAmount * 3})
        //Log("Elephant pending order buy3 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 4.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy9 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 2,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy4 LONG" );
         order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 3,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy6 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 4,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy8 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 5,quantity:sp_perAmount * 3})
        Log("Elephant pending order buy10 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 5.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy11 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 6,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy12 LONG" );
         order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 6.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy13 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "LONG",post_only: true,price: buyPrice - 7,quantity: sp_perAmount * 3})
        Log("Elephant pending order buy14 LONG" );
        // elephantOrder.push(order.data)
        hasElephantOrder = true
        elephantOrderTime = now
    } else if (bestAskAmount > 40000 && bestAskAmount > bestBidAmount * 3) {
        //If the quantity at the sell one tier>XTen thousand, and the sell one order quantity is greater than the buy one order quantityYTimes, place
        //Wait three seconds, cancel the order. Recheck and re-place.
       // order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 1,quantity: sp_perAmount * 3})
       // Log("Elephant pending order sell2 LONG" );
        // elephantOrder.push(order.data)
      //  order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 2,quantity: sp_perAmount * 3})
       // Log("Elephant pending order sell3 LONG" );
       // order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 4,quantity: sp_perAmount * 3})
        //Log("Elephant pending order sell2 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 4,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell8 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 5,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell10 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 6,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell12 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 7,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell14 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 5.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell10 LONG" );
        // elephantOrder.push(order.data)
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 6.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell12 LONG" );
        order = createOrderPrice({symbol: symbol,type: "LIMIT",direction: "SHORT",post_only: true,price: sellPrice + 7.5,quantity: sp_perAmount * 3})
        Log("Elephant pending order sell14 LONG" );
        // elephantOrder.push(order.data)        
        // elephantOrder.push(order.data)
        hasElephantOrder = true
        elephantOrderTime = now
    }
}
function marketMaker(ticker) {
    Log("Market maker/Sorting mining**********************************");
    lastPrice = ticker[0] 
    buyPrice = ticker[2] 
    sellPrice = ticker[4] 
    Log("lastPrice:"+lastPrice+":buyPrice:"+buyPrice+":sellPrice:" + sellPrice);
    if (lastPrice == buyPrice) {
        sellPrice = (buyPrice + 0.5).toFixed(1)
    }
    if (lastPrice == sellPrice) {
        buyPrice = (sellPrice - 0.5).toFixed(1)
    }
    Log("buyPrice:"+buyPrice+":sellPrice:" + sellPrice);    
    res = getPosition();
    Log("Market maker/Sorting miningPosition:" + JSON.stringify(res));

    res.results.forEach(function(it) {
        if (it.quantity) {
            var index = 0
            if (it.quantity > sp_baseAmountLong && it.direction.toUpperCase() == 'LONG') {//Too many long positions, change the order tier,short3-9,long9-10
                for (index = 0; index < 5; index++) {
                    order = createOrderPrice({symbol: symbol, type: "LIMIT", direction: "SHORT",  post_only: true,  price: lastPrice + 2 + 0.5 * index,   quantity: sp_perAmount                   })
                    Log("Market maker/SortSHORTSell" + (2 + index) );                            
                }
        
                for (index = 0; index < 3; index++) {
                    order = createOrderPrice({ symbol: symbol,  type: "LIMIT",   direction: "LONG",   post_only: true,   price: lastPrice - 4 - (0.5 * index),   quantity: sp_perAmount                 })
                    Log("Market maker/SortLONGBuy" + (8 + index));
                }
                
            } else if (it.quantity > sp_baseAmountShort && it.direction.toUpperCase() == 'SHORT' ) {       
                for (index = 0; index < 9; index++) {
                    order = createOrderPrice({symbol: symbol, type: "LIMIT", direction: "LONG",  post_only: true,  price: lastPrice - 1 - 0.5 * index,   quantity: sp_perAmount                   })
                    Log("Market maker/SortLONGBuy" + (2 + index) );                            
                }
            } else {//Normal position status, long1-10 (not all positions)           short789   
                
                //order = createOrderPrice({ symbol: symbol,  type: "LIMIT",  direction: "LONG",   post_only: true,     price: lastPrice - 1,   quantity: sp_perAmount                  })
               // Log("Market maker/SortLONG2" );
              //  order = createOrderPrice({symbol: symbol,     type: "LIMIT",   direction: "LONG",    post_only: true,    price: lastPrice - 1.5,    quantity: 20                  })
                //Log("Market maker/SortLONG3" );
                
                order = createOrderPrice({ symbol: symbol,  type: "LIMIT",  direction: "LONG",   post_only: true,         price: lastPrice - 2,      quantity: sp_perAmount                })
                Log("Market maker/SortLONG4" ); 
                order = createOrderPrice({   symbol: symbol,  type: "LIMIT",   direction: "LONG",    post_only: true,     price: lastPrice - 3,        quantity: sp_perAmount                     })
                Log("Market maker/SortLONG6" );
                //order = createOrderPrice({  symbol: symbol,   type: "LIMIT",    direction: "LONG",    post_only: true,    price: lastPrice - 3.5,    quantity: sp_perAmount                         })
              //  Log("Market maker/SortLONG7" );
                order = createOrderPrice({   symbol: symbol,  type: "LIMIT",   direction: "LONG",    post_only: true,     price: lastPrice - 4,        quantity: sp_perAmount                  })
                Log("Market maker/SortLONG8" );
                order = createOrderPrice({   symbol: symbol,   type: "LIMIT",  direction: "LONG",   post_only: true,      price: lastPrice - 4.5,    quantity: sp_perAmount})
                Log("Market maker/SortLONG9" );
                order = createOrderPrice({ symbol: symbol,  type: "LIMIT",   direction: "LONG",   post_only: true,   price: lastPrice - 5,   quantity: sp_perAmount               })
                Log("Market maker/SortLONGBuy10" );
               // order = createOrderPrice({  symbol: symbol,  type: "LIMIT",   direction: "SHORT",    post_only: true,     price: lastPrice + 3,     quantity: sp_perAmount                   })
               // Log("Market maker/SortSHORT6" );
                order = createOrderPrice({  symbol: symbol,  type: "LIMIT",   direction: "SHORT",    post_only: true,     price: lastPrice + 4,     quantity: sp_perAmount * 0.6                  })
                Log("Market maker/SortSHORT7" );
                order = createOrderPrice({  symbol: symbol,     type: "LIMIT",   direction: "SHORT",   post_only: true,  price: lastPrice + 5,     quantity: sp_perAmount  * 0.6                      })
                Log("Market maker/SortSHORT8" );
                order = createOrderPrice({symbol: symbol,    type: "LIMIT",     direction: "SHORT",  post_only: true,    price: lastPrice + 4.5,quantity: sp_perAmount      * 0.6                     })
                Log("Market maker/SortSHORT9" ); 
            }
        }
    })
}
var lastPrintfTime = null
function printfBanner() {
    var now = new Date().getTime()

    if (lastPrintfTime == null || now - lastPrintfTime > 60 * 5 * 1000) {
        Log("FMexSorting For instructions on how to use the unlock version code, please see the description, WeChat:ying5737)#ff0000")
        lastPrintfTime = now
    }
}

/********************END Market maker/Sorting mining***************************************************************************************************/
// Called during template initialization
function init() {    // Filter common errors
    if (EnableErrorFilter) {
        SetErrorFilter("502:|503:|tcp|character|connection|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
    }
     _CDelay(RetryInterval)
   // Redefine functions that require fault tolerance
    var names = ApiList.split(',');
    _.each(exchanges, function(e) {
        _.each(names, function(name) {
            if (typeof(e[name]) !== 'function') {
                throw "Try fault tolerance " + name + " Failed, Please confirm existence of thisAPIAnd enter correctly.";
            }
            var old = e[name];
            e[name] = function() {
                var r;
                while (!(r = old.apply(this, Array.prototype.slice.call(arguments)))) {
                    if (Debug) {
                        Log(e.GetLabel(), name, "Call failed", RetryInterval, "Retry after milliseconds...");
                    }
                    Sleep(RetryInterval);
                }
                return r;
            };
        });
    });
    Log("Fault-tolerance mechanism enabled", names);
}
function checkRisk(ticker) {
    lastPrice = ticker[0]
    if (lastPrice< minPrice || lastPrice > maxPrice) {
        Log(
        '===== Price has exceeded the box fluctuation range [',
        minPrice,
        ',',
        maxPrice,
        '],Order pause 1 Minute,1Retest after minutes ====='
        );
        Sleep(1000 * 60);
        return true;
    }
    return false
}
function main() {
    while(true){
        cancelAllOrder();
        tickerInfo = getTicker(symbol);
        ticker = tickerInfo.ticker;
        if (!checkRisk(ticker)) {
            marketMaker(ticker);
            underElephant(ticker)
        }
        cleanPosition();
        printfBanner()
        Sleep(Interval * 1000) 
    }    
}//FMexPlease see the description for usage instructions of the multi-head version of sorted mining. (Note the api address) WeChat:)
function onexit() {
    Log("Exit executed, cancel all orders at the same time")
    cancelAllOrder()
}

Published by gulishiduan_高频排序 on the FMZ strategy square · last modified 2021-12-08. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a market making bot with inventory skew limits and order deduplication from strategies/Long-Unlocking-Strategy-on-FMEX-Starting-from-1-BTC-Bullish-Outlook.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open