Gráfico de arbitraje de futuros y spot de materias primas basado en datos fundamentales de la FMZ

El autor:La bondad, Creado: 2020-06-17 10:59:26, Actualizado: 2023-11-01 20:28:10

img

Resumen de las actividades

Algunas personas pueden no estar familiarizadas con la palabra arbitraje, pero arbitraje es muy común en la vida real. Por ejemplo, el dueño de una tienda de conveniencia compra una botella de agua mineral del mercado mayorista por 0,5 yuanes, luego la vende en la tienda por 1 yuán, y finalmente gana una diferencia de 0,5 yuanes.

¿Qué es el arbitraje?

En el mercado de futuros de materias primas, en teoría, el precio del contrato de Apple entregado en mayo menos el precio del contrato de Apple entregado en octubre, el resultado debería ser cercano a 0 o estable dentro de un cierto rango de precios.

Pero en cualquier caso, la diferencia de precio finalmente volverá a un cierto rango de precios, entonces si la diferencia de precio es mayor que este rango, vende corto el contrato de mayo, y comprar largo el contrato de octubre al mismo tiempo, corta la diferencia para obtener ganancias; si la diferencia de precio es menor que este rango, compra largo contrato de mayo, al mismo tiempo vender corto contrato de octubre, obtener ganancias de comprar largo el margen. Este es el arbitraje intertemporal a través de la compra y venta de la misma variedad pero diferentes meses de entrega.

Además del arbitraje intertemporal, existen arbitrajes transfronterizos como la compra de soja de los países exportadores y la venta de soja de los países importadores, o la venta de soja de los países exportadores e importación de soja de los países importadores; la compra de materias primas, mineral de hierro, y la venta de hilo acabado de acero, o la venta de mineral de hierro de la materia prima al mismo tiempo que se compra el arbitraje de rebarras acabadas, etc.

¿Qué es futures y spot arbitraje?

Aunque los métodos de arbitraje anteriores son literalmente arbitraje, no son puramente arbitraje. son esencialmente especulación arriesgada. Esta forma de especulación es obtener ganancias comprando largo o vendiendo corto los diferenciales de precios. Aunque el diferencial se ha estabilizado la mayor parte del tiempo, puede haber una situación de mercado en la que el diferencial de precios no regrese durante mucho tiempo.

El principio básico del arbitraje futures and spots es que la misma mercancía solo puede tener un precio en el mismo momento. Los futuros se convertirán en un punto cuando se alcance el tiempo de entrega, por lo que se forzará un retorno de precio cuando el tiempo de entrega del contrato esté cerca. Esto es completamente diferente del arbitraje intertemporal. El arbitraje intertemporal es un contrato con dos meses de entrega diferentes. Cuando expira, se convierte en el punto de dos meses diferentes. O puede ser dos precios.

  • El importe de las pérdidas de capital de las entidades incluidas en el modelo CR SA, incluidas las pérdidas de capital de las entidades incluidas en el modelo CR IRB.

La mayor característica del arbitraje futures and spots es que no hay riesgo en teoría, basándose principalmente en el estado de la propagación para calcular el rango de ganancia. Si el spread es demasiado grande, puedes hacer long el spot y short los futuros al mismo tiempo, esperar a que el spread vuelva a cero, puedes cerrar la posición en ambos lados del futures y spot, y obtener un beneficio del spread.

Mercancías futures y spot canal de arbitraje

En pocas palabras, el vínculo más complicado es el comercio al contado de productos básicos, que implica una serie de problemas como recibos de almacén, impuestos y así sucesivamente. En primer lugar, se necesita una empresa relacionada con el alcance de la inversión. Si se trata de una cuenta de futuros de arbitraje de entrega de contratos, debe ser una persona jurídica corporativa. Si se necesita un doble arbitraje de posición cerrada, se necesita un canal de ventas confiable.

Debe tenerse en cuenta que las transacciones al contado generalmente tienen un impuesto al valor agregado del 17% al 20%, por lo que si se trata de un doble arbitraje de posición cerrada, debe acortar futuros de 1.2 a 1.25 veces después de comprar al contado. En el caso del arbitraje de entrega de contratos, debe acortar la misma proporción de futuros después de comprar el spot, y también debe considerar los costos de las tarifas de transacción, transporte y almacenes. Por supuesto, la premisa de todo esto es que el margen de precio actual es lo suficientemente grande y hay suficientes límites.

Además, debido a la existencia de oro (T + D) en la Bolsa de Oro de Shanghai, el arbitraje actual en el período de oro no solo puede ser arbitraje positivo, sino también operaciones de arbitraje inverso sin arrendamiento de oro.

Cómo obtener datos al contado y a diferencia

Hay muchos tipos de datos spot y spread en línea, la mayoría de los cuales se presentan en forma de tablas, lo que obviamente no es adecuado para analizar y juzgar el mercado.FMZ.COMSólo necesita llamar a una función para obtener el precio al contado y el precio del diferencial de cada variedad, y soportar datos históricos desde 2016 hasta el presente.

# Backtest configuration
'''backtest
start: 2020-06-01 00:00:00
end: 2020-06-02 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

# Strategy entry
def main():
    while True:
        ret = exchange.GetData("GDP")  # Calling GDP data
        Log(ret)  # Print data
        Sleep(1000 * 60 * 60 * 24 * 30)

Resultado de la devolución

{
     "Quarterly": "Q1 2006",
     "GDP": {
         "Absolute Value (100 million yuan)": 47078.9,
         "YoY Growth": 0.125
     },
     "primary industry": {
         "Absolute Value (100 million yuan)": 3012.7,
         "YoY Growth": 0.044
     },
     "Tertiary Industry": {
         "Absolute Value (100 million yuan)": 22647.4,
         "YoY Growth": 0.131
     },
     "Secondary industry": {
         "Absolute Value (100 million yuan)": 21418.7,
         "YoY Growth": 0.131
     }
}

Implementación de los gráficos al contado y a diferencia

Utilicemos la plataforma FMZ para cuantificar y realizar los precios al contado y los precios de dispersión en forma de gráficos.FMZ.COMSeleccione Python en el menú desplegable en la esquina superior izquierda y complete el nombre de la estrategia.

Paso 1: redactar el marco estratégico

# Strategy main function
def onTick():
     pass


# Strategy entrance
def main():
     while True: # Enter loop mode
         onTick() # execution strategy main function
         Sleep(1000 * 60 * 60 * 24) # Strategy sleep for one day

El marco estratégico tiene dos funciones:mainLa estrategia de la empresa es la entrada de lamainLa función es el pre-procesamiento antes de la negociación, el programa comenzará desde elmainfunción, y luego entrar en el modo de bucle infinito, ejecutar repetidamente elonTickLa función, elonTickLa función principal de la estrategia es ejecutar el código principal.

Paso 2: Añadir la función de gráfico

# Global variables
# Futures and Spots chart
cfgA = {
    "extension": {
        "layout":'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "futures and spots chart"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "Futures Price",
        "data": [],
    }, {
        "name": "Spot Price",
        "data": [],
    }
    ]
}
# Spread chart
cfgB = {
    "extension": {
        "layout":'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "Spread chart"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "Spread Price",
        "data": [],
    }]
}
chart = Chart([cfgA, cfgB]) # Create a chart object


# Strategy main function
def onTick():
    chart.add(0, []) # draw chart
    chart.add(1, []) # draw chart
    chart.add(2, []) # draw chart
    chart.update([cfgA, cfgB]) # update chart


# Strategy entrance
def main():
    LogReset() # Clear the previous log information before running
    chart.reset() # Clear the previous chart information before running
    while True: # Enter loop mode
        onTick() # execution strategy main function
        Sleep(1000 * 60 * 60 * 24) # Strategy sleep for one day

En esta estrategia, se han creado un total de 2 gráficos y se organizan uno al lado del otro.cfgAa la izquierda se muestra un gráfico actual, que incluye los precios de los futuros y los precios al contado, ycfgBa la derecha es un gráfico de dispersión. Luego llame a la plataforma FMZ integrada en la biblioteca de dibujo de líneas de Python para crear un objeto de gráfico. Finalmente, los datos en el gráfico se actualizan en tiempo real en elonTick function.

Paso 3: Obtener datos

last_spot_price = 0 # Save the last valid spot price
last_spread_price = 0 # Save the last valid spread price

def onTick():
    global last_spread_price, last_spot_price # import global variables
    exchange.SetContractType("i888") # Subscribe to futures varieties
    futures = _C(exchange.GetRecords)[-1] # Get the latest K line data
    futures_ts = futures.Time # Get the latest K-line futures timestamp
    futures_price = futures.Close # Get the latest K-line closing price

    spot = exchange.GetData("SPOTPRICE") # Get spot data
    spot_ts = spot.Time # Get spot timestamp
    if 'iron ore' in spot.Data:
        spot_price = spot.Data['iron ore']
        last_spot_price = spot_price
    else:
        spot_price = last_spot_price

    spread = exchange.GetData("spread") # Get spread data
    spread_ts = spread.Time # Get spread timestamp
    if 'iron ore' in spread.Data:
        spread_price = spread.Data['iron ore']
        last_spread_price = spread_price
    else:
        spread_price = last_spread_price

En total, necesitamos obtener tres tipos de datos: precio de futuros, precio al contado y precio de dispersión.SetContractTypeLa función de suscribirse directamente al símbolo de futuros, y luego utilizar elGetRecordsPara los precios del spot y del spread, puede utilizar el método introducido anteriormente, utilizar elGetDatafunción para llamar el código de datos básicos, y devolver los datos del diccionario que contiene la marca de tiempo.

Muestra de gráfico

img img img

Obtenga el código completo de la estrategia

# fmz@b72930603791887d7452f25f23a13bde
'''backtest
start: 2017-01-01 00:00:00
end: 2020-06-01 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''


