{ "cells": [ { "cell_type": "markdown", "id": "59d19f73", "metadata": {}, "source": [ "# Python API Example - Netbacks Data Import and Storage in Dataframe\n", "\n", "This guide is designed to provide an example of how to access the Spark API:\n", "- The path to your client credentials is the only input needed to run this script (just before Section 2)\n", "- This script has been designed to display the raw outputs of requests from the API, and how to format those outputs to enable easy reading and analysis\n", "- This script can be copy and pasted by customers for quick use of the API\n", "- Once comfortable with the process, you can change the variables that are called to produce your own custom analysis products. (Section 2 onwards in this guide).\n", "\n", "__N.B. This guide is just for Netbacks data. If you're looking for other API data products (such as Price releases or Freight routes), please refer to their according code example files.__ " ] }, { "cell_type": "markdown", "id": "b0a05be4", "metadata": {}, "source": [ "### Have any questions?\n", "\n", "If you have any questions regarding our API, or need help accessing specific datasets, please contact us at:\n", "\n", "__data@sparkcommodities.com__\n", "\n", "or refer to our API website for more information about this endpoint:\n", "https://www.sparkcommodities.com/api/request/netbacks.html" ] }, { "cell_type": "markdown", "id": "9e00ae34", "metadata": {}, "source": [ "## 1. Importing Data\n", "\n", "Here we define the functions that allow us to retrieve the valid credentials to access the Spark API.\n", "\n", "__This section can remain unchanged for most Spark API users.__" ] }, { "cell_type": "code", "execution_count": 1, "id": "705cbb25", "metadata": {}, "outputs": [], "source": [ "# Importing libraries for calling the API\n", "import json\n", "import os\n", "import sys\n", "import pandas as pd\n", "from base64 import b64encode\n", "from urllib.parse import urljoin\n", "\n", "\n", "try:\n", " from urllib import request, parse\n", " from urllib.error import HTTPError\n", "except ImportError:\n", " raise RuntimeError(\"Python 3 required\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "1161e807", "metadata": {}, "outputs": [], "source": [ "# Defining functions for API request\n", "\n", "API_BASE_URL = \"https://api.sparkcommodities.com\"\n", "\n", "\n", "def retrieve_credentials(file_path=None):\n", " \"\"\"\n", " Find credentials either by reading the client_credentials file or reading\n", " environment variables\n", " \"\"\"\n", " if file_path is None:\n", " client_id = os.getenv(\"SPARK_CLIENT_ID\")\n", " client_secret = os.getenv(\"SPARK_CLIENT_SECRET\")\n", " if not client_id or not client_secret:\n", " raise RuntimeError(\n", " \"SPARK_CLIENT_ID and SPARK_CLIENT_SECRET environment vars required\"\n", " )\n", " else:\n", " # Parse the file\n", " if not os.path.isfile(file_path):\n", " raise RuntimeError(\"The file {} doesn't exist\".format(file_path))\n", "\n", " with open(file_path) as fp:\n", " lines = [l.replace(\"\\n\", \"\") for l in fp.readlines()]\n", "\n", " if lines[0] in (\"clientId,clientSecret\", \"client_id,client_secret\"):\n", " client_id, client_secret = lines[1].split(\",\")\n", " else:\n", " print(\"First line read: '{}'\".format(lines[0]))\n", " raise RuntimeError(\n", " \"The specified file {} doesn't look like to be a Spark API client \"\n", " \"credentials file\".format(file_path)\n", " )\n", "\n", " print(\">>>> Found credentials!\")\n", " print(\n", " \">>>> Client_id={}, client_secret={}****\".format(client_id, client_secret[:5])\n", " )\n", "\n", " return client_id, client_secret\n", "\n", "\n", "def do_api_post_query(uri, body, headers):\n", " \"\"\"\n", " OAuth2 authentication requires a POST request with client credentials before accessing the API. \n", " This POST request will return an Access Token which will be used for the API GET request.\n", " \"\"\"\n", " url = urljoin(API_BASE_URL, uri)\n", "\n", " data = json.dumps(body).encode(\"utf-8\")\n", "\n", " # HTTP POST request\n", " req = request.Request(url, data=data, headers=headers)\n", " try:\n", " response = request.urlopen(req)\n", " except HTTPError as e:\n", " print(\"HTTP Error: \", e.code)\n", " print(e.read())\n", " sys.exit(1)\n", "\n", " resp_content = response.read()\n", "\n", " # The server must return HTTP 201. Raise an error if this is not the case\n", " assert response.status == 201, resp_content\n", "\n", " # The server returned a JSON response\n", " content = json.loads(resp_content)\n", "\n", " return content\n", "\n", "\n", "def do_api_get_query(uri, access_token):\n", " \"\"\"\n", " After receiving an Access Token, we can request information from the API.\n", " \"\"\"\n", " url = urljoin(API_BASE_URL, uri)\n", "\n", " headers = {\n", " \"Authorization\": \"Bearer {}\".format(access_token),\n", " \"Accept\": \"application/json\",\n", " }\n", "\n", " # HTTP POST request\n", " req = request.Request(url, headers=headers)\n", " try:\n", " response = request.urlopen(req)\n", " except HTTPError as e:\n", " print(\"HTTP Error: \", e.code)\n", " print(e.read())\n", " sys.exit(1)\n", "\n", " resp_content = response.read()\n", "\n", " # The server must return HTTP 201. Raise an error if this is not the case\n", " assert response.status == 200, resp_content\n", "\n", " # The server returned a JSON response\n", " content = json.loads(resp_content)\n", "\n", " return content\n", "\n", "\n", "def get_access_token(client_id, client_secret):\n", " \"\"\"\n", " Get a new access_token. Access tokens are the thing that applications use to make\n", " API requests. Access tokens must be kept confidential in storage.\n", "\n", " # Procedure:\n", "\n", " Do a POST query with `grantType` and `scopes` in the body. A basic authorization\n", " HTTP header is required. The \"Basic\" HTTP authentication scheme is defined in\n", " RFC 7617, which transmits credentials as `clientId:clientSecret` pairs, encoded\n", " using base64.\n", " \"\"\"\n", "\n", " # Note: for the sake of this example, we choose to use the Python urllib from the\n", " # standard lib. One should consider using https://requests.readthedocs.io/\n", "\n", " payload = \"{}:{}\".format(client_id, client_secret).encode()\n", " headers = {\n", " \"Authorization\": b64encode(payload).decode(),\n", " \"Accept\": \"application/json\",\n", " \"Content-Type\": \"application/json\",\n", " }\n", " body = {\n", " \"grantType\": \"clientCredentials\",\n", " \"scopes\": \"read:netbacks,read:access,read:prices,read:routes\",\n", " }\n", "\n", " content = do_api_post_query(uri=\"/oauth/token/\", body=body, headers=headers)\n", "\n", " print(\n", " \">>>> Successfully fetched an access token {}****, valid {} seconds.\".format(\n", " content[\"accessToken\"][:5], content[\"expiresIn\"]\n", " )\n", " )\n", "\n", " return content[\"accessToken\"]" ] }, { "cell_type": "markdown", "id": "9c527e40", "metadata": {}, "source": [ "## Defining Fetch Request\n", "\n", "Here is where we define what type of data we want to fetch from the API.\n", "\n", "In the fetch request, we use the URL:\n", "\n", "__uri=\"/v1.0/netbacks/reference-data/\"__\n", "\n", "This query shows an overview on all available netbacks, showing all available ports and possible routes to/from these destinations (i.e. via Suez, Panama etc.).\n", "\n", "An example of pulling all available Netbacks data for a specific route (e.g. Netbacks data for Sabine Pass via Suez) is shown later in this script. \n", "\n", "Pulling other data products (such as price releases) require different URL's in the fetch request (refer to other Python API examples)." ] }, { "cell_type": "code", "execution_count": 3, "id": "ada4f167", "metadata": {}, "outputs": [], "source": [ "# Define the function for listing all netbacks\n", "def list_netbacks(access_token):\n", " \"\"\"\n", " Fetch available routes. Return contract ticker symbols\n", "\n", " # Procedure:\n", "\n", " Do a GET query to /v1.0/routes/ with a Bearer token authorization HTTP header.\n", " \"\"\"\n", " content = do_api_get_query(\n", " uri=\"/v1.0/netbacks/reference-data/\", access_token=access_token\n", " )\n", "\n", " print(\">>>> All the routes you can fetch\")\n", " tickers = []\n", " fobPort_names = []\n", "\n", " availablevia = []\n", "\n", " for contract in content[\"data\"][\"staticData\"][\"fobPorts\"]:\n", " tickers.append(contract[\"uuid\"])\n", " fobPort_names.append(contract[\"name\"])\n", "\n", " availablevia.append(contract[\"availableViaPoints\"])\n", "\n", " reldates = content[\"data\"][\"staticData\"][\"sparkReleases\"]\n", "\n", " dicto1 = content[\"data\"]\n", "\n", " return tickers, fobPort_names, availablevia, reldates, dicto1" ] }, { "cell_type": "markdown", "id": "1e890e9e", "metadata": {}, "source": [ "## N.B. Credentials\n", "\n", "Here we call the above functions, and input the file path to our credentials.\n", "\n", "N.B. You must have downloaded your client credentials CSV file before proceeding. Please refer to the API documentation if you have not dowloaded them already. Instructions for downloading your credentials can be found here:\n", "\n", "https://api.sparkcommodities.com/redoc#section/Authentication/Create-an-Oauth2-Client\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "2b010f83", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ">>>> Found credentials!\n", ">>>> Client_id=875f483b-19de-421a-8e9b-dceff6703e83, client_secret=6cdf8****\n", ">>>> Successfully fetched an access token eyJhb****, valid 604799 seconds.\n", ">>>> All the routes you can fetch\n" ] } ], "source": [ "# Input the path to your client credentials here\n", "client_id, client_secret = retrieve_credentials(file_path=\"/tmp/client_credentials.csv\")\n", "\n", "# Authenticate:\n", "access_token = get_access_token(client_id, client_secret)\n", "\n", "# Fetch all contracts:\n", "tickers, fobPort_names, availablevia, reldates, dicto1 = list_netbacks(access_token)" ] }, { "cell_type": "code", "execution_count": 5, "id": "5d456a0a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[['suez', None], ['panama', None], ['cogh', 'panama', 'suez', None], ['suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'suez', None], ['cogh', 'suez', None], ['cogh', 'panama', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['panama', None], ['cogh', 'suez', None], ['suez', None], ['cogh', 'panama', 'suez', None], ['panama', None], ['cogh', 'suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['panama', None], ['cogh', 'suez', None], ['cogh', 'panama', 'suez', None], [None], ['cogh', None], ['cogh', 'panama', 'suez', None], ['cogh', 'panama', 'suez', None], ['panama', None], ['suez', None], [None], ['cogh', 'suez', None], ['cogh', 'panama', 'suez', None], ['cogh', 'suez', None]]\n" ] } ], "source": [ "# Prints the callable route options, corresponding to each Route ID number shown above\n", "# I.e. availablevia[2] shows the available route options for tickers[2]\n", "\n", "\n", "print(availablevia)" ] }, { "cell_type": "code", "execution_count": 6, "id": "7bcee4d3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Wheatstone', 'Woodfibre LNG', 'Corpus Christi', 'Bintulu', 'Lake Charles', 'Elba Island', 'Das Island', 'Gorgon', 'Atlantic LNG', 'Bethioua', 'Cove Point', 'Peru LNG', 'Ras Laffan', 'Murmansk', 'Hammerfest', 'LNG Canada', 'Yamal', 'Rio Grande LNG', 'Plaquemines', 'Altamira', 'Sabine Pass', 'Puerto Libertad', 'NWS', 'Delfin FLNG', 'Bioko', 'Bonny LNG', 'Freeport', 'Cameron (Liqu.)', 'Kamchatka', 'GLNG', 'Soyo', 'Qalhat', 'Calcasieu Pass', 'Tangguh']\n" ] } ], "source": [ "# Print the names of each of the ports, corresponding to Route ID and availablevia details shown above\n", "# Some of these options are currently unavailable. \n", "# Please refer to the Netbacks tool on the Spark Platform to check which Netbacks are currently available\n", "\n", "print(fobPort_names)" ] }, { "cell_type": "code", "execution_count": 7, "id": "4003cf3b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'staticData': {'viaPoints': [{'code': 'panama', 'name': 'Panama'},\n", " {'code': 'suez', 'name': 'Suez'},\n", " {'code': 'cogh', 'name': 'COGH'},\n", " {'code': 'magellan-straits', 'name': 'Strait of Magellan'}],\n", " 'fobPorts': [{'uuid': '00398967-3ee1-4b26-bcdb-805ad19dbcce',\n", " 'name': 'Wheatstone',\n", " 'availableViaPoints': ['suez', None]},\n", " {'uuid': '00314d16-eada-4f37-bff3-d844708aeb45',\n", " 'name': 'Woodfibre LNG',\n", " 'availableViaPoints': ['panama', None]},\n", " {'uuid': '0030c461-9a63-403d-8f53-9327ea773517',\n", " 'name': 'Corpus Christi',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003342b7-ba5b-4f0e-b6df-4d95837a5691',\n", " 'name': 'Bintulu',\n", " 'availableViaPoints': ['suez', None]},\n", " {'uuid': '003ff22f-77d8-413f-9997-2c6280e7c28c',\n", " 'name': 'Lake Charles',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00352a22-e959-4233-b93d-d23a0da3dfed',\n", " 'name': 'Elba Island',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003b48e3-aedd-417c-8ea3-2d1dd434d8a9',\n", " 'name': 'Das Island',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '00312574-769c-4edf-9a55-362f3da20312',\n", " 'name': 'Gorgon',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '00339787-d27c-4605-8409-e1c544820cec',\n", " 'name': 'Atlantic LNG',\n", " 'availableViaPoints': ['cogh', 'panama', None]},\n", " {'uuid': '003afd77-2b63-41e4-8b7a-6d6294236d78',\n", " 'name': 'Bethioua',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003e8539-3a98-48fa-b35d-0ba061beea4e',\n", " 'name': 'Cove Point',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00398395-a9d6-4d09-8e17-f731caf760d9',\n", " 'name': 'Peru LNG',\n", " 'availableViaPoints': ['panama', None]},\n", " {'uuid': '003f9d1b-b4ad-4de9-8c8d-bd7fbcacd3df',\n", " 'name': 'Ras Laffan',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '003f9252-e4e3-4957-8462-36f4b61b3370',\n", " 'name': 'Murmansk',\n", " 'availableViaPoints': ['suez', None]},\n", " {'uuid': '003f92ce-86d5-4d03-9761-311036c47812',\n", " 'name': 'Hammerfest',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00369d3c-62db-4833-8c49-ea1a2fbb2b18',\n", " 'name': 'LNG Canada',\n", " 'availableViaPoints': ['panama', None]},\n", " {'uuid': '003a8724-b074-42e2-9e2f-ac3cc3e67ea4',\n", " 'name': 'Yamal',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '00383491-7e92-4b89-8b26-473fb3dcb9ed',\n", " 'name': 'Rio Grande LNG',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003adf4e-01b5-4680-9cd7-49613d5d0e3e',\n", " 'name': 'Plaquemines',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00302863-23af-41a6-a8ec-82c703860811',\n", " 'name': 'Altamira',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003dec0a-ce8f-41db-8c24-4d7ef6addf70',\n", " 'name': 'Sabine Pass',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003ef335-be59-48ca-97aa-cf1fd8dea6fb',\n", " 'name': 'Puerto Libertad',\n", " 'availableViaPoints': ['panama', None]},\n", " {'uuid': '00381c87-4180-4430-80f1-bf828099124f',\n", " 'name': 'NWS',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '003fa7a4-b8ff-42e7-a146-983baddc769c',\n", " 'name': 'Delfin FLNG',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '003e50dc-2dca-44e5-b519-c4d704c6762d',\n", " 'name': 'Bioko',\n", " 'availableViaPoints': [None]},\n", " {'uuid': '0034fc9c-bb57-42b6-a91b-6f08c3795a25',\n", " 'name': 'Bonny LNG',\n", " 'availableViaPoints': ['cogh', None]},\n", " {'uuid': '0039b921-cc5c-47e3-9a31-9dfb0c55d345',\n", " 'name': 'Freeport',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00356046-86ab-4a76-a689-99af1b3027ad',\n", " 'name': 'Cameron (Liqu.)',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '0033d717-1d87-407b-94b0-3f115ecd1887',\n", " 'name': 'Kamchatka',\n", " 'availableViaPoints': ['panama', None]},\n", " {'uuid': '003390dc-0918-485a-ba91-12465d2f1890',\n", " 'name': 'GLNG',\n", " 'availableViaPoints': ['suez', None]},\n", " {'uuid': '003bdb09-9cc9-4998-a849-0e0dce812fa7',\n", " 'name': 'Soyo',\n", " 'availableViaPoints': [None]},\n", " {'uuid': '003627f4-c752-4ce4-9ae7-7ad0fa6e53ce',\n", " 'name': 'Qalhat',\n", " 'availableViaPoints': ['cogh', 'suez', None]},\n", " {'uuid': '003e005e-9aeb-4e31-b44f-6f1a5d79ea67',\n", " 'name': 'Calcasieu Pass',\n", " 'availableViaPoints': ['cogh', 'panama', 'suez', None]},\n", " {'uuid': '00387996-f338-4c38-abcf-3fcfd3712339',\n", " 'name': 'Tangguh',\n", " 'availableViaPoints': ['cogh', 'suez', None]}],\n", " 'sparkReleases': ['2025-01-14',\n", " '2025-01-13',\n", " '2025-01-10',\n", " '2025-01-09',\n", " '2025-01-08',\n", " '2025-01-07',\n", " '2025-01-06',\n", " '2025-01-03',\n", " '2025-01-02',\n", " '2024-12-31',\n", " '2024-12-30',\n", " '2024-12-27',\n", " '2024-12-24',\n", " '2024-12-23',\n", " '2024-12-20',\n", " '2024-12-19',\n", " '2024-12-18',\n", " '2024-12-17',\n", " '2024-12-16',\n", " '2024-12-13',\n", " '2024-12-12',\n", " '2024-12-11',\n", " '2024-12-10',\n", " '2024-12-09',\n", " '2024-12-06',\n", " '2024-12-05',\n", " '2024-12-04',\n", " '2024-12-03',\n", " '2024-12-02',\n", " '2024-11-29',\n", " '2024-11-28',\n", " '2024-11-27',\n", " '2024-11-26',\n", " '2024-11-25',\n", " '2024-11-22',\n", " '2024-11-21',\n", " '2024-11-20',\n", " '2024-11-19',\n", " '2024-11-18',\n", " '2024-11-15',\n", " '2024-11-14',\n", " '2024-11-13',\n", " '2024-11-12',\n", " '2024-11-11',\n", " '2024-11-08',\n", " '2024-11-07',\n", " '2024-11-06',\n", " '2024-11-05',\n", " '2024-11-04',\n", " '2024-11-01',\n", " '2024-10-31',\n", " '2024-10-30',\n", " '2024-10-29',\n", " '2024-10-28',\n", " '2024-10-25',\n", " '2024-10-24',\n", " '2024-10-23',\n", " '2024-10-22',\n", " '2024-10-21',\n", " '2024-10-18',\n", " '2024-10-17',\n", " '2024-10-16',\n", " '2024-10-15',\n", " '2024-10-14',\n", " '2024-10-11',\n", " '2024-10-10',\n", " '2024-10-09',\n", " '2024-10-08',\n", " '2024-10-07',\n", " '2024-10-04',\n", " '2024-10-03',\n", " '2024-10-02',\n", " '2024-10-01',\n", " '2024-09-30',\n", " '2024-09-27',\n", " '2024-09-26',\n", " '2024-09-25',\n", " '2024-09-24',\n", " '2024-09-23',\n", " '2024-09-20',\n", " '2024-09-19',\n", " '2024-09-18',\n", " '2024-09-17',\n", " '2024-09-16',\n", " '2024-09-13',\n", " '2024-09-12',\n", " '2024-09-11',\n", " '2024-09-10',\n", " '2024-09-09',\n", " '2024-09-06',\n", " '2024-09-05',\n", " '2024-09-04',\n", " '2024-09-03',\n", " '2024-09-02',\n", " '2024-08-30',\n", " '2024-08-29',\n", " '2024-08-28',\n", " '2024-08-27',\n", " '2024-08-23',\n", " '2024-08-22',\n", " '2024-08-21',\n", " '2024-08-20',\n", " '2024-08-19',\n", " '2024-08-16',\n", " '2024-08-15',\n", " '2024-08-14',\n", " '2024-08-13',\n", " '2024-08-12',\n", " '2024-08-09',\n", " '2024-08-08',\n", " '2024-08-07',\n", " '2024-08-06',\n", " '2024-08-05',\n", " '2024-08-02',\n", " '2024-08-01',\n", " '2024-07-31',\n", " '2024-07-30',\n", " '2024-07-29',\n", " '2024-07-26',\n", " '2024-07-25',\n", " '2024-07-24',\n", " '2024-07-23',\n", " '2024-07-22',\n", " '2024-07-19',\n", " '2024-07-18',\n", " '2024-07-17',\n", " '2024-07-16',\n", " '2024-07-15',\n", " '2024-07-12',\n", " '2024-07-11',\n", " '2024-07-10',\n", " '2024-07-09',\n", " '2024-07-08',\n", " '2024-07-05',\n", " '2024-07-04',\n", " '2024-07-03',\n", " '2024-07-02',\n", " '2024-07-01',\n", " '2024-06-28',\n", " '2024-06-27',\n", " '2024-06-26',\n", " '2024-06-25',\n", " '2024-06-24',\n", " '2024-06-21',\n", " '2024-06-20',\n", " '2024-06-19',\n", " '2024-06-18',\n", " '2024-06-17',\n", " '2024-06-14',\n", " '2024-06-13',\n", " '2024-06-12',\n", " '2024-06-11',\n", " '2024-06-10',\n", " '2024-06-07',\n", " '2024-06-06',\n", " '2024-06-05',\n", " '2024-06-04',\n", " '2024-06-03',\n", " '2024-05-31',\n", " '2024-05-30',\n", " '2024-05-29',\n", " '2024-05-28',\n", " '2024-05-24',\n", " '2024-05-23',\n", " '2024-05-22',\n", " '2024-05-21',\n", " '2024-05-20',\n", " '2024-05-17',\n", " '2024-05-16',\n", " '2024-05-15',\n", " '2024-05-14',\n", " '2024-05-13',\n", " '2024-05-10',\n", " '2024-05-09',\n", " '2024-05-08',\n", " '2024-05-07',\n", " '2024-05-03',\n", " '2024-05-02',\n", " '2024-05-01',\n", " '2024-04-30',\n", " '2024-04-29',\n", " '2024-04-26',\n", " '2024-04-25',\n", " '2024-04-24',\n", " '2024-04-23',\n", " '2024-04-22',\n", " '2024-04-19',\n", " '2024-04-18',\n", " '2024-04-17',\n", " '2024-04-16',\n", " '2024-04-15',\n", " '2024-04-12',\n", " '2024-04-11',\n", " '2024-04-10',\n", " '2024-04-09',\n", " '2024-04-08',\n", " '2024-04-05',\n", " '2024-04-04',\n", " '2024-04-03',\n", " '2024-04-02',\n", " '2024-03-28',\n", " '2024-03-27',\n", " '2024-03-26',\n", " '2024-03-25',\n", " '2024-03-22',\n", " '2024-03-21',\n", " '2024-03-20',\n", " '2024-03-19',\n", " '2024-03-18',\n", " '2024-03-15',\n", " '2024-03-14',\n", " '2024-03-13',\n", " '2024-03-12',\n", " '2024-03-11',\n", " '2024-03-08',\n", " '2024-03-07',\n", " '2024-03-06',\n", " '2024-03-05',\n", " '2024-03-04',\n", " '2024-03-01',\n", " '2024-02-29',\n", " '2024-02-28',\n", " '2024-02-27',\n", " '2024-02-26',\n", " '2024-02-23',\n", " '2024-02-22',\n", " '2024-02-21',\n", " '2024-02-20',\n", " '2024-02-19',\n", " '2024-02-16',\n", " '2024-02-15',\n", " '2024-02-14',\n", " '2024-02-13',\n", " '2024-02-12',\n", " '2024-02-09',\n", " '2024-02-08',\n", " '2024-02-07',\n", " '2024-02-06',\n", " '2024-02-05',\n", " '2024-02-02',\n", " '2024-02-01',\n", " '2024-01-31',\n", " '2024-01-30',\n", " '2024-01-29',\n", " '2024-01-26',\n", " '2024-01-25',\n", " '2024-01-24',\n", " '2024-01-23',\n", " '2024-01-22',\n", " '2024-01-19',\n", " '2024-01-18',\n", " '2024-01-17',\n", " '2024-01-16',\n", " '2024-01-15',\n", " '2024-01-12',\n", " '2024-01-11',\n", " '2024-01-10',\n", " '2024-01-09',\n", " '2024-01-08',\n", " '2024-01-05',\n", " '2024-01-04',\n", " '2024-01-03',\n", " '2024-01-02',\n", " '2023-12-29',\n", " '2023-12-28',\n", " '2023-12-27',\n", " '2023-12-22',\n", " '2023-12-21',\n", " '2023-12-20',\n", " '2023-12-19',\n", " '2023-12-18',\n", " '2023-12-15',\n", " '2023-12-14',\n", " '2023-12-13',\n", " '2023-12-12',\n", " '2023-12-11',\n", " '2023-12-08',\n", " '2023-12-07',\n", " '2023-12-06',\n", " '2023-12-05',\n", " '2023-12-04',\n", " '2023-12-01',\n", " '2023-11-30',\n", " '2023-11-29',\n", " '2023-11-28',\n", " '2023-11-27',\n", " '2023-11-24',\n", " '2023-11-23',\n", " '2023-11-22',\n", " '2023-11-21',\n", " '2023-11-20',\n", " '2023-11-17',\n", " '2023-11-16',\n", " '2023-11-15',\n", " '2023-11-14',\n", " '2023-11-13',\n", " '2023-11-10',\n", " '2023-11-09',\n", " '2023-11-08',\n", " '2023-11-07',\n", " '2023-11-06',\n", " '2023-11-03',\n", " '2023-11-02',\n", " '2023-11-01',\n", " '2023-10-31',\n", " '2023-10-30',\n", " '2023-10-27',\n", " '2023-10-26',\n", " '2023-10-25',\n", " '2023-10-24',\n", " '2023-10-23',\n", " '2023-10-20',\n", " '2023-10-19',\n", " '2023-10-18',\n", " '2023-10-17',\n", " '2023-10-16',\n", " '2023-10-13',\n", " '2023-10-12',\n", " '2023-10-11',\n", " '2023-10-10',\n", " '2023-10-09',\n", " '2023-10-06',\n", " '2023-10-05',\n", " '2023-10-04',\n", " '2023-10-03',\n", " '2023-10-02',\n", " '2023-09-29',\n", " '2023-09-28',\n", " '2023-09-27',\n", " '2023-09-26',\n", " '2023-09-25',\n", " '2023-09-22',\n", " '2023-09-21',\n", " '2023-09-20',\n", " '2023-09-19',\n", " '2023-09-18',\n", " '2023-09-15',\n", " '2023-09-14',\n", " '2023-09-13',\n", " '2023-09-12',\n", " '2023-09-11',\n", " '2023-09-08',\n", " '2023-09-07',\n", " '2023-09-06',\n", " '2023-09-05',\n", " '2023-09-04',\n", " '2023-09-01',\n", " '2023-08-31',\n", " '2023-08-30',\n", " '2023-08-29',\n", " '2023-08-25',\n", " '2023-08-24',\n", " '2023-08-23',\n", " '2023-08-22',\n", " '2023-08-21',\n", " '2023-08-18',\n", " '2023-08-17',\n", " '2023-08-16',\n", " '2023-08-15',\n", " '2023-08-14',\n", " '2023-08-11',\n", " '2023-08-10',\n", " '2023-08-09',\n", " '2023-08-08',\n", " '2023-08-07',\n", " '2023-08-04',\n", " '2023-08-03',\n", " '2023-08-02',\n", " '2023-08-01',\n", " '2023-07-31',\n", " '2023-07-28',\n", " '2023-07-27',\n", " '2023-07-26',\n", " '2023-07-25',\n", " '2023-07-24',\n", " '2023-07-21',\n", " '2023-07-20',\n", " '2023-07-19',\n", " '2023-07-18',\n", " '2023-07-17',\n", " '2023-07-14',\n", " '2023-07-13',\n", " '2023-07-12',\n", " '2023-07-11',\n", " '2023-07-10',\n", " '2023-07-07',\n", " '2023-07-06',\n", " '2023-07-05',\n", " '2023-07-04',\n", " '2023-07-03',\n", " '2023-06-30',\n", " '2023-06-29',\n", " '2023-06-28',\n", " '2023-06-27',\n", " '2023-06-26',\n", " '2023-06-23',\n", " '2023-06-22',\n", " '2023-06-21',\n", " '2023-06-20',\n", " '2023-06-19',\n", " '2023-06-16',\n", " '2023-06-15',\n", " '2023-06-14',\n", " '2023-06-13',\n", " '2023-06-12',\n", " '2023-06-09',\n", " '2023-06-08',\n", " '2023-06-07',\n", " '2023-06-06',\n", " '2023-06-05',\n", " '2023-06-02',\n", " '2023-06-01',\n", " '2023-05-31',\n", " '2023-05-30',\n", " '2023-05-26',\n", " '2023-05-25',\n", " '2023-05-24',\n", " '2023-05-23',\n", " '2023-05-22',\n", " '2023-05-19',\n", " '2023-05-18',\n", " '2023-05-17',\n", " '2023-05-16',\n", " '2023-05-15',\n", " '2023-05-12',\n", " '2023-05-11',\n", " '2023-05-10',\n", " '2023-05-09',\n", " '2023-05-05',\n", " '2023-05-04',\n", " '2023-05-03',\n", " '2023-05-02',\n", " '2023-04-28',\n", " '2023-04-27',\n", " '2023-04-26',\n", " '2023-04-25',\n", " '2023-04-24',\n", " '2023-04-21',\n", " '2023-04-20',\n", " '2023-04-19',\n", " '2023-04-18',\n", " '2023-04-17',\n", " '2023-04-14',\n", " '2023-04-13',\n", " '2023-04-12',\n", " '2023-04-11',\n", " '2023-04-06',\n", " '2023-04-05',\n", " '2023-04-04',\n", " '2023-04-03',\n", " '2023-03-31',\n", " '2023-03-30',\n", " '2023-03-29',\n", " '2023-03-28',\n", " '2023-03-27',\n", " '2023-03-24',\n", " '2023-03-23',\n", " '2023-03-22',\n", " '2023-03-21',\n", " '2023-03-20',\n", " '2023-03-17',\n", " '2023-03-16',\n", " '2023-03-15',\n", " '2023-03-14',\n", " '2023-03-13',\n", " '2023-03-10',\n", " '2023-03-09',\n", " '2023-03-08',\n", " '2023-03-07',\n", " '2023-03-06',\n", " '2023-03-03',\n", " '2023-03-02',\n", " '2023-03-01',\n", " '2023-02-28',\n", " '2023-02-27',\n", " '2023-02-24',\n", " '2023-02-23',\n", " '2023-02-22',\n", " '2023-02-21',\n", " '2023-02-20',\n", " '2023-02-17',\n", " '2023-02-16',\n", " '2023-02-15',\n", " '2023-02-14',\n", " '2023-02-13',\n", " '2023-02-10',\n", " '2023-02-09',\n", " '2023-02-08',\n", " '2023-02-07',\n", " '2023-02-06',\n", " '2023-02-03',\n", " '2023-02-02',\n", " '2023-02-01',\n", " '2023-01-31',\n", " '2023-01-30',\n", " '2023-01-27',\n", " '2023-01-26',\n", " '2023-01-25',\n", " '2023-01-24',\n", " '2023-01-23',\n", " '2023-01-20',\n", " '2023-01-19',\n", " '2023-01-18',\n", " '2023-01-17',\n", " '2023-01-16',\n", " '2023-01-13',\n", " '2023-01-12',\n", " '2023-01-11',\n", " '2023-01-10',\n", " '2023-01-09',\n", " '2023-01-06',\n", " '2023-01-05',\n", " '2023-01-04',\n", " '2023-01-03',\n", " '2022-12-30',\n", " '2022-12-29',\n", " '2022-12-28',\n", " '2022-12-23',\n", " '2022-12-22',\n", " '2022-12-21',\n", " '2022-12-20',\n", " '2022-12-19',\n", " '2022-12-16',\n", " '2022-12-15',\n", " '2022-12-14',\n", " '2022-12-13',\n", " '2022-12-12',\n", " '2022-12-09',\n", " '2022-12-08',\n", " '2022-12-07',\n", " '2022-12-06',\n", " '2022-12-05',\n", " '2022-12-02',\n", " '2022-12-01',\n", " '2022-11-30',\n", " '2022-11-29',\n", " '2022-11-28',\n", " '2022-11-25',\n", " '2022-11-24',\n", " '2022-11-23',\n", " '2022-11-22',\n", " '2022-11-21',\n", " '2022-11-18',\n", " '2022-11-17',\n", " '2022-11-16',\n", " '2022-11-15',\n", " '2022-11-14',\n", " '2022-11-11',\n", " '2022-11-10',\n", " '2022-11-09',\n", " '2022-11-08',\n", " '2022-11-07',\n", " '2022-11-04',\n", " '2022-11-03',\n", " '2022-11-02',\n", " '2022-11-01',\n", " '2022-10-31',\n", " '2022-10-28',\n", " '2022-10-27',\n", " '2022-10-26',\n", " '2022-10-25',\n", " '2022-10-24',\n", " '2022-10-21',\n", " '2022-10-20',\n", " '2022-10-19',\n", " '2022-10-18',\n", " '2022-10-17',\n", " '2022-10-14',\n", " '2022-10-13',\n", " '2022-10-12',\n", " '2022-10-11',\n", " '2022-10-10',\n", " '2022-10-07',\n", " '2022-10-06',\n", " '2022-10-05',\n", " '2022-10-04',\n", " '2022-10-03',\n", " '2022-09-30',\n", " '2022-09-29',\n", " '2022-09-28',\n", " '2022-09-27',\n", " '2022-09-26',\n", " '2022-09-23',\n", " '2022-09-22',\n", " '2022-09-21',\n", " '2022-09-20',\n", " '2022-09-16',\n", " '2022-09-15',\n", " '2022-09-14',\n", " '2022-09-13',\n", " '2022-09-12',\n", " '2022-09-09',\n", " '2022-09-08',\n", " '2022-09-07',\n", " '2022-09-06',\n", " '2022-09-05',\n", " '2022-09-02',\n", " '2022-09-01',\n", " '2022-08-31',\n", " '2022-08-30',\n", " '2022-08-26',\n", " '2022-08-25',\n", " '2022-08-24',\n", " '2022-08-23',\n", " '2022-08-22',\n", " '2022-08-19',\n", " '2022-08-18',\n", " '2022-08-17',\n", " '2022-08-16',\n", " '2022-08-15',\n", " '2022-08-12',\n", " '2022-08-11',\n", " '2022-08-10',\n", " '2022-08-09',\n", " '2022-08-08',\n", " '2022-08-05',\n", " '2022-08-04',\n", " '2022-08-03',\n", " '2022-08-02',\n", " '2022-08-01',\n", " '2022-07-29',\n", " '2022-07-28',\n", " '2022-07-27',\n", " '2022-07-26',\n", " '2022-07-25',\n", " '2022-07-22',\n", " '2022-07-21',\n", " '2022-07-20',\n", " '2022-07-19',\n", " '2022-07-18',\n", " '2022-07-15',\n", " '2022-07-14',\n", " '2022-07-13',\n", " '2022-07-12',\n", " '2022-07-11',\n", " '2022-07-08',\n", " '2022-07-07',\n", " '2022-07-06',\n", " '2022-07-05',\n", " '2022-07-04',\n", " '2022-07-01',\n", " '2022-06-30',\n", " '2022-06-29',\n", " '2022-06-28',\n", " '2022-06-27',\n", " '2022-06-24',\n", " '2022-06-23',\n", " '2022-06-22',\n", " '2022-06-21',\n", " '2022-06-20',\n", " '2022-06-17',\n", " '2022-06-16',\n", " '2022-06-15',\n", " '2022-06-14',\n", " '2022-06-13',\n", " '2022-06-10',\n", " '2022-06-09',\n", " '2022-06-08',\n", " '2022-06-07',\n", " '2022-06-06',\n", " '2022-06-01',\n", " '2022-05-31',\n", " '2022-05-30',\n", " '2022-05-27',\n", " '2022-05-26',\n", " '2022-05-25',\n", " '2022-05-24',\n", " '2022-05-23',\n", " '2022-05-20',\n", " '2022-05-19',\n", " '2022-05-18',\n", " '2022-05-17',\n", " '2022-05-16',\n", " '2022-05-13',\n", " '2022-05-12',\n", " '2022-05-11',\n", " '2022-05-10',\n", " '2022-05-09',\n", " '2022-05-06',\n", " '2022-05-05',\n", " '2022-05-04',\n", " '2022-05-03',\n", " '2022-04-29',\n", " '2022-04-28',\n", " '2022-04-27',\n", " '2022-04-26',\n", " '2022-04-25',\n", " '2022-04-22',\n", " '2022-04-21',\n", " '2022-04-20',\n", " '2022-04-19',\n", " '2022-04-14',\n", " '2022-04-13',\n", " '2022-04-12',\n", " '2022-04-11',\n", " '2022-04-08',\n", " '2022-04-07',\n", " '2022-04-06',\n", " '2022-04-05',\n", " '2022-04-04',\n", " '2022-04-01',\n", " '2022-03-31',\n", " '2022-03-30',\n", " '2022-03-29',\n", " '2022-03-28',\n", " '2022-03-25',\n", " '2022-03-24',\n", " '2022-03-23',\n", " '2022-03-22',\n", " '2022-03-21',\n", " '2022-03-18',\n", " '2022-03-17',\n", " '2022-03-16',\n", " '2022-03-15',\n", " '2022-03-14',\n", " '2022-03-11',\n", " '2022-03-10',\n", " '2022-03-09',\n", " '2022-03-08',\n", " '2022-03-07',\n", " '2022-03-04',\n", " '2022-03-03',\n", " '2022-03-02',\n", " '2022-03-01',\n", " '2022-02-28',\n", " '2022-02-25',\n", " '2022-02-24',\n", " '2022-02-23',\n", " '2022-02-22',\n", " '2022-02-21',\n", " '2022-02-18',\n", " '2022-02-17',\n", " '2022-02-16',\n", " '2022-02-15',\n", " '2022-02-14',\n", " '2022-02-11',\n", " '2022-02-10',\n", " '2022-02-09',\n", " '2022-02-08',\n", " '2022-02-07',\n", " '2022-02-04',\n", " '2022-02-03',\n", " '2022-02-02',\n", " '2022-02-01',\n", " '2022-01-31',\n", " '2022-01-28',\n", " '2022-01-27',\n", " '2022-01-26',\n", " '2022-01-25',\n", " '2022-01-24',\n", " '2022-01-21',\n", " '2022-01-20',\n", " '2022-01-19',\n", " '2022-01-18',\n", " '2022-01-17',\n", " '2022-01-14',\n", " '2022-01-13',\n", " '2022-01-12',\n", " '2022-01-11',\n", " '2022-01-10',\n", " '2022-01-07',\n", " '2022-01-06',\n", " '2022-01-05',\n", " '2022-01-04',\n", " '2021-12-30',\n", " '2021-12-29',\n", " '2021-12-23',\n", " '2021-12-22',\n", " '2021-12-21',\n", " '2021-12-20',\n", " '2021-12-17',\n", " '2021-12-16',\n", " '2021-12-15',\n", " '2021-12-14',\n", " '2021-12-13',\n", " '2021-12-10',\n", " '2021-12-09',\n", " '2021-12-08',\n", " '2021-12-07',\n", " '2021-12-06',\n", " '2021-12-03',\n", " '2021-12-02',\n", " '2021-12-01',\n", " '2021-11-30',\n", " '2021-11-29',\n", " '2021-11-26',\n", " '2021-11-25',\n", " '2021-11-24',\n", " '2021-11-23',\n", " '2021-11-22',\n", " '2021-11-19',\n", " '2021-11-18',\n", " '2021-11-17',\n", " '2021-11-16',\n", " '2021-11-15',\n", " '2021-11-12',\n", " '2021-11-11',\n", " '2021-11-10',\n", " '2021-11-09',\n", " '2021-11-08',\n", " '2021-11-05',\n", " '2021-11-04',\n", " '2021-11-03',\n", " '2021-11-02',\n", " '2021-11-01',\n", " '2021-10-29',\n", " '2021-10-28',\n", " '2021-10-27',\n", " '2021-10-26',\n", " '2021-10-25',\n", " '2021-10-22',\n", " '2021-10-21',\n", " '2021-10-20',\n", " '2021-10-19',\n", " '2021-10-18',\n", " '2021-10-15',\n", " '2021-10-14',\n", " '2021-10-13',\n", " '2021-10-12',\n", " '2021-10-11',\n", " '2021-10-08',\n", " '2021-10-07',\n", " '2021-10-06',\n", " '2021-10-05',\n", " '2021-10-04',\n", " '2021-10-01',\n", " '2021-09-30',\n", " '2021-09-29',\n", " '2021-09-28',\n", " '2021-09-27',\n", " '2021-09-24',\n", " '2021-09-23',\n", " '2021-09-22',\n", " '2021-09-21',\n", " '2021-09-20',\n", " '2021-09-17',\n", " '2021-09-16',\n", " '2021-09-15',\n", " '2021-09-14',\n", " '2021-09-13',\n", " '2021-09-10',\n", " '2021-09-09',\n", " '2021-09-08',\n", " '2021-09-07',\n", " '2021-09-06',\n", " '2021-09-03',\n", " '2021-09-02',\n", " '2021-09-01'],\n", " 'ladenBallastDays': [[0, 0],\n", " [1, 1],\n", " [4, 4],\n", " [7, 7],\n", " [10, 10],\n", " [15, 15],\n", " [20, 20]]}}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Shows the structure of the raw dictionary called\n", "dicto1" ] }, { "cell_type": "markdown", "id": "91809a58", "metadata": {}, "source": [ "### Reformatting\n", "\n", "For a more accessible data format, we filter the data to only retrieve ports that have available Netbacks data. We then reformat this into a DataFrame." ] }, { "cell_type": "code", "execution_count": 8, "id": "aaefce45", "metadata": {}, "outputs": [], "source": [ "# Define formatting data function\n", "def format_store(available_via, fob_names, tickrs):\n", " dict_store = {\n", " \"Index\": [],\n", " \"Callable Ports\": [],\n", " \"Corresponding Ticker\": [],\n", " \"Available Via\": []\n", " }\n", " \n", " c = 0\n", " for a in available_via:\n", " ## Check which routes have non-empty Netbacks data and save indices\n", " if len(a) != 0:\n", " dict_store['Index'].append(c)\n", "\n", " # Use these indices to retrive the corresponding Netbacks info\n", " dict_store['Callable Ports'].append(fob_names[c])\n", " dict_store['Corresponding Ticker'].append(tickrs[c])\n", " dict_store['Available Via'].append(available_via[c])\n", " c += 1\n", " # Show available Netbacks ports in a DataFrame (with corresponding indices)\n", " dict_df = pd.DataFrame(dict_store)\n", " return dict_df" ] }, { "cell_type": "code", "execution_count": 9, "id": "9e461158", "metadata": {}, "outputs": [], "source": [ "# Run formatting data function\n", "available_df = format_store(availablevia,fobPort_names,tickers)" ] }, { "cell_type": "code", "execution_count": 10, "id": "b78f47f6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IndexCallable PortsCorresponding TickerAvailable Via
00Wheatstone00398967-3ee1-4b26-bcdb-805ad19dbcce[suez, None]
11Woodfibre LNG00314d16-eada-4f37-bff3-d844708aeb45[panama, None]
22Corpus Christi0030c461-9a63-403d-8f53-9327ea773517[cogh, panama, suez, None]
33Bintulu003342b7-ba5b-4f0e-b6df-4d95837a5691[suez, None]
44Lake Charles003ff22f-77d8-413f-9997-2c6280e7c28c[cogh, panama, suez, None]
\n", "
" ], "text/plain": [ " Index Callable Ports Corresponding Ticker \\\n", "0 0 Wheatstone 00398967-3ee1-4b26-bcdb-805ad19dbcce \n", "1 1 Woodfibre LNG 00314d16-eada-4f37-bff3-d844708aeb45 \n", "2 2 Corpus Christi 0030c461-9a63-403d-8f53-9327ea773517 \n", "3 3 Bintulu 003342b7-ba5b-4f0e-b6df-4d95837a5691 \n", "4 4 Lake Charles 003ff22f-77d8-413f-9997-2c6280e7c28c \n", "\n", " Available Via \n", "0 [suez, None] \n", "1 [panama, None] \n", "2 [cogh, panama, suez, None] \n", "3 [suez, None] \n", "4 [cogh, panama, suez, None] " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# View some of the dataframe\n", "available_df.head()" ] }, { "cell_type": "markdown", "id": "e447d6b2", "metadata": {}, "source": [ "## Fetching Netbacks Data specific to one port\n", "\n", "Now that we can see all the available Netbacks data available to us, we can start to define what ports we want to call Netbacks data for (by referring to 'available_df' above).\n", "\n", "The first step is to choose which port ID ('my_ticker') and which price release date ('my_release') we want. We check what possible routes are available for this port ('possible_via') and then choose one ('my_via').\n", "\n", "__This is where you should input the specific Netbacks parameters you want to see__\n", "\n", "### N.B. Plan Limits\n", "\n", "__Premium__ Users can choose any release date, as they have full access to the dataset.\n", "\n", "__Trial__ Users must not exceed 'reldates[13]' as they are limited to the latest 2 weeks' datapoints." ] }, { "cell_type": "code", "execution_count": 11, "id": "a4480909", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "003e8539-3a98-48fa-b35d-0ba061beea4e\n", "2025-01-14\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/v3/5pn2lssn077ch9xm2rttdmym0000gn/T/ipykernel_6871/215422504.py:5: FutureWarning: Calling int on a single element Series is deprecated and will raise a TypeError in the future. Use int(ser.iloc[0]) instead\n", " ti = int(available_df[available_df[\"Callable Ports\"] == port][\"Index\"])\n" ] } ], "source": [ "# Choose route ID and price release date\n", "\n", "# Here we define which port we want\n", "port = \"Cove Point\"\n", "ti = int(available_df[available_df[\"Callable Ports\"] == port][\"Index\"])\n", "my_ticker = tickers[ti]\n", "my_release = reldates[0]\n", "\n", "print(my_ticker)\n", "print(my_release)" ] }, { "cell_type": "code", "execution_count": 12, "id": "cae8ec64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['cogh', 'panama', 'suez', None]\n" ] } ], "source": [ "# See possible route passage options\n", "possible_via = availablevia[tickers.index(my_ticker)]\n", "print(possible_via)" ] }, { "cell_type": "code", "execution_count": 13, "id": "c21d6991", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cogh\n" ] } ], "source": [ "# Choose route passage\n", "my_via = possible_via[0]\n", "print(my_via)" ] }, { "cell_type": "markdown", "id": "2d1bf4c0", "metadata": {}, "source": [ "## Defining the Function\n", "\n", "We now define the function needed to call this data.\n", "\n", "Again, we define what type of data we want to fetch from the API.\n", "\n", "In the fetch request, we use the URL:\n", "\n", "__uri=\"/v1.0/netbacks/\"__\n", "\n", "We then print the output.\n", "\n", "__This function does not need to be altered by the user.__" ] }, { "cell_type": "code", "execution_count": 14, "id": "eb563eb4", "metadata": {}, "outputs": [], "source": [ "## Defining the function\n", "\n", "\n", "def fetch_netback(access_token, ticker, release, via=None, laden=None, ballast=None):\n", " \"\"\"\n", " For a route, fetch then display the route details\n", "\n", " # Procedure:\n", "\n", " Do GET queries to https://api.sparkcommodities.com/v1.0/routes/{route_uuid}/\n", " with a Bearer token authorization HTTP header.\n", " \"\"\"\n", " \n", " query_params = \"?fob-port={}\".format(ticker)\n", " if release is not None:\n", " query_params += \"&release-date={}\".format(release)\n", " if via is not None:\n", " query_params += \"&via-point={}\".format(via)\n", " if laden is not None:\n", " query_params += \"&laden-congestion-days={}\".format(laden)\n", " if ballast is not None:\n", " query_params += \"&ballast-congestion-days={}\".format(ballast)\n", " \n", " \n", " content = do_api_get_query(\n", " uri=\"/v1.0/netbacks/{}\".format(query_params),\n", " access_token=access_token,\n", " )\n", " \n", " my_dict = content['data']\n", "\n", " return my_dict\n", "\n", "\n", "## Calling that function and storing the output\n", "\n", "my_dict = fetch_netback(access_token, my_ticker, release=my_release, via=my_via)" ] }, { "cell_type": "code", "execution_count": 15, "id": "e009a633", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'name': 'Cove Point',\n", " 'releaseDate': '2025-01-14',\n", " 'viaPoint': 'cogh',\n", " 'congestionLadenDays': 0,\n", " 'congestionBallastDays': 0,\n", " 'netbacks': [{'monthIdx': 1,\n", " 'load': {'month': '2025-02', 'loadingDate': '2025-02-15'},\n", " 'neaCargoDeliveryDate': '2025-03-29',\n", " 'nweCargoDeliveryDate': '2025-03-01',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.526'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.638'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.361'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.803'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.361'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.803'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.835'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.835'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.208'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.148'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.06'},\n", " 'routeCost': {'usdPerMMBtu': '0.614'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.92'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.526'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.638'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.178'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.28'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.898'},\n", " 'routeCost': {'usdPerMMBtu': '0.269'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.268'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.361'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.803'}}},\n", " {'monthIdx': 2,\n", " 'load': {'month': '2025-03', 'loadingDate': '2025-03-15'},\n", " 'neaCargoDeliveryDate': '2025-04-26',\n", " 'nweCargoDeliveryDate': '2025-03-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.56'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.632'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.389'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.803'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.389'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.803'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.829'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.829'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.244'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.159'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.085'},\n", " 'routeCost': {'usdPerMMBtu': '0.603'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.922'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.56'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.632'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.208'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.267'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.941'},\n", " 'routeCost': {'usdPerMMBtu': '0.283'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.269'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.389'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.803'}}},\n", " {'monthIdx': 3,\n", " 'load': {'month': '2025-04', 'loadingDate': '2025-04-15'},\n", " 'neaCargoDeliveryDate': '2025-05-27',\n", " 'nweCargoDeliveryDate': '2025-04-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.679'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.548'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.437'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.79'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.437'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.79'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.758'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.758'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.293'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.118'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.175'},\n", " 'routeCost': {'usdPerMMBtu': '0.565'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.931'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.679'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.548'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.248'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.27'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.978'},\n", " 'routeCost': {'usdPerMMBtu': '0.271'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.27'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.437'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.79'}}},\n", " {'monthIdx': 4,\n", " 'load': {'month': '2025-05', 'loadingDate': '2025-05-15'},\n", " 'neaCargoDeliveryDate': '2025-06-26',\n", " 'nweCargoDeliveryDate': '2025-05-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.779'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.494'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.498'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.775'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.498'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.775'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.719'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.719'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.331'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.054'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.277'},\n", " 'routeCost': {'usdPerMMBtu': '0.56'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.938'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.779'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.494'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.296'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.27'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.026'},\n", " 'routeCost': {'usdPerMMBtu': '0.257'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.271'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.498'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.775'}}},\n", " {'monthIdx': 5,\n", " 'load': {'month': '2025-06', 'loadingDate': '2025-06-15'},\n", " 'neaCargoDeliveryDate': '2025-07-27',\n", " 'nweCargoDeliveryDate': '2025-06-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.863'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.462'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.536'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.789'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.536'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.789'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.673'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.673'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.345'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.044'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.389'},\n", " 'routeCost': {'usdPerMMBtu': '0.582'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.944'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.863'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.462'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.333'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.268'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.065'},\n", " 'routeCost': {'usdPerMMBtu': '0.257'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.272'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.536'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.789'}}},\n", " {'monthIdx': 6,\n", " 'load': {'month': '2025-07', 'loadingDate': '2025-07-15'},\n", " 'neaCargoDeliveryDate': '2025-08-26',\n", " 'nweCargoDeliveryDate': '2025-07-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.867'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.475'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.538'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.804'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.538'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.804'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.671'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.671'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.367'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.087'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.454'},\n", " 'routeCost': {'usdPerMMBtu': '0.642'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.945'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.867'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.475'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.346'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.267'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.079'},\n", " 'routeCost': {'usdPerMMBtu': '0.269'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.272'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.538'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.804'}}},\n", " {'monthIdx': 7,\n", " 'load': {'month': '2025-08', 'loadingDate': '2025-08-15'},\n", " 'neaCargoDeliveryDate': '2025-09-26',\n", " 'nweCargoDeliveryDate': '2025-08-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.718'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.633'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.547'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.804'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.547'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.804'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.829'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.829'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '14.292'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.106'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.398'},\n", " 'routeCost': {'usdPerMMBtu': '0.746'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.934'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.718'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.633'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.371'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.275'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.096'},\n", " 'routeCost': {'usdPerMMBtu': '0.277'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.272'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.547'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.804'}}},\n", " {'monthIdx': 8,\n", " 'load': {'month': '2025-09', 'loadingDate': '2025-09-15'},\n", " 'neaCargoDeliveryDate': '2025-10-27',\n", " 'nweCargoDeliveryDate': '2025-09-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.346'},\n", " 'ttfBasis': {'usdPerMMBtu': '-2.049'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.404'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.991'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.404'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.991'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-1.058'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.058'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '13.994'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.152'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.146'},\n", " 'routeCost': {'usdPerMMBtu': '0.894'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.906'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.346'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-2.049'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '14.264'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.28'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.984'},\n", " 'routeCost': {'usdPerMMBtu': '0.311'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.269'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.404'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.991'}}},\n", " {'monthIdx': 9,\n", " 'load': {'month': '2025-10', 'loadingDate': '2025-10-15'},\n", " 'neaCargoDeliveryDate': '2025-11-26',\n", " 'nweCargoDeliveryDate': '2025-10-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.123'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.992'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '13.065'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.05'}},\n", " 'max': {'outright': {'usdPerMMBtu': '13.065'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.05'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.942'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.942'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '13.776'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.301'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.077'},\n", " 'routeCost': {'usdPerMMBtu': '1.064'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.89'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.123'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.992'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '13.974'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.287'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.687'},\n", " 'routeCost': {'usdPerMMBtu': '0.36'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.262'},\n", " 'netbackOutright': {'usdPerMMBtu': '13.065'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.05'}}},\n", " {'monthIdx': 10,\n", " 'load': {'month': '2025-11', 'loadingDate': '2025-11-15'},\n", " 'neaCargoDeliveryDate': '2025-12-27',\n", " 'nweCargoDeliveryDate': '2025-11-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '12.106'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.697'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '12.821'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.982'}},\n", " 'max': {'outright': {'usdPerMMBtu': '12.821'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.982'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.715'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.715'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '13.71'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.48'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.19'},\n", " 'routeCost': {'usdPerMMBtu': '1.195'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.889'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.106'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.697'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '13.769'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.29'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.479'},\n", " 'routeCost': {'usdPerMMBtu': '0.401'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.257'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.821'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-0.982'}}},\n", " {'monthIdx': 11,\n", " 'load': {'month': '2025-12', 'loadingDate': '2025-12-15'},\n", " 'neaCargoDeliveryDate': '2026-01-26',\n", " 'nweCargoDeliveryDate': '2025-12-29',\n", " 'nea': {'outright': {'usdPerMMBtu': '11.948'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.782'}},\n", " 'nwe': {'outright': {'usdPerMMBtu': '12.72'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.01'}},\n", " 'max': {'outright': {'usdPerMMBtu': '12.72'},\n", " 'ttfBasis': {'usdPerMMBtu': '-1.01'}},\n", " 'neaMinusNwe': {'outright': {'usdPerMMBtu': '-0.772'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.772'}},\n", " 'neaMeta': {'ttfPrice': {'usdPerMMBtu': '13.629'},\n", " 'ttfBasis': {'usdPerMMBtu': '0.49'},\n", " 'desLngPrice': {'usdPerMMBtu': '14.119'},\n", " 'routeCost': {'usdPerMMBtu': '1.294'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.877'},\n", " 'netbackOutright': {'usdPerMMBtu': '11.948'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.782'}},\n", " 'nweMeta': {'ttfPrice': {'usdPerMMBtu': '13.707'},\n", " 'ttfBasis': {'usdPerMMBtu': '-0.285'},\n", " 'desLngPrice': {'usdPerMMBtu': '13.422'},\n", " 'routeCost': {'usdPerMMBtu': '0.447'},\n", " 'volumeAdjustment': {'usdPerMMBtu': '-0.255'},\n", " 'netbackOutright': {'usdPerMMBtu': '12.72'},\n", " 'netbackTtfBasis': {'usdPerMMBtu': '-1.01'}}}],\n", " 'neaAssumptions': {'fobPort': {'uuid': '003e8539-3a98-48fa-b35d-0ba061beea4e',\n", " 'name': 'Cove Point'},\n", " 'dischargePort': {'name': 'Futtsu'},\n", " 'viaPoint': 'cogh',\n", " 'nauticalMiles': '15227',\n", " 'vesselSizeM3': 174000,\n", " 'vesselSpeedKnots': 17,\n", " 'daysUntilDelivery': 42},\n", " 'nweAssumptions': {'fobPort': {'uuid': '003e8539-3a98-48fa-b35d-0ba061beea4e',\n", " 'name': 'Cove Point'},\n", " 'dischargePort': {'name': 'Gate'},\n", " 'viaPoint': None,\n", " 'nauticalMiles': '3573',\n", " 'vesselSizeM3': 174000,\n", " 'vesselSpeedKnots': 17,\n", " 'daysUntilDelivery': 14}}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Displaying the raw output\n", "my_dict" ] }, { "cell_type": "markdown", "id": "16fb96d1", "metadata": {}, "source": [ "## Formatting\n", "\n", "Here we format the raw output into a Pandas Dataframe. This is useful for plotting, netbacks analysis and comparisons." ] }, { "cell_type": "code", "execution_count": 17, "id": "d5c62acb", "metadata": {}, "outputs": [], "source": [ "# Defining function for storing and formating netback prices\n", "def format_store_netback(dict_netback):\n", " dict_store = {\n", " \"Period\": [],\n", " \"NEA Outrights\": [],\n", " \"NWE Outrights\": [],\n", " \"NEA TTF Basis\": [],\n", " \"NWE TTF Basis\": [],\n", " \"NEA-NWE Outrights\": [],\n", " \"NEA-NWE TTF Basis\": []\n", " }\n", "\n", " route_name = dict_netback[\"name\"]\n", "\n", " for m in dict_netback[\"netbacks\"]:\n", " dict_store['Period'].append(m[\"load\"][\"month\"])\n", "\n", " dict_store['NEA Outrights'].append(float(m[\"nea\"][\"outright\"][\"usdPerMMBtu\"]))\n", " dict_store['NEA TTF Basis'].append(float(m[\"nea\"][\"ttfBasis\"][\"usdPerMMBtu\"]))\n", "\n", " dict_store['NWE Outrights'].append(float(m[\"nwe\"][\"outright\"][\"usdPerMMBtu\"]))\n", " dict_store['NWE TTF Basis'].append(float(m[\"nwe\"][\"ttfBasis\"][\"usdPerMMBtu\"]))\n", "\n", " dict_store['NEA-NWE Outrights'].append(float(m[\"neaMinusNwe\"][\"outright\"][\"usdPerMMBtu\"]))\n", " dict_store['NEA-NWE TTF Basis'].append(float(m[\"neaMinusNwe\"][\"ttfBasis\"][\"usdPerMMBtu\"]))\n", "\n", " stored_df = pd.DataFrame(dict_store)\n", " return route_name, stored_df" ] }, { "cell_type": "code", "execution_count": 18, "id": "cde48ff9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PeriodNEA OutrightsNWE OutrightsNEA TTF BasisNWE TTF BasisNEA-NWE OutrightsNEA-NWE TTF Basis
02025-0212.52613.361-1.638-0.803-0.835-0.835
12025-0312.56013.389-1.632-0.803-0.829-0.829
22025-0412.67913.437-1.548-0.790-0.758-0.758
32025-0512.77913.498-1.494-0.775-0.719-0.719
42025-0612.86313.536-1.462-0.789-0.673-0.673
\n", "
" ], "text/plain": [ " Period NEA Outrights NWE Outrights NEA TTF Basis NWE TTF Basis \\\n", "0 2025-02 12.526 13.361 -1.638 -0.803 \n", "1 2025-03 12.560 13.389 -1.632 -0.803 \n", "2 2025-04 12.679 13.437 -1.548 -0.790 \n", "3 2025-05 12.779 13.498 -1.494 -0.775 \n", "4 2025-06 12.863 13.536 -1.462 -0.789 \n", "\n", " NEA-NWE Outrights NEA-NWE TTF Basis \n", "0 -0.835 -0.835 \n", "1 -0.829 -0.829 \n", "2 -0.758 -0.758 \n", "3 -0.719 -0.719 \n", "4 -0.673 -0.673 " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Store information in a DataFrame\n", "route_name, netbacks_df = format_store_netback(my_dict)\n", "\n", "netbacks_df.head()" ] }, { "cell_type": "markdown", "id": "b4652309", "metadata": {}, "source": [ "# Historical Data\n", "\n", "Defining a function to fetch historical data and store as a Dataframe\n", "\n", "The historical data call incorporates a \"time.sleep(0.5)\" function. This is needed if you're looking to pull more than 500 datapoints in an hour, as our API is rate-limited. For more information, please see our API Docs:\n", "\n", "https://api.sparkcommodities.com/redoc#section/Requests-and-Responses/Rate-Limits\n", "\n", "### N.B. Plan Limits\n", "\n", "__Premium__ Users can choose any release date, as they have full access to the dataset.\n", "\n", "__Trial__ Users must not exceed 'reldates[:13]' as they are limited to the latest 2 weeks' datapoints." ] }, { "cell_type": "code", "execution_count": 19, "id": "4bee1068", "metadata": {}, "outputs": [], "source": [ "## Plotting Netbacks in a similar style to the Spark Platform Netbacks Price Chart\n", "\n", "import time\n", "\n", "def netbacks_history(tick, reldates, my_via=None, laden =None, ballast=None):\n", "\n", " months = []\n", " nea_outrights = []\n", " nea_ttfbasis = []\n", " nwe_outrights = []\n", " nwe_ttfbasis = []\n", " delta_outrights = []\n", " delta_ttfbasis = []\n", " release_date = []\n", " \n", " port = []\n", "\n", " for r in reldates:\n", " try:\n", " my_dict = fetch_netback(access_token, tickers[tick], release=r, via=my_via, laden=laden, ballast=ballast)\n", " \n", " for m in my_dict['netbacks']:\n", "\n", " months.append(m['load']['month'])\n", "\n", " nea_outrights.append(float(m['nea']['outright']['usdPerMMBtu']))\n", " nea_ttfbasis.append(float(m['nea']['ttfBasis']['usdPerMMBtu']))\n", "\n", " nwe_outrights.append(float(m['nwe']['outright']['usdPerMMBtu']))\n", " nwe_ttfbasis.append(float(m['nwe']['ttfBasis']['usdPerMMBtu']))\n", "\n", " delta_outrights.append(float(m['neaMinusNwe']['outright']['usdPerMMBtu']))\n", " delta_ttfbasis.append(float(m['neaMinusNwe']['ttfBasis']['usdPerMMBtu']))\n", "\n", " release_date.append(my_dict['releaseDate'])\n", " port.append(fobPort_names[tick])\n", " \n", " except:\n", " print('Bad Date: ' + r)\n", " \n", " # Incorporating sleep function\n", " time.sleep(0.5)\n", " \n", " historical_df = pd.DataFrame({\n", " 'Release Date': release_date,\n", " 'FoB Port': port,\n", " 'Month': months,\n", " 'NEA Outrights': nea_outrights,\n", " 'NEA TTF Basis': nea_ttfbasis,\n", " 'NWE Outrights': nwe_outrights,\n", " 'NWE TTF Basis': nwe_ttfbasis,\n", " 'Delta Outrights': delta_outrights,\n", " 'Delta TTF Basis': delta_ttfbasis,\n", " })\n", " \n", " historical_df['Release Date'] = pd.to_datetime(historical_df['Release Date'])\n", " \n", " return historical_df\n" ] }, { "cell_type": "code", "execution_count": 20, "id": "4875854b", "metadata": {}, "outputs": [], "source": [ "via ='cogh'\n", "my_t = 'Sabine Pass'\n", "t = fobPort_names.index(my_t)\n", "\n", "my_rels = reldates[:2]\n", "\n", "df_cogh = netbacks_history(t, my_rels, my_via='cogh')\n", "df_panama = netbacks_history(t, my_rels, my_via='panama')" ] }, { "cell_type": "code", "execution_count": 20, "id": "346d919f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Release DateFoB PortMonthNEA OutrightsNEA TTF BasisNWE OutrightsNWE TTF BasisDelta OutrightsDelta TTF Basis
02024-10-16Sabine Pass2024-1111.581-0.93011.650-0.862-0.069-0.069
12024-10-16Sabine Pass2024-1211.622-1.05311.714-0.961-0.091-0.091
22024-10-16Sabine Pass2025-0111.396-1.39911.741-1.054-0.344-0.344
32024-10-16Sabine Pass2025-0211.026-1.83611.659-1.203-0.633-0.633
42024-10-16Sabine Pass2025-0310.916-1.85911.462-1.313-0.546-0.546
52024-10-16Sabine Pass2025-0411.026-1.37111.295-1.102-0.269-0.269
62024-10-16Sabine Pass2025-0511.146-1.14111.256-1.031-0.110-0.110
72024-10-16Sabine Pass2025-0611.164-1.09111.263-0.992-0.099-0.099
82024-10-16Sabine Pass2025-0711.111-1.16011.220-1.051-0.108-0.108
92024-10-16Sabine Pass2025-0810.990-1.28411.188-1.086-0.199-0.199
102024-10-16Sabine Pass2025-0910.830-1.49611.150-1.176-0.321-0.321
112024-10-15Sabine Pass2024-1111.802-0.97011.856-0.917-0.053-0.053
122024-10-15Sabine Pass2024-1211.872-1.05511.953-0.974-0.081-0.081
132024-10-15Sabine Pass2025-0111.656-1.39011.982-1.064-0.326-0.326
142024-10-15Sabine Pass2025-0211.265-1.84811.902-1.211-0.637-0.637
152024-10-15Sabine Pass2025-0311.116-1.90811.697-1.327-0.581-0.581
162024-10-15Sabine Pass2025-0411.230-1.40411.516-1.118-0.286-0.286
172024-10-15Sabine Pass2025-0511.391-1.12311.469-1.045-0.078-0.078
182024-10-15Sabine Pass2025-0611.399-1.06911.469-0.999-0.070-0.070
192024-10-15Sabine Pass2025-0711.326-1.16011.432-1.054-0.106-0.106
202024-10-15Sabine Pass2025-0811.183-1.30811.395-1.096-0.212-0.212
212024-10-15Sabine Pass2025-0911.026-1.51811.356-1.188-0.330-0.330
\n", "
" ], "text/plain": [ " Release Date FoB Port Month NEA Outrights NEA TTF Basis \\\n", "0 2024-10-16 Sabine Pass 2024-11 11.581 -0.930 \n", "1 2024-10-16 Sabine Pass 2024-12 11.622 -1.053 \n", "2 2024-10-16 Sabine Pass 2025-01 11.396 -1.399 \n", "3 2024-10-16 Sabine Pass 2025-02 11.026 -1.836 \n", "4 2024-10-16 Sabine Pass 2025-03 10.916 -1.859 \n", "5 2024-10-16 Sabine Pass 2025-04 11.026 -1.371 \n", "6 2024-10-16 Sabine Pass 2025-05 11.146 -1.141 \n", "7 2024-10-16 Sabine Pass 2025-06 11.164 -1.091 \n", "8 2024-10-16 Sabine Pass 2025-07 11.111 -1.160 \n", "9 2024-10-16 Sabine Pass 2025-08 10.990 -1.284 \n", "10 2024-10-16 Sabine Pass 2025-09 10.830 -1.496 \n", "11 2024-10-15 Sabine Pass 2024-11 11.802 -0.970 \n", "12 2024-10-15 Sabine Pass 2024-12 11.872 -1.055 \n", "13 2024-10-15 Sabine Pass 2025-01 11.656 -1.390 \n", "14 2024-10-15 Sabine Pass 2025-02 11.265 -1.848 \n", "15 2024-10-15 Sabine Pass 2025-03 11.116 -1.908 \n", "16 2024-10-15 Sabine Pass 2025-04 11.230 -1.404 \n", "17 2024-10-15 Sabine Pass 2025-05 11.391 -1.123 \n", "18 2024-10-15 Sabine Pass 2025-06 11.399 -1.069 \n", "19 2024-10-15 Sabine Pass 2025-07 11.326 -1.160 \n", "20 2024-10-15 Sabine Pass 2025-08 11.183 -1.308 \n", "21 2024-10-15 Sabine Pass 2025-09 11.026 -1.518 \n", "\n", " NWE Outrights NWE TTF Basis Delta Outrights Delta TTF Basis \n", "0 11.650 -0.862 -0.069 -0.069 \n", "1 11.714 -0.961 -0.091 -0.091 \n", "2 11.741 -1.054 -0.344 -0.344 \n", "3 11.659 -1.203 -0.633 -0.633 \n", "4 11.462 -1.313 -0.546 -0.546 \n", "5 11.295 -1.102 -0.269 -0.269 \n", "6 11.256 -1.031 -0.110 -0.110 \n", "7 11.263 -0.992 -0.099 -0.099 \n", "8 11.220 -1.051 -0.108 -0.108 \n", "9 11.188 -1.086 -0.199 -0.199 \n", "10 11.150 -1.176 -0.321 -0.321 \n", "11 11.856 -0.917 -0.053 -0.053 \n", "12 11.953 -0.974 -0.081 -0.081 \n", "13 11.982 -1.064 -0.326 -0.326 \n", "14 11.902 -1.211 -0.637 -0.637 \n", "15 11.697 -1.327 -0.581 -0.581 \n", "16 11.516 -1.118 -0.286 -0.286 \n", "17 11.469 -1.045 -0.078 -0.078 \n", "18 11.469 -0.999 -0.070 -0.070 \n", "19 11.432 -1.054 -0.106 -0.106 \n", "20 11.395 -1.096 -0.212 -0.212 \n", "21 11.356 -1.188 -0.330 -0.330 " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_cogh" ] }, { "cell_type": "markdown", "id": "d72f4eb0", "metadata": {}, "source": [ "# Analytics Gallery\n", "Want to gain market insights using our data?\n", "\n", "Take a look at our [Analytics Gallery](https://www.sparkcommodities.com/api/code-examples/analytics-examples.html) on the Spark API website, which includes:\n", "\n", "- __US Arb Monthly Tracker__ - Analyse the variations of the US Arb via COGH across multiple years.\n", "\n", "- __US Front Month Historical Arb__ - Explore how the historical US front month Arb has evolved over time and compare them across different via points (Panama, Suez, COGH).\n", "\n", "- __Regas Slots vs US Arb__ - See how the US Arb (M+1, M+2, M+3) correlates with monthly average slots for all European Terminals.\n", "__Note: This requires both Access and Cargo subscriptions.__\n", "\n", "\n", "Take a look at all our Analytics charts [here](https://www.sparkcommodities.com/api/code-examples/analytics-examples.html). \n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 5 }