Estoy intentando calcular el precio medio de entrada de los contratos de swap perpetuo para utilizarlo en el back-testing de una estrategia de trading, según Bitmex documentación :
Un contrato perpetuo es un producto derivado similar a un tradicional, pero tiene algunas especificaciones diferentes:
No hay vencimiento ni liquidación. Los Contratos Perpetuos imitan un mercado al contado basado en el margen y, por lo tanto, se negocian cerca del de referencia subyacente. Esto contrasta con un contrato de futuros que puede negociarse a precios significativamente diferentes debido a la base. El principal mecanismo de vinculación con el precio al contado es la Financiación
Esta especificación de contrato se encuentra en numerosos intercambios, Bitmex, Okex, Binance, etc. El precio medio de entrada se utiliza para calcular el PNL realizado, a continuación se describe el contexto en el que se utiliza.
John tiene 1.000 contratos de XBTUSD con un precio medio de entrada de $1,000. The mark price of XBTUSD is currently $ 1,250.
La PNL no realizada de Juan se basa en la diferencia entre su precio medio de precio de entrada y el precio de marca.
Beneficio no realizado = ( $1/$ 1,000 - $1/$ 1.250) * 1.000 = 0,20 XBT
El último precio del XBTUSD es de 1.500 dólares. Sin embargo, para el cálculo de la PNL no realizada, se utiliza el precio de marca y no el último precio. Para entender por qué, por favor, lea el apartado Marcado del precio justo.
John decide vender 500 contratos de XBTUSD a 1.500 dólares y realizar unos beneficio.
La PNL realizada de John se basa en la diferencia entre su media de entrada y el precio al que vende el XBTUSD.
Beneficio realizado = ( $1/1,000 - $ 1/$1.500) * 500 = 0,17 XBT
La PNL realizada se basa en el lugar donde puede comprar o vender su posición, que en la mayoría de los casos no es el precio de mercado. Si Juan hubiera vendido sus 500 contratos al precio de marca de 1.250 dólares, tendría un beneficio realizado de 0,10 XBT.
He tomado nota de las respuestas localizadas aquí.
cantidad_total / ((cantidad_1 / precio_1) + (cantidad_2 / precio_2)) = precio_de_entrada
y hemos añadido cada ejecución a un array y luego ejecutamos una suma antes de dividir la posición actual por las ejecuciones sumadas, es decir
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
Sin embargo, en este caso devuelve un precio medio de entrada presumiblemente incorrecto de 8181,8181818182.Esto ocurre en numerosos casos.
Después de contactar con el servicio de asistencia, me dieron el siguiente protocolo para obtener el precio medio de entrada:
- El execCost de cada orden de entrada se suma. Para nuestros contratos, el execCost se calcula como round(1e8/precio) * número de contratos.
- El execCost total se divide por el número total de contratos de entrada. Este es el "precio satoshi medio" de la posición.
- Para posiciones largas, floor() el precio medio de satoshi. Para posiciones cortas, round() el precio medio de los satoshi.
- Divida 1e8 por el precio medio de los satoshi para obtener el precio medio en USD. A continuación, se redondea a 4 decimales para la API, y redondeado al tick más cercano para el front-end.
Y a partir de entonces se implementó una simple "prueba de concepto":
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 ???
Sin embargo, esta aplicación también parece ser insuficiente. ¿Podría alguien aconsejarme sobre cómo calcular el precio medio de entrada? Su orientación es realmente apreciada.
0 votos
Creo que la respuesta de bitmex es errónea, no se debe redondear el material. Pero también tengo algún problema, no puede coincidir el resultado de la mía con el resultado en bitmex web ui. ¿Lo has solucionado?
0 votos
Creo que la fórmula correcta es la que has mencionado: cantidad_total / ((cantidad_1 / precio_1) + (cantidad_2 / precio_2)) = precio_entrada. Pero en tu implementación de esta fórmula, utilizas abs() en el tamaño de la orden y el total de la posición. Creo que si eliminas abs, debería funcionar.