Commodity "futures and spots" Tableau d'arbitrage basé sur les données fondamentales du FMZ

Auteur:La bonté, Créé: 2020-06-17 10:59:26, Mis à jour: 2023-11-01 20:28:10

img

Résumé

Certains ne connaissent peut-être pas le mot arbitrage, mais arbitrage est très courant dans la vie réelle. Par exemple, le propriétaire d'un magasin de proximité achète une bouteille d'eau minérale sur le marché de gros pour 0,5 yuan, puis la vend dans le magasin pour 1 yuan, et gagne finalement une différence de 0,5 yuan. Ce processus est en fait similaire à l'arbitrage.

Qu'est-ce que l'arbitrage?

Sur le marché des contrats à terme sur matières premières, en théorie, le prix du contrat Apple livré en mai moins le prix du contrat Apple livré en octobre, le résultat devrait être proche de 0 ou stable dans une certaine fourchette de prix.

Mais dans tous les cas, la différence de prix finira par revenir à une certaine fourchette de prix, puis si la différence de prix est supérieure à cette fourchette, vendre court le contrat de mai, et acheter long le contrat d'octobre en même temps, court la différence pour faire un profit; si la différence de prix est inférieure à cette fourchette, acheter long contrat de mai, en même temps vendre court contrat d'octobre, faire un profit d'acheter long le spread.

L'arbitrage intertemporel est complété par l'arbitrage transfrontalier, tel que l'achat de soja des pays exportateurs tout en vendant du soja des pays importateurs, ou la vente de soja des pays exportateurs et l'importation de soja des pays importateurs; l'achat en amont de matières premières, de minerai de fer et la vente en aval du fil fini d'acier, ou la vente en amont du minerai de fer en achetant en aval du minerai de fer fini d'armature, etc.

Qu'est-ce que l'arbitrage à terme?

Bien que les méthodes d'arbitrage ci-dessus soient littéralement arbitrage, elles ne sont pas purement arbitrage. elles sont essentiellement des spéculations à risque. Cette façon de spéculer consiste à réaliser des profits en achetant long ou en vendant court les spreads de prix. Bien que l'écart se soit stabilisé la plupart du temps, il peut y avoir une situation de marché où l'écart de prix ne revient pas pendant une longue période.

Le principe de base de l'arbitrage futures and spots est que la même marchandise ne peut avoir qu'un seul prix au même moment. Les futures deviendront un spot lorsque le temps de livraison est atteint, de sorte qu'un retour de prix sera forcé lorsque le temps de livraison du contrat est proche. Ceci est complètement différent de l'arbitrage intertemporel. L'arbitrage intertemporel est un contrat avec deux mois de livraison différents. Lorsqu'il expire, il devient le spot de deux mois différents.

  • Le taux de conversion est le taux de conversion de l'établissement.

La plus grande caractéristique de l'arbitrage futures and spots est qu'il n'y a aucun risque en théorie, principalement basé sur l'état de l'écart pour calculer la fourchette de profit.

Commodity futures et spot canal d'arbitrage

Pour le dire simplement, le lien le plus compliqué est le trading au comptant des matières premières, qui implique une série de questions telles que les reçus d'entrepôt, la fiscalité, etc. Tout d'abord, une entreprise liée à la portée de l'investissement est nécessaire. S'il s'agit d'un compte à terme d'arbitrage de livraison de contrats, il doit s'agir d'une personne morale d'entreprise.

Il convient de noter que les transactions au comptant ont généralement une taxe sur la valeur ajoutée de 17% à 20%, donc s'il s'agit d'un arbitrage de double position fermée, vous devez raccourcir les contrats à terme de 1,2 à 1,25 fois après l'achat au comptant. Dans le cas de l'arbitrage de livraison de contrat, vous devez raccourcir la même proportion de contrats à terme après l'achat du comptant, et vous devez également prendre en compte les coûts des frais de transaction, du transport et des entrepôts. Bien sûr, la prémisse de tout cela est que l'écart de prix actuel est suffisamment grand et qu'il y a suffisamment de limites.

En outre, en raison de l'existence d'or (T + D) sur la Bourse d'or de Shanghai, l'arbitrage actuel dans la période de l'or peut non seulement être un arbitrage positif, mais aussi des opérations d'arbitrage inverse sans leasing d'or.

Comment obtenir les données ponctuelles et les données sur les écarts

Il existe en ligne de nombreux types de données au comptant et de données sur les spreads, dont la plupart sont présentées sous forme de tableaux, ce qui n'est évidemment pas adapté à l'analyse et au jugement du marché.FMZ.COMIl suffit d'appeler une fonction pour obtenir le prix au comptant et au spread de chaque variété, et prendre en charge les données historiques de 2016 à nos jours.

# 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)

Retourner le résultat

{
     "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
     }
}

Mise en œuvre des graphiques au comptant et des spreads

Utilisons la plateforme FMZ pour quantifier et réaliser les prix au comptant et les prix de spread sous forme de graphiques.FMZ.COM), cliquez sur Dashboard, puis cliquez sur Strategy Library + New Strategy. Sélectionnez Python dans le menu déroulant dans le coin supérieur gauche et renseignez le nom de la stratégie.

Étape 1: Écrire le cadre stratégique

# 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

Le cadre stratégique a deux fonctions:mainLa fonction est l'entrée de la stratégie, lamainLa fonction est le pré-traitement avant la négociation, le programme commencera à partir de lamainfonction, puis entrer dans le mode de boucle infinie, exécuter à plusieurs reprises leonTickfonction, leonTickLa fonction principale de la stratégie est d'exécuter le code de base.

Étape 2: Ajout de la fonction graphique

# 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

Dans cette stratégie, 2 graphiques ont été créés et sont disposés côte à côte.cfgAà gauche, un graphique actuel, comprenant les prix à terme et les prix au comptant, etcfgBEnsuite, appelez la plateforme FMZ intégrée à la bibliothèque de dessin de lignes Python pour créer un objet graphique.onTick function.

Étape 3: obtenir des données

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

Au total, nous avons besoin d'obtenir trois types de données: le prix des contrats à terme, le prix au comptant et le prix du spread.SetContractTypeLa fonction de souscrire directement au symbole des contrats à terme, puis d'utiliser leGetRecordsPour les prix au comptant et au spread, vous pouvez utiliser la méthode introduite précédemment,GetDatafonction pour appeler le code de données fondamentales, et retourner les données du dictionnaire qui contient l'horodatage.

Affichage du graphique

img img img

Obtenez le code complet de la stratégie

# 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 stratégie complète a été publiée sur la plateforme FMZ (FMZ.COM) stratégie, elle peut être utilisée directement en cliquant sur le lien ci-dessous.

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

Finition

L'arbitrage n'est pas aussi compliqué que l'on pourrait l'imaginer. Il ne nécessite pas trop de connaissances en théorie financière, ni de modèles mathématiques ou statistiques trop compliqués. L'arbitrage consiste essentiellement à réaliser un profit à partir d'un prix déraisonnable pour un rendement raisonnable. Les conditions du marché changent chaque année.


Relationnée

Plus de