Read Live Algorithm
Live Algorithm Statistics
Description
The response contains the most recent live deployment of the project. To read the deployments of a project, call the /live/list endpoint.
Responses
The /live/read API provides a response in the following format:
200 Success
LiveAlgorithmResults Model - Details a live algorithm from the live/read API endpoint. | |
|---|---|
| message | string Error message. |
| deployId | string Unique live algorithm deployment identifier (similar to a backtest id). |
| status | string Enum State of the live deployment. Options : ['DeployError', 'InQueue', 'Running', 'Stopped', 'Liquidated', 'Deleted', 'Completed', 'RuntimeError', 'Invalid', 'LoggingIn', 'Initializing', 'History'] |
| cloneId | integer The snapshot project Id for cloning the live development's source code. |
| launched | string($date-time) Datetime the first live deployment of the project started in UTC. To get the start time of this deployment, call the /live/list endpoint. |
| stopped | string($date-time) Datetime the algorithm was stopped in UTC, null if its still running. |
| brokerage | string Brokerage. |
| securityTypes | string Security types detected in the algorithm. |
| datacenter | string Name of the datacenter where the algorithm is physically located. |
| isPublicStreaming | boolean Flag to indicate if public streaming is enabled. |
| public | boolean Flag to indicate if the algorithm is public. |
| files | ProjectFile Array Files of the deployed algorithm. If the deployment has no files, this is an empty object instead of an array. |
| runtimeStatistics | RuntimeStatistics object Runtime banner/updating statistics in the title banner of the live algorithm GUI. It can be empty if the algorithm is not running. |
| serverStatistics | ServerStatistics object Status of the node that runs the live algorithm, including its CPU and RAM usage. It's empty if the algorithm is not running. |
| deploymentDetails | string object Details the brokerage, data provider or any other component shares about the deployment, like account information. It's omitted if the deployment reported none. |
| charts | ChartSummary object Contains the names of all charts. |
| projectName | string Name of the project the live algorithm is in. |
| success | boolean Indicate if the API request was successful. |
| errors | string Array List of errors with the API call. |
| Example |
{
"message": "string",
"deployId": "L-sdf86b7045bb83203e79d2aa6150b321",
"status": "DeployError",
"cloneId": 0,
"launched": "2021-11-26T15:18:27.693Z",
"stopped": "2021-11-26T15:18:27.693Z",
"brokerage": "string",
"securityTypes": "string",
"datacenter": "NY7",
"isPublicStreaming": true,
"public": true,
"files": [
{
"id": 0,
"projectId": 23456789,
"name": "string",
"content": "string",
"modified": "2021-11-26T15:18:27.693Z",
"open": true,
"isLibrary": true
}
],
"runtimeStatistics": {
"Equity": "$100.00",
"Fees": "-$100.00",
"Holdings": "$100.00",
"Net Profit": "$100.00",
"Probabilistic Sharpe Ratio": "50.00%",
"Return": "50.00%",
"Unrealized": "$100.00",
"Volume": "$100.00"
},
"serverStatistics": {
"CPU Usage": "0.0%",
"Used RAM (MB)": "241",
"Total RAM (MB)": "16384",
"Hostname": "BACKTESTING-48-b663526eb061eda8efa07d9bde55c24f",
"LEAN Version": "v2.5.0.0.18009",
"Up Time": "0d 00:00:03"
},
"deploymentDetails": {
"key": "string"
},
"charts": {
"name": "string"
},
"projectName": "string",
"success": true,
"errors": [
"string"
]
}
|
ProjectFile Model - File for a project. | |
|---|---|
| id | integer ID of the project file. This can also be null. |
| projectId | integer ID of the project. |
| name | string Name of a project file. |
| content | string Contents of the project file. |
| modified | string($date-time) DateTime project file was modified. |
| open | boolean Indicates if the project file is open or not. |
| isLibrary | boolean Indicates if the project file is a library or not. It's always false in live/read and backtest/read. |
| Example |
{
"id": 0,
"projectId": 23456789,
"name": "string",
"content": "string",
"modified": "2021-11-26T15:18:27.693Z",
"open": true,
"isLibrary": true
}
|
RuntimeStatistics Model | |
|---|---|
| Equity | string Total portfolio value. |
| Fees | string Transaction fee. |
| Holdings | string Equity value of security holdings. |
| Net Profit | string Net profit. |
| Probabilistic Sharpe Ratio | string Probabilistic Sharpe Ratio. |
| Return | string Return. |
| Unrealized | string Unrealized profit/loss. |
| Volume | string Total transaction volume. |
| Example |
{
"Equity": "$100.00",
"Fees": "-$100.00",
"Holdings": "$100.00",
"Net Profit": "$100.00",
"Probabilistic Sharpe Ratio": "50.00%",
"Return": "50.00%",
"Unrealized": "$100.00",
"Volume": "$100.00"
}
|
ServerStatistics Model | |
|---|---|
| CPU Usage | string Percentage of the node CPU in use. |
| Used RAM (MB) | string RAM the algorithm uses, in megabytes. |
| Total RAM (MB) | string RAM the node provides, in megabytes. |
| Hostname | string Name of the machine that runs the algorithm, which starts with the type of deployment. |
| LEAN Version | string Version of LEAN that runs the algorithm. |
| Up Time | string Time the node has been running, in days, hours, minutes, and seconds. |
| Example |
{
"CPU Usage": "0.0%",
"Used RAM (MB)": "241",
"Total RAM (MB)": "16384",
"Hostname": "BACKTESTING-48-b663526eb061eda8efa07d9bde55c24f",
"LEAN Version": "v2.5.0.0.18009",
"Up Time": "0d 00:00:03"
}
|
ChartSummary Model - Contains the names of all charts | |
|---|---|
| name | string Name of the Chart. |
| Example |
{
"name": "string"
}
|
401 Authentication Error
UnauthorizedError Model - Unauthorized response from the API. Key is missing, invalid, or timestamp is too old for hash. | |
|---|---|
| www_authenticate | string Header |
Examples
The following example demonstrates listing, creating, reading, and updating live algorithms of a project through the cloud API.
from base64 import b64encode
from hashlib import sha256
from time import time
from requests import get, post
BASE_URL = 'https://www.quantconnect.com/api/v2/'
# You need to replace these with your actual credentials.
# You can request your credentials at https://www.quantconnect.com/settings/
# You can find our organization ID at https://www.quantconnect.com/organization/
USER_ID = 0
API_TOKEN = '____'
ORGANIZATION_ID = '____'
def get_headers():
# Get timestamp
timestamp = f'{int(time())}'
time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
# Get hased API token
hashed_token = sha256(time_stamped_token).hexdigest()
authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
authentication = b64encode(authentication).decode('ascii')
# Create headers dictionary.
return {
'Authorization': f'Basic {authentication}',
'Timestamp': timestamp
}
# Authenticate to verify credentials
response = post(f'{BASE_URL}/authenticate', headers = get_headers())
print(response.json())
# --------------------
### List Live Algorithms
# Define placeholder IDs for project, compilation and node (replace with actual values)
project_id = 12345678
compile_id = "compile_id..."
node_id = "node_id..."
# Prepare data payload to list the past and current deployments of the project
payload = {
"projectId": project_id # ID of the project
}
# Send a POST request to the /live/list endpoint to list algorithms
response = post(f'{BASE_URL}/live/list', headers=get_headers(), json=payload)
# Parse the JSON response into python managable dict
result = response.json()
deployments = result['live'] if result['success'] else []
# The most recent deployment of the project, if any
latest = max(deployments, key=lambda x: x['launched'], default=None)
print(f"Live deployments: {len(deployments)}, latest: {latest['deployId'] if latest else None}")
### Create Live Algorithm
# Deploy only if the project has no running deployment
if latest is None or latest['status'] != 'Running':
# Prepare the data payload for creating a live algorithm with necessary details
payload = {
"versionId": -1, # Use the latest version of LEAN
"projectId": project_id, # ID of the project to deploy as a live algorithm
"compileId": compile_id, # Compilation ID for the algorithm code
"nodeId": node_id, # Node ID where the algorithm will run
"brokerage": { # Brokerage configuration for live trading
"id": "QuantConnectBrokerage" # Paper trading brokerage identifier
},
"dataProviders": { # Data provider configuration
"QuantConnectBrokerage": {
"id": "QuantConnectBrokerage" # Data provider identifier
}
},
"parameters": {} # Optional algorithm parameters (empty in this example)
}
# Send a POST request to the /live/create endpoint to deploy the algorithm
response = post(f'{BASE_URL}/live/create', headers=get_headers(), json=payload)
# Parse the JSON response into python managable dict from the API
result = response.json()
# Check if the request was successful and print the result
if result['success']:
print("Live Algorithm Created Successfully:")
print(result)
### Read Live Algorithm Statistics
# Prepare data payload with the project ID to fetch the statistics of its latest deployment
payload = {
"projectId": project_id # ID of the project
}
# Send a POST request to the /live/read endpoint to get algorithm statistics
response = post(f'{BASE_URL}/live/read', headers=get_headers(), json=payload)
# Parse the JSON response into python managable dict
result = response.json()
# Check if the request was successful and print the statistics
if result['success']:
print("Live Algorithm Statistics:")
print(result)
### Liquidate Live Algorithm
# Prepare data payload with project ID to liquidate the algorithm
payload = {
"projectId": project_id # ID of the project to liquidate
}
# Send a POST request to the /live/update/liquidate endpoint to liquidate
response = post(f'{BASE_URL}/live/update/liquidate', headers=get_headers(), json=payload)
# Parse the JSON response into python managable dict
result = response.json()
# Check if the request was successful and print the result
if result['success']:
print("Live Algorithm Liquidated Successfully:")
print(result)
### Stop Live Algorithm
# Prepare data payload with project ID to stop the algorithm
payload = {
"projectId": project_id # ID of the project to stop
}
# Send a POST request to the /live/update/stop endpoint to stop the algorithm
response = post(f'{BASE_URL}/live/update/stop', headers=get_headers(), json=payload)
# Parse the JSON response into python managable dict
result = response.json()
# Check if the request was successful and print the result
if result['success']:
print("Live Algorithm Stopped Successfully:")
print(result)
### Export Orders
from decimal import Decimal
from time import sleep
# Download the orders of the last 750 days as a CSV file
payload = {
"projectId": project_id # ID of the project
}
response = post(f'{BASE_URL}/live/export/orders', headers=get_headers(), json=payload)
rows = response.text.splitlines()
header, recent = rows[0], rows[1:]
# The export starts at its first row. Older orders come from the /live/orders/read endpoint.
cutoff = recent[0].split(',')[1][:19].replace('T', ' ') if recent else '9999'
# Map the order type and status enums to the names in the CSV file
order_types = ["Market", "Limit", "Stop Market", "Stop Limit", "Market On Open", "Market On Close",
"Option Exercise", "Limit If Touched", "Combo Market", "Combo Limit", "Combo Leg Limit", "Trailing Stop"]
order_statuses = ["New", "Submitted", "Partially Filled", "Filled", "", "Canceled", "None", "Invalid",
"Cancel Pending", "Update Submitted"]
def number(value):
text = format(Decimal(str(value)), 'f')
return text.rstrip('0').rstrip('.') if '.' in text else text
# Read the older orders of each deployment that started before the cutoff
older = []
response = post(f'{BASE_URL}/live/list', headers=get_headers(), json={"projectId": project_id})
deployments = sorted(response.json()['live'], key=lambda x: x['launched'])
for deployment in deployments:
if deployment['launched'] >= cutoff:
continue
start = 0
while True:
payload = {
"projectId": project_id, # ID of the project
"deployId": deployment['deployId'], # ID of the deployment
"start": start, # Starting index for orders
"end": start + 1000 # Ending index for orders
}
result = post(f'{BASE_URL}/live/orders/read', headers=get_headers(), json=payload).json()
# The first request can return a loading status while the orders are prepared
if result.get('status') == 'loading':
sleep(1)
continue
for order in result['orders']:
if order['time'][:19].replace('T', ' ') >= cutoff:
continue
older.append(','.join([
deployment['deployId'], order['time'], order['symbol']['value'],
number(order['price']), number(order['quantity']),
f'"{order_types[order["type"]]}"', f'"{order_statuses[order["status"]]}"',
number(order['value']), '"' + order['tag'].replace('"', '""') + '" '
]))
start += 1000
if start >= result['length']:
break
# Save all the orders in one CSV file
with open(f'orders-{project_id}.csv', 'w', newline='') as file:
file.write('\n'.join([header] + older + recent) + '\n')
print(f"Saved {len(older) + len(recent)} orders")
### Export Trades
# Download the closed trades that opened since the start time as a CSV file
payload = {
"projectId": project_id, # ID of the project
"start": 1717801200, # Start time (Unix timestamp) for the trade entry time
"end": 1743462000 # End time (Unix timestamp) for the trade exit time
}
response = post(f'{BASE_URL}/live/export/trades', headers=get_headers(), json=payload)
with open(f'trades-{project_id}.csv', 'w', newline='') as file:
file.write(response.text)
### Export Insights
# Download the insights of all the live deployments of the project as a JSON file
payload = {
"deployId": latest['deployId'] # ID of a deployment of the project
}
response = post(f'{BASE_URL}/live/export/insights', headers=get_headers(), json=payload)
with open(f'insights-{project_id}.json', 'w', newline='') as file:
file.write(response.text)
### Export Logs
# Download the logs of all the live deployments of the project as a text file
payload = {
"projectId": project_id, # ID of the project
"deployId": latest['deployId'] # ID of a deployment of the project, used to name the file
}
response = post(f'{BASE_URL}/live/export/logs', headers=get_headers(), json=payload)
with open(f'logs-{project_id}.txt', 'w', newline='') as file:
file.write(response.text)