Skip to content

Commit 3292ea0

Browse files
committed
New example: Charts, Volume, Closing, Daily return plots.
1 parent d2a1eff commit 3292ea0

File tree

4 files changed

+167
-6
lines changed

4 files changed

+167
-6
lines changed

examples/README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ This directory contains example scripts demonstrating how to use the Borsdata AP
66

77
Before running these examples, make sure you have:
88

9-
1. Installed the borsdata-client package:
10-
11-
```bash
12-
pip install borsdata-client
13-
```
9+
1. Installed the borsdata-client package by cloning the repo.
1410

1511
2. Set up your API key as an environment variable or in a `.env` file:
1612
```

examples/portfolio_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def calculate_portfolio_value(
6666
instrument = get_instrument_by_ticker(client, ticker)
6767

6868
# Get historical prices
69-
prices = get_historical_prices(client, instrument.insId)
69+
prices = get_historical_prices(client, instrument.ins_id)
7070

7171
if not prices:
7272
print(f"No price data available for {ticker}")

examples/stock_visualization.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Stock visualization example using the Borsdata API client.
4+
5+
This example demonstrates how to create beautiful visualizations of stock data
6+
including price trends, volume, and basic technical indicators.
7+
"""
8+
9+
import os
10+
from datetime import datetime, timedelta
11+
import pandas as pd
12+
import matplotlib.pyplot as plt
13+
import seaborn as sns
14+
from dotenv import load_dotenv
15+
from borsdata_client import BorsdataClient
16+
17+
# Set style for prettier plots
18+
plt.style.use('seaborn-v0_8')
19+
sns.set_palette("husl")
20+
21+
# Load environment variables from .env file
22+
load_dotenv()
23+
24+
# Get API key from environment
25+
api_key = os.getenv("BORSDATA_API_KEY")
26+
if not api_key:
27+
raise ValueError("BORSDATA_API_KEY environment variable not set")
28+
29+
def get_stock_data(client: BorsdataClient, ticker: str, days: int = 365) -> pd.DataFrame:
30+
"""
31+
Fetch stock data and convert it to a pandas DataFrame.
32+
33+
Args:
34+
client: BorsdataClient instance
35+
ticker: Stock ticker symbol
36+
days: Number of days of historical data to fetch
37+
38+
Returns:
39+
DataFrame with stock price data
40+
"""
41+
# Find the instrument
42+
instruments = client.get_instruments()
43+
instrument = next((i for i in instruments if i.ticker == ticker), None)
44+
if not instrument:
45+
raise ValueError(f"Could not find instrument with ticker {ticker}")
46+
47+
# Get historical prices
48+
today = datetime.now()
49+
start_date = today - timedelta(days=days)
50+
prices = client.get_stock_prices(
51+
instrument_id=instrument.ins_id,
52+
from_date=start_date,
53+
to_date=today
54+
)
55+
56+
# Convert to DataFrame
57+
df = pd.DataFrame([{
58+
'Date': datetime.strptime(p.d, '%Y-%m-%d'),
59+
'Open': p.o,
60+
'High': p.h,
61+
'Low': p.l,
62+
'Close': p.c,
63+
'Volume': p.v
64+
} for p in prices])
65+
66+
df.set_index('Date', inplace=True)
67+
68+
# Add some technical indicators
69+
df['SMA_20'] = df['Close'].rolling(window=20).mean()
70+
df['SMA_50'] = df['Close'].rolling(window=50).mean()
71+
df['Daily_Return'] = df['Close'].pct_change()
72+
73+
return df
74+
75+
def plot_stock_analysis(df: pd.DataFrame, ticker: str):
76+
"""
77+
Create a comprehensive visualization of stock data.
78+
79+
Args:
80+
df: DataFrame with stock price data
81+
ticker: Stock ticker symbol for the title
82+
"""
83+
# Create a figure with subplots
84+
fig = plt.figure(figsize=(16, 10), constrained_layout=True)
85+
86+
# Define grid for subplots
87+
gs = fig.add_gridspec(3, 1, height_ratios=[2, 1, 1])
88+
89+
# Price and Moving Averages
90+
ax1 = fig.add_subplot(gs[0])
91+
ax1.plot(df.index, df['Close'], label='Close Price', linewidth=1.5)
92+
ax1.plot(df.index, df['SMA_20'], label='20-day SMA', linestyle='--', alpha=0.8)
93+
ax1.plot(df.index, df['SMA_50'], label='50-day SMA', linestyle='--', alpha=0.8)
94+
ax1.set_title(f'{ticker} Stock Price Analysis', fontsize=14, pad=20)
95+
ax1.set_ylabel('Price')
96+
ax1.legend(loc='center left', bbox_to_anchor=(1.02, 0.5),
97+
fancybox=True, shadow=True, framealpha=1)
98+
ax1.grid(True, alpha=0.3)
99+
100+
# Volume
101+
ax2 = fig.add_subplot(gs[1], sharex=ax1)
102+
ax2.bar(df.index, df['Volume'], alpha=0.5, color='darkblue')
103+
ax2.set_ylabel('Volume')
104+
ax2.grid(True, alpha=0.3)
105+
106+
# Daily Returns
107+
ax3 = fig.add_subplot(gs[2], sharex=ax1)
108+
ax3.plot(df.index, df['Daily_Return'], color='green', alpha=0.7)
109+
ax3.axhline(y=0, color='black', linestyle='-', alpha=0.3)
110+
ax3.fill_between(df.index, df['Daily_Return'], 0,
111+
where=(df['Daily_Return'] >= 0), color='green', alpha=0.3)
112+
ax3.fill_between(df.index, df['Daily_Return'], 0,
113+
where=(df['Daily_Return'] < 0), color='red', alpha=0.3)
114+
ax3.set_ylabel('Daily Returns')
115+
ax3.grid(True, alpha=0.3)
116+
117+
# Adjust layout and display
118+
plt.xlabel('Date')
119+
120+
# Add some statistics as text
121+
stats_text = (
122+
f"Statistics:\n"
123+
f"Current Price: {df['Close'].iloc[-1]:.2f}\n"
124+
f"52-week High: {df['High'].max():.2f}\n"
125+
f"52-week Low: {df['Low'].min():.2f}\n"
126+
f"Daily Vol.: {df['Daily_Return'].std()*100:.2f}%"
127+
)
128+
129+
# Add text in a better position that won't conflict with tight_layout
130+
ax1.text(0.02, 0.98, stats_text,
131+
transform=ax1.transAxes,
132+
bbox=dict(facecolor='white', alpha=0.8, edgecolor='none'),
133+
fontsize=10,
134+
verticalalignment='top')
135+
136+
return fig
137+
138+
def main():
139+
"""Run the stock visualization example."""
140+
# Example tickers (can be changed to any stock available in Borsdata)
141+
tickers = ['ERIC B', 'VOLV B']
142+
143+
with BorsdataClient(api_key) as client:
144+
for ticker in tickers:
145+
try:
146+
print(f"\nFetching data for {ticker}...")
147+
df = get_stock_data(client, ticker)
148+
149+
print("Creating visualization...")
150+
fig = plot_stock_analysis(df, ticker)
151+
152+
# Save the plot
153+
filename = f"{ticker.replace(' ', '_')}_analysis.png"
154+
fig.savefig(filename)
155+
print(f"Saved visualization to {filename}")
156+
plt.close(fig)
157+
158+
except Exception as e:
159+
print(f"Error processing {ticker}: {e}")
160+
161+
if __name__ == "__main__":
162+
main()

requirements-dev.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
-r requirements.txt
2+
pandas>=2.0.0
3+
matplotlib>=3.8.0
4+
seaborn>=0.13.0
25
pytest>=7.4.0
36
pytest-cov>=4.1.0
47
pytest-mock>=3.11.1

0 commit comments

Comments
 (0)