mirror of
https://github.com/norandom/trading_analysis.git
synced 2026-10-05 14:19:28 +00:00
351 KiB
351 KiB
In [22]:
from dotenv import load_dotenv
import os
# Load the environment variables from .env file
load_dotenv("api_keys")Out [22]:
True
In [23]:
nasdaq_api_key = os.getenv('NASDAQ_API_KEY')
if len(nasdaq_api_key) > 0:
print("loaded key")loaded key
In [40]:
import requests
import pandas as pd
from datetime import datetime
import urllib.parse
# API endpoint components
base_url = "https://data.nasdaq.com/api/v3/datasets/"
dataset = "CFTC/084691_F_ALL"
data_format = ".json"
# Parameters
params = {
"start_date": "2022-01-01",
"end_date": "2024-01-01",
"api_key": nasdaq_api_key # Make sure this variable is defined
}
# Construct the full URL with parameters
param_string = urllib.parse.urlencode(params)
url = f"{base_url}{dataset}{data_format}?{param_string}"
# Make the API request
response = requests.get(url)
# Check if the request was successful
if response.status_code == 200:
# Parse the JSON response
data = response.json()
# Extract the dataset from the response
dataset = data['dataset']
# Create a pandas DataFrame
df = pd.DataFrame(dataset['data'], columns=dataset['column_names'])
# Convert the date column to datetime
df['Date'] = pd.to_datetime(df['Date'])
# Set the date as the index
df.set_index('Date', inplace=True)
# Sort the DataFrame by date
df.sort_index(inplace=True)
# Display the first few rows of the DataFrame
print(df.tail())
# You can now use this DataFrame for further analysis or visualization
else:
print(f"Error fetching data: {response.status_code}")
print(response.text) Open Interest Producer/Merchant/Processor/User Longs \
Date
2023-11-28 139144.0 3472.0
2023-12-05 139753.0 4714.0
2023-12-12 134281.0 4311.0
2023-12-19 127549.0 3701.0
2023-12-26 131408.0 4063.0
Producer/Merchant/Processor/User Shorts Swap Dealer Longs \
Date
2023-11-28 40323.0 33045.0
2023-12-05 41340.0 33328.0
2023-12-12 38849.0 30707.0
2023-12-19 39714.0 30908.0
2023-12-26 41011.0 29911.0
Swap Dealer Shorts Swap Dealer Spreads Money Manager Longs \
Date
2023-11-28 44049.0 3770.0 45604.0
2023-12-05 48716.0 2932.0 43852.0
2023-12-12 43665.0 2832.0 33472.0
2023-12-19 43686.0 1911.0 34931.0
2023-12-26 45585.0 2415.0 36546.0
Money Manager Shorts Money Manager Spreads \
Date
2023-11-28 21842.0 6885.0
2023-12-05 22322.0 7544.0
2023-12-12 24805.0 8439.0
2023-12-19 20060.0 6662.0
2023-12-26 19749.0 6847.0
Other Reportable Longs Other Reportable Shorts \
Date
2023-11-28 17276.0 6758.0
2023-12-05 19389.0 4616.0
2023-12-12 22212.0 2421.0
2023-12-19 17700.0 2820.0
2023-12-26 18013.0 2947.0
Other Reportable Spreads Total Reportable Longs \
Date
2023-11-28 2445.0 112497.0
2023-12-05 1607.0 113366.0
2023-12-12 1706.0 103679.0
2023-12-19 1577.0 97390.0
2023-12-26 2137.0 99932.0
Total Reportable Shorts Non Reportable Longs \
Date
2023-11-28 126072.0 26647.0
2023-12-05 129077.0 26387.0
2023-12-12 122717.0 30602.0
2023-12-19 116430.0 30159.0
2023-12-26 120691.0 31476.0
Non Reportable Shorts
Date
2023-11-28 13072.0
2023-12-05 10676.0
2023-12-12 11564.0
2023-12-19 11119.0
2023-12-26 10717.0
In [41]:
df.columnsOut [41]:
Index(['Open Interest', 'Producer/Merchant/Processor/User Longs',
'Producer/Merchant/Processor/User Shorts', 'Swap Dealer Longs',
'Swap Dealer Shorts', 'Swap Dealer Spreads', 'Money Manager Longs',
'Money Manager Shorts', 'Money Manager Spreads',
'Other Reportable Longs', 'Other Reportable Shorts',
'Other Reportable Spreads', 'Total Reportable Longs',
'Total Reportable Shorts', 'Non Reportable Longs',
'Non Reportable Shorts'],
dtype='object')In [44]:
df.tail()Out [44]:
| Open Interest | Producer/Merchant/Processor/User Longs | Producer/Merchant/Processor/User Shorts | Swap Dealer Longs | Swap Dealer Shorts | Swap Dealer Spreads | Money Manager Longs | Money Manager Shorts | Money Manager Spreads | Other Reportable Longs | Other Reportable Shorts | Other Reportable Spreads | Total Reportable Longs | Total Reportable Shorts | Non Reportable Longs | Non Reportable Shorts | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||||||||
| 2023-11-28 | 139144.0 | 3472.0 | 40323.0 | 33045.0 | 44049.0 | 3770.0 | 45604.0 | 21842.0 | 6885.0 | 17276.0 | 6758.0 | 2445.0 | 112497.0 | 126072.0 | 26647.0 | 13072.0 |
| 2023-12-05 | 139753.0 | 4714.0 | 41340.0 | 33328.0 | 48716.0 | 2932.0 | 43852.0 | 22322.0 | 7544.0 | 19389.0 | 4616.0 | 1607.0 | 113366.0 | 129077.0 | 26387.0 | 10676.0 |
| 2023-12-12 | 134281.0 | 4311.0 | 38849.0 | 30707.0 | 43665.0 | 2832.0 | 33472.0 | 24805.0 | 8439.0 | 22212.0 | 2421.0 | 1706.0 | 103679.0 | 122717.0 | 30602.0 | 11564.0 |
| 2023-12-19 | 127549.0 | 3701.0 | 39714.0 | 30908.0 | 43686.0 | 1911.0 | 34931.0 | 20060.0 | 6662.0 | 17700.0 | 2820.0 | 1577.0 | 97390.0 | 116430.0 | 30159.0 | 11119.0 |
| 2023-12-26 | 131408.0 | 4063.0 | 41011.0 | 29911.0 | 45585.0 | 2415.0 | 36546.0 | 19749.0 | 6847.0 | 18013.0 | 2947.0 | 2137.0 | 99932.0 | 120691.0 | 31476.0 | 10717.0 |
In [45]:
import pandas as pd
import plotly.graph_objects as go
import numpy as np
# Assuming df is your DataFrame with the COT data
# If not, you'll need to load your data here
# Calculate percentages for producers
categories = [
'Producer/Merchant/Processor/User Longs',
'Producer/Merchant/Processor/User Shorts'
]
for category in categories:
df[f'{category} %'] = df[category] / df['Open Interest'] * 100
# Create the main figure
fig = go.Figure()
# Add traces for each category
colors = ['blue', 'red']
for i, category in enumerate(categories):
fig.add_trace(go.Scatter(
x=df.index,
y=df[f'{category} %'],
mode='lines',
name=category,
line=dict(width=2, color=colors[i])
))
# Update layout
fig.update_layout(
title='COT Data: Percentage of Open Interest for Producers',
yaxis_title='Percentage of Open Interest',
xaxis_title='Date',
legend_title='Producer Categories',
height=600,
width=1200,
hovermode='x unified'
)
# Improve date labeling for better readability
fig.update_xaxes(
tickformat="%d %b %Y",
tickangle=45,
dtick="M1",
ticklabelmode="period"
)
# Set y-axis to percentage
fig.update_yaxes(ticksuffix='%')
# Show the plot
fig.show()
# Calculate and print metrics
for category in categories:
print(f"\nMetrics for {category}:")
data = df[f'{category} %']
print(f"Volatility (Standard Deviation): {data.std():.2f}%")
print(f"Average: {data.mean():.2f}%")
print(f"Median: {data.median():.2f}%")
print(f"Minimum: {data.min():.2f}%")
print(f"Maximum: {data.max():.2f}%")
# Calculate typical range
typical_low = np.percentile(data, 25)
typical_high = np.percentile(data, 75)
print(f"Typical Range: {typical_low:.2f}% to {typical_high:.2f}%")
# Calculate and print the correlation between longs and shorts
correlation = df[f'{categories[0]} %'].corr(df[f'{categories[1]} %'])
print(f"\nCorrelation between Longs and Shorts: {correlation:.2f}")Metrics for Producer/Merchant/Processor/User Longs: Volatility (Standard Deviation): 1.36% Average: 3.23% Median: 3.00% Minimum: 0.64% Maximum: 7.14% Typical Range: 2.37% to 3.78% Metrics for Producer/Merchant/Processor/User Shorts: Volatility (Standard Deviation): 3.96% Average: 25.57% Median: 25.32% Minimum: 18.08% Maximum: 32.77% Typical Range: 22.26% to 28.93% Correlation between Longs and Shorts: -0.22
In [26]:
import pandas as pd
import plotly.graph_objects as go
import numpy as np
from scipy import signal
# Assuming df is your DataFrame with the COT data
# If not, you'll need to load your data here
# Create the main figure
fig = go.Figure()
# Add trace for Open Interest
fig.add_trace(go.Scatter(
x=df.index,
y=df['Open Interest'],
mode='lines',
name='Open Interest',
line=dict(width=2, color='blue')
))
# Update layout
fig.update_layout(
title='COT Data: Open Interest Over Time (Silver)',
yaxis_title='Open Interest',
xaxis_title='Date',
height=600,
width=800,
hovermode='x unified'
)
# Improve date labeling for better readability
fig.update_xaxes(
tickformat="%d %b %Y",
tickangle=45,
dtick="M1",
ticklabelmode="period"
)
# Show the plot
fig.show()
# Calculate and print metrics
print("\nMetrics for Open Interest:")
data = df['Open Interest']
print(f"Volatility (Standard Deviation): {data.std():.2f}")
print(f"Average: {data.mean():.2f}")
print(f"Median: {data.median():.2f}")
print(f"Minimum: {data.min():.2f}")
print(f"Maximum: {data.max():.2f}")
# Calculate typical range
typical_low = np.percentile(data, 25)
typical_high = np.percentile(data, 75)
print(f"Typical Range: {typical_low:.2f} to {typical_high:.2f}")
# Identify trends
def identify_trend(series):
# Calculate the overall trend
trend = np.polyfit(range(len(series)), series, 1)[0]
if trend > 0:
return "Upward"
elif trend < 0:
return "Downward"
else:
return "Stable"
trend = identify_trend(data)
print(f"\nOverall trend: {trend}")
# Identify significant points
def find_peaks(series, prominence=1000):
peaks, _ = signal.find_peaks(series, prominence=prominence)
troughs, _ = signal.find_peaks(-series, prominence=prominence)
return peaks, troughs
peaks, troughs = find_peaks(data)
print("\nSignificant points:")
for peak in peaks:
print(f"Peak on {df.index[peak]}: {data.iloc[peak]:.2f}")
for trough in troughs:
print(f"Trough on {df.index[trough]}: {data.iloc[trough]:.2f}")
# Identify sudden changes
pct_change = data.pct_change()
sudden_changes = pct_change[abs(pct_change) > 0.05] # 5% threshold
if not sudden_changes.empty:
print("\nSudden changes (>5% day-to-day):")
for date, change in sudden_changes.items():
print(f"{date}: {change*100:.2f}% change")
else:
print("\nNo sudden changes above 5% threshold detected.")Metrics for Open Interest: Volatility (Standard Deviation): 5894.28 Average: 131794.00 Median: 131408.00 Minimum: 123640.00 Maximum: 144138.00 Typical Range: 126377.50 to 135836.50 Overall trend: Downward Significant points: Peak on 2023-10-10 00:00:00: 126971.00 Peak on 2023-12-05 00:00:00: 139753.00 Trough on 2023-09-12 00:00:00: 125292.00 Trough on 2023-10-17 00:00:00: 123640.00 Trough on 2023-12-19 00:00:00: 127549.00 Sudden changes (>5% day-to-day): 2023-12-19 00:00:00: -5.01% change
In [ ]: