I'm trying to calculate the average entry price for perpetual swap contracts for use in back-testing a trading strategy, as per Bitmex's documentation : A Perpetual Contract is a derivative product that is similar to a traditional Futures Contract, but has a few differing specifications: There is no expiry or settlement. Perpetual Contracts mimic a margin-based spot market and hence trade close to the underlying reference Index Price. This is in contrast to a Futures Contract which may trade at significantly different prices due to basis. The primary mechanism to tether to spot price is Funding This contract specification is found on numerous exchanges, Bitmex, Okex, Binance etc. The average entry price is used in calculating the realized PNL, the following describes the context in which it is used. John is long 1,000 XBTUSD contracts with an average entry price of 1,250. John’s unrealised PNL is based on the difference between his average entry price and the mark price. Unrealised Profit = ( 1,000 - 1,250) * 1,000 = 0.20 XBT The last price of XBTUSD is 1,500 and realise some profit. John’s realised PNL is based on the difference between his average entry price and the price at which he sells XBTUSD. Realised Profit = ( 1/1,250, he would have a realised profit of 0.10 XBT. I have taken note of the answers located here. total_quantity / ((quantity_1 / price_1) + (quantity_2 / price_2)) = entry_price and have appended each execution to an array then run a summation before dividing the current position by the summed executions i.e. entries = [] position = 0 orders = [ {"size":-50, "price":10000, "side":"sell"}, {"size":5, "price":10000, "side":"sell"}, ] for order in orders: entries.append(abs(order["size"])/order["price"]) position += order["size"] average_entry_price = abs(position)/sum(entries) print(average_entry_price) # 8181.818181818182 However in this instance it returns a presumably incorrect average entry price of 8181.818181818182.This happens in numerous cases. I then after contacting support was given the following protocol for deriving the average entry price: The execCost of each entry order is added together. For our contracts, execCost is calculated as round(1e8/price) * number of contracts. The total execCost is divided by the total number of entry contracts. This is the 'average satoshi price' of the position. For long positions, floor() the average satoshi price. For short position, round() the average satoshi price. Divide 1e8 by the average satoshi price to get the average USD price. This is then rounded to 4 decimal places for the API, and rounded to the nearest tick for the front-end. And thereafter implemented a simple "proof of concept" implementation: orders = [ {"price":10000, "size": -100}, {"price":10000, "size": -100}, {"price":10000, "size": 100}, {"price":10000, "size": 100}, {"price":9000, "size": 100}, ]
execCosts = 0 totalEntry = 0 position = 0 for order in orders: next_position = position+order["size"] if position * next_position <0: #Current position is closed and opposite position is opened execCosts = 0 totalEntry = 0 execCosts += (round(1e8/order["price"]) * order["size"]) totalEntry += abs(order["size"]) elif abs(position) > abs(next_position): # The current position is reduced pass else: #The current position is increased execCosts += (round(1e8/order["price"]) * order["size"]) totalEntry += abs(order["size"]) position = next_position
averageSatoshiPrice = abs(execCosts/totalEntry) print(averageSatoshiPrice) # 2963.0 ??? However this again seemed to be an insufficient implementation. Could someone please advise me on how to calculate the Average Entry Price. Your guidance is truly appreciated.