# Global variables
# Futures and Spots chart
cfgA = {
    "extension": {
        "layout":'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "futures and spots chart"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "Futures Price",
        "data": [],
    }, {
        "name": "Spot Price",
        "data": [],
    }
    ]
}
# spread chart
cfgB = {
    "extension": {
        "layout":'single',
        "col": 6,
        "height": "500px",
    },
    "title": {
        "text": "spread chart"
    },
    "xAxis": {
        "type": "datetime"
    },
    "series": [{
        "name": "spread Price",
        "data": [],
    }]
}
last_spot_price = 0 # Save the last valid spot price
last_spread_price = 0 # Save the last valid spread price
chart = Chart([cfgA, cfgB]) # Create a chart object

def onTick():
    global last_spread_price, last_spot_price # import global variables
    exchange.SetContractType("i888") # Subscribe to futures varieties
    futures = _C(exchange.GetRecords)[-1] # Get the latest candlestick data
    futures_ts = futures.Time # Get the latest K-line futures timestamp
    futures_price = futures.Close # Get the latest K-line closing price
    Log('Future price:', futures_ts, futures_price)

    spot = exchange.GetData("SPOTPRICE") # Get spot data
    spot_ts = spot.Time # Get spot timestamp
    if 'iron ore' in spot.Data:
        spot_price = spot.Data['iron ore']
        last_spot_price = spot_price
    else:
        spot_price = last_spot_price
    Log('Spot price:', spot_ts, spot_price)

    spread = exchange.GetData("spread") # Get spread data
    spread_ts = spread.Time # Get spread timestamp
    if 'iron ore' in spread.Data:
        spread_price = spread.Data['iron ore']
        last_spread_price = spread_price
    else:
        spread_price = last_spread_price
    Log('spread price:', spread_ts, spread_price)

    chart.add(0, [futures_ts, futures_price]) # draw chart
    chart.add(1, [spot_ts, spot_price]) # draw chart
    chart.add(2, [spread_ts, spread_price]) # draw chart
    chart.update([cfgA, cfgB]) # update chart
    Log('---------')


# Strategy entrance
def main():
    LogReset() # Clear the previous log information before running
    chart.reset() # Clear the previous chart information before running
    while True: # Enter loop mode
        onTick() # execution strategy main function
        Sleep(1000 * 60 * 60 * 24) # Strategy sleep for one day

La estrategia completa se ha publicado en la plataforma FMZ (FMZ.COM) puede utilizarse directamente haciendo clic en el siguiente enlace.

https://www.fmz.com/strategy/211941

El final

El arbitraje no es tan complicado como se imagina. No requiere demasiado conocimiento de la teoría financiera, ni requiere modelos matemáticos o estadísticos demasiado complicados. El arbitraje es esencialmente para obtener ganancias de un precio irrazonable a un rendimiento razonable. Las condiciones del mercado cambian cada año.


Relacionados

Más.