Stockmarket-data-java
stockmarket data java
The Stockmarket Service is a Java-based microservice designed to manage stock market data, including dividends, historical stock data, sectors, and more. It leverages Spring Boot, PostgreSQL, Redis, RabbitMQ, and Loki for logging. This service is built with scalability and observability in mind, making it suitable for production-grade deployments.
Table of Contents
- Features
- Architecture
- Technologies Used
- Getting Started
- Prerequisites
- Running Locally
- Running in UAT
- Configuration
- Profiles
- Environment Variables
- Database Schema
- Logging
- Health Checks
- API Endpoints
- Contributing
- License
Features
- Stock Management: Manage stocks, dividends, and historical stock data.
- Sector Management: Organize stocks into sectors and sub-sectors.
- Redis Integration: Cache frequently accessed data for improved performance.
- RabbitMQ Messaging: Enable asynchronous communication between services.
- Flyway Migrations: Manage database schema changes with version control.
- Loki Logging: Centralized logging with Loki and Grafana.
- Health Monitoring: Expose health and metrics endpoints for observability.
Architecture
The Stockmarket Service follows a microservices architecture with the following components:
- Spring Boot: Core framework for building the service.
- PostgreSQL: Relational database for persistent storage.
- Redis: In-memory data store for caching.
- RabbitMQ: Message broker for asynchronous communication.
- Loki: Centralized logging system.
Technologies Used
| Technology | Version | Purpose |
|---|---|---|
| Java | 21 | Core programming language |
| Spring Boot | 3.2 | Framework for building the service |
| PostgreSQL | 14 | Relational database |
| Redis | 6.2 | In-memory data store |
| RabbitMQ | Latest | Message broker |
| Docker | Latest | Containerization |
| Loki | Latest | Centralized logging |
| Flyway | Latest | Database migrations |
Getting Started
Prerequisites
Ensure you have the following installed:
Running Locally
- Clone the repository:
git clone https://github.com/olara-tech/stockmarket-service-java.git
cd stockmarket-service-java
- Start the required services (PostgreSQL, Redis, RabbitMQ) using Docker Compose:
docker-compose -f docker-compose-local.yml up -d
- Run the application:
./gradlew bootRun
-
Access the application:
-
Health Check: http://localhost:10003/actuator/health
Running in UAT
- Start the UAT environment:
docker-compose -f docker-compose-uat.yml up -d
-
Verify the service is running:
-
Health Check: http://localhost:10003/actuator/health
Configuration
Profiles
The application supports multiple profiles:
- local: For local development.
- uat: For UAT testing.
Environment Variables
Key environment variables include:
| Variable | Description |
|---|---|
SPRING_PROFILES_ACTIVE |
Active Spring profile (local, uat) |
SPRING_DATASOURCE_URL |
Database connection URL |
SPRING_REDIS_HOST |
Redis host |
SPRING_RABBITMQ_HOST |
RabbitMQ host |
LOGGING_LOKI_URL |
Loki logging endpoint |
Database Schema
The database schema is managed using Flyway. Key tables include:
dividends: Tracks dividend information.historical_stock_data: Stores historical stock data.stocks: Manages stock details.sectors: Organizes stocks into sectors.
Refer to the V1__Initial_Schema.sql for the full schema.
Logging
Logging is configured using Logback with Loki integration. Logs are sent to Loki for centralized monitoring.
- Configuration: logback-spring.xml
- Loki URL:
http://localhost:3100/loki/api/v1/push
Health Checks
The application exposes health and metrics endpoints:
- Health Check: http://localhost:10003/actuator/health
- Metrics: http://localhost:10003/actuator/metrics
API Endpoints
Below are all REST and WebSocket endpoints exposed by the Stockmarket Service.
REST API Endpoints
All REST endpoints are prefixed with /api/v1.
π Stocks
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /stocks |
List all stocks (paginated) |
| GET | /stocks/{stockId} |
Get stock details by stock UUID |
| GET | /stocks/symbol/{symbol} |
Get stock details by ticker symbol |
| GET | /stocks/sector/{sectorId} |
List stocks in a sector (paginated) |
| GET | /stocks/statistics?symbols=SYM1,SYM2 |
Get statistics for multiple stocks |
| GET | /stocks/related-stocks/symbol/{symbol} |
Get stocks related to a symbol (paginated) |
| GET | /stocks/related-stocks/stockId/{stockId} |
Get stocks related to a stock UUID (paginated) |
| GET | /stocks/symbol/{symbol}/details |
Get full stock details by ticker symbol |
| GET | /stocks/details?symbols=SYM1,SYM2 |
Get full stock details for multiple symbols |
| GET | /stocks/symbol/{symbol}/chart |
Get Chart Finance chart data for a symbol |
Response: Paginated Stock List (GET /stocks, /stocks/sector/{sectorId})
{
"data": [
{
"id": "uuid",
"ticker": "AAPL",
"name": "Apple Inc.",
"exchange": "NASDAQ",
"currency": "USD",
"status": "ACTIVE",
"isin": "US0378331005",
"cusip": "037833100",
"sector": "Technology",
"industry": "Consumer Electronics",
"website": "https://www.apple.com",
"logoUrl": "https://logo.clearbit.com/apple.com",
"marketCap": 2500000000000,
"employees": 164000,
"description": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide.",
"created": "2024-01-01T00:00:00Z",
"updated": "2024-05-01T00:00:00Z"
}
],
"pageable": {
"sort": { "sorted": true, "unsorted": false, "empty": false },
"offset": 0,
"pageNumber": 0,
"pageSize": 20,
"paged": true,
"unpaged": false
},
"totalElements": 100,
"totalPages": 10,
"last": false,
"first": true,
"numberOfElements": 20,
"size": 20,
"number": 0,
"sort": { "sorted": true, "unsorted": false, "empty": false },
"empty": false
}
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Stock unique identifier |
| ticker | string | Stock ticker symbol |
| name | string | Company name |
| exchange | string | Stock exchange |
| currency | string | Trading currency |
| status | string | Stock status (e.g., ACTIVE) |
| isin | string | ISIN code |
| cusip | string | CUSIP code |
| sector | string | Sector name |
| industry | string | Industry name |
| website | string | Company website |
| logoUrl | string | Logo URL |
| marketCap | number | Market capitalization |
| employees | integer | Number of employees |
| description | string | Company description |
| created | string | Creation timestamp (ISO8601) |
| updated | string | Last update timestamp (ISO8601) |
Pagination fields:
| Field | Type | Description |
|---|---|---|
| pageable | object | Pagination info |
| totalElements | integer | Total number of elements |
| totalPages | integer | Total number of pages |
| last | boolean | Is last page |
| first | boolean | Is first page |
| numberOfElements | integer | Number of elements in page |
| size | integer | Page size |
| number | integer | Page number |
| sort | object | Sort info |
| empty | boolean | Is page empty |
Response: Single Stock (GET /stocks/{stockId}, /stocks/symbol/{symbol})
{
"id": "uuid",
"ticker": "AAPL",
"name": "Apple Inc.",
"exchange": "NASDAQ",
"currency": "USD",
"status": "ACTIVE",
"isin": "US0378331005",
"cusip": "037833100",
"sector": "Technology",
"industry": "Consumer Electronics",
"website": "https://www.apple.com",
"logoUrl": "https://logo.clearbit.com/apple.com",
"marketCap": 2500000000000,
"employees": 164000,
"description": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide.",
"created": "2024-01-01T00:00:00Z",
"updated": "2024-05-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Stock unique identifier |
| ticker | string | Stock ticker symbol |
| name | string | Company name |
| exchange | string | Stock exchange |
| currency | string | Trading currency |
| status | string | Stock status |
| isin | string | ISIN code |
| cusip | string | CUSIP code |
| sector | string | Sector name |
| industry | string | Industry name |
| website | string | Company website |
| logoUrl | string | Logo URL |
| marketCap | number | Market capitalization |
| employees | integer | Number of employees |
| description | string | Company description |
| created | string | Creation timestamp |
| updatedAt | string | Last update timestamp |
Response: Finance Full Stock Details (GET /stocks/symbol/{symbol}/details, /stocks/details?symbols=SYM1,SYM2)
{
"quoteResponse": {
"result": [
{
"symbol": "AAPL",
"shortName": "Apple Inc.",
"longName": "Apple Inc.",
"regularMarketPrice": 172.5,
"regularMarketChange": 2.1,
"regularMarketChangePercent": 1.23,
"marketCap": 2500000000000,
"currency": "USD",
"exchange": "NASDAQ",
"industry": "Consumer Electronics",
"sector": "Technology",
"websiteUrl": "https://www.apple.com",
"logoUrl": "https://logo.clearbit.com/apple.com",
"trailingPE": 28.5,
"forwardPE": 25.1,
"dividendYield": 0.005,
"fiftyTwoWeekRange": "140.0 - 180.0",
"averageDailyVolume3Month": 90000000,
"...": "other fields"
}
],
"error": null
}
}
Response: Finance Chart Data (GET /stocks/symbol/{symbol}/chart)
{
"chart": {
"result": [
{
"meta": {
"currency": "USD",
"symbol": "AAPL",
"exchangeName": "NASDAQ",
"instrumentType": "EQUITY",
"regularMarketPrice": 172.5,
"chartPreviousClose": 170.4,
"...": "other meta fields"
},
"timestamp": [1715558400, 1715644800, ...],
"indicators": {
"quote": [
{
"open": [170.5, 171.0, ...],
"close": [172.5, 173.0, ...],
"low": [170.0, 170.8, ...],
"high": [172.8, 173.5, ...],
"volume": [90000000, 85000000, ...]
}
]
}
}
],
"error": null
}
}
| Field | Type | Description |
|---|---|---|
| quoteResponse | object | Finance quote response |
| chart | object | Finance chart response |
π’ Sectors
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /sectors |
List all sectors (paginated) |
| GET | /sectors/search?name=Tech |
Search sectors by name (paginated) |
Response: Paginated Sector List
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2024-05-09T12:34:56.789Z",
"success": true,
"message": "Sectors fetched successfully",
"data": [
{
"id": "uuid",
"name": "Technology",
"description": "Tech sector"
}
],
"page": 0,
"size": 20,
"totalElements": 12,
"totalPages": 1,
"metadata": {
"customField": "value"
}
}
| Field | Type | Description |
|---|---|---|
| requestId | string | Unique request identifier |
| timestamp | string (ISO8601) | Response creation timestamp |
| success | boolean | Operation success flag |
| message | string | Additional info message |
| data | array | List of sectors (see below) |
| page | integer | Current page number (0-based) |
| size | integer | Page size |
| totalElements | integer | Total number of elements |
| totalPages | integer | Total number of pages |
| metadata | object | Additional metadata (optional) |
Sector fields in data:
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Sector unique identifier |
| name | string | Sector name |
| description | string | Description |
π° News
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /news/popular-news |
Get Finance news for popular symbols |
| GET | /news/news?symbols=SYM1,SYM2 |
Get Finance news by stock symbols |
| GET | /news/popular-quotes |
Get Finance quotes for popular symbols |
Response: News List
{
"news": [
{
"id": "uuid",
"title": "Apple hits new high",
"publisher": "Reuters",
"link": "https://...",
"providerPublishTime": 1714828800,
"type": "STORY",
"thumbnail": {
"resolutions": [
{ "url": "https://...", "width": 120, "height": 80, "tag": "default" }
]
},
"relatedTickers": ["AAPL", "MSFT"]
}
]
}
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | News unique identifier |
| title | string | News headline |
| publisher | string | Publisher name |
| link | string | News URL |
| providerPublishTime | number | Unix timestamp |
| type | string | News type |
| thumbnail | object | Image info |
| relatedTickers | array of strings | Related stock tickers |
Response: Popular Quotes
{
"content": [
{
"id": "uuid",
"exchange": "NASDAQ",
"shortname": "Apple Inc.",
"quoteType": "EQUITY",
"symbol": "AAPL"
// ...
}
]
}
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Quote unique identifier |
| exchange | string | Exchange name |
| shortname | string | Company name |
| quoteType | string | Type of quote |
| symbol | string | Stock symbol |
β Watchlist
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /watchlists |
Get current user's watchlist (headers: userId, corporate-tenantId) |
| POST | /watchlists/add |
Add stock to watchlist (by ticker or stockId param) |
| POST | /watchlists/remove |
Remove stock from watchlist (by ticker or stockId param) |
| POST | /watchlists/clear |
Clear all stocks from current user's watchlist |
Headers (required for all endpoints):
- userId (UUID)
- corporate-tenantId (UUID)
Add/Remove Example:
- Add by ticker: POST /api/v1/watchlists/add?ticker=AAPL
- Add by stockId: POST /api/v1/watchlists/add?stockId=...
- Remove by ticker: POST /api/v1/watchlists/remove?ticker=AAPL
- Remove by stockId: POST /api/v1/watchlists/remove?stockId=...
Response: Get Watchlist
{
"timestamp": "2025-05-18T12:26:02.034358949Z",
"success": true,
"message": "Operation successful",
"data": {
"userId": "1f02763d-1cda-66ff-a09b-8d2dae59b0ad",
"stocks": [
{
"id": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"ticker": "AAPL",
"name": "Apple Inc.",
"price": 172.5,
"changePercent": 1.23,
"marketCap": 2500000000000,
"marketCapUnit": "USD",
"sector": "Technology"
// ...other fields as returned by the API
}
// ...more stocks
]
},
"metadata": {
"processingTime": "0ms",
"serverId": "ac1b4d35a16c",
"version": "1.0.0"
}
}
Response: Add/Remove/Clear Watchlist
{
"timestamp": "2025-05-18T12:31:25.400269666Z",
"success": true,
"message": "Operation successful",
"data": "Stock added to watchlist",
"metadata": {
"processingTime": "2ms",
"serverId": "8b8c2711aa3e",
"version": "1.0.0"
}
}
π Blogs
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /blogs |
Get all blogs (paginated) |
| GET | /blogs/search?q=keyword |
Search blogs by title (contains, case-insensitive, paginated) |
| GET | /blogs/search/prefix?titlePrefix=...&categoryPrefix=... |
Search blogs by title & category prefixes (case-insensitive, paginated) |
Response: Paginated Blog List
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2024-05-09T12:34:56.789Z",
"success": true,
"message": "Blogs fetched successfully",
"data": [
{
"id": "uuid",
"title": "Market Update: Tech Stocks Rally",
"summary": "A summary of today's tech stock performance.",
"content": "Today, tech stocks rallied as investors reacted to strong earnings reports from major companies...",
"type": "NEWS",
"readDuration": "5 min",
"category": "Technology",
"imageUrl": "https://example.com/image1.jpg",
"pageUrl": "https://example.com/blog/1",
"tags": "stocks,technology,market",
"media": [
{
"id": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"title": "Image Title",
"description": "Image description",
"mediaUrl": "https://example.com/media1.jpg",
"blogId": "c2d3e4f5-6789-01bc-defa-234567890abc"
}
],
"created": "2024-05-01T10:00:00Z",
"updated": "2024-05-01T12:00:00Z",
"createdBy": "Jane Doe",
"updatedBy": "Jane Doe"
}
],
"page": 0,
"size": 20,
"totalElements": 42,
"totalPages": 5,
"metadata": {
"customField": "value"
}
}
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Blog unique identifier |
| title | string | Blog title |
| summary | string | Blog summary |
| content | string | Blog content body |
| type | string | Blog type (see BlogType enum) |
| readDuration | string | Estimated read duration |
| category | string | Blog category |
| imageUrl | string | Image URL |
| pageUrl | string | Page URL |
| tags | string | Comma-separated tags |
| media | array | List of media objects |
| media.id | string (UUID) | Media unique identifier |
| media.title | string | Media title |
| media.description | string | Media description |
| media.mediaUrl | string | Media URL |
| media.blogId | string (UUID) | Blog ID for the media |
| created | string (ISO8601) | Creation timestamp |
| updated | string (ISO8601) | Last update timestamp |
| createdBy | string | Creator |
| updatedBy | string | Last updater |
π Trending Stocks
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /trending |
Get trending stocks (default category, paginated) |
| GET | /trending/{category} |
Get stocks for a category (paginated) |
Categories:
- TRENDING (default)
- MOST_ACTIVE
- TOP_GAINERS
- TOP_LOSERS
Request: Get Trending Stocks (Default)
GET /api/v1/trending?page=0&size=20
Request: Get Top Gainers
GET /api/v1/trending/TOP_GAINERS?page=0&size=10
Response: PageBaseResponse
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Trending stocks fetched successfully",
"data": [
{
"id": "1f02e642-863c-6c8a-986a-3f45b18885ca",
"name": "NuScale Power Corporation",
"price": 17.45,
"change": 0.52,
"changePercent": 3.07,
"logoUrl": null,
"category": "TRENDING",
"rank": 4,
"ticker": "SMR",
"stockId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"marketCap": 1234567890.12,
"sector": "Industrials, Utilities"
}
],
"page": 0,
"size": 10,
"totalElements": 20,
"totalPages": 2,
"metadata": {
"customField": "value"
}
}
| Field | Type | Description |
|---|---|---|
| id | string | TrendingStock unique identifier (UUID) |
| name | string | Stock/company name |
| price | number | Current price |
| change | number | Price change (absolute) |
| changePercent | number | Price change (percent) |
| logoUrl | string | Logo URL |
| category | string | Trending category (see above) |
| rank | int | Rank in the category (0 = highest) |
| ticker | string | Stock ticker symbol |
| stockId | string | Stock UUID (canonical stock entity) |
| marketCap | number | Market capitalization (from Yahoo or Stock) |
| sector | string | Comma-separated sector names |
Error Response
{
"timestamp": "2025-05-10T12:34:56.789+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "Failed to fetch trending stocks",
"path": "/api/v1/trending/TOP_GAINERS"
}
Notes:
- If the trending table is empty for a category, the API will fall back to returning stocks from the main stock table.
- Pagination parameters: page, size, sort are supported.
- If {category} is omitted, the default is TRENDING.
- Categories are case-insensitive (e.g., top_gainers, TOP_GAINERS, top-gainers all work).
- All paginated endpoints return a PageBaseResponse<T> structure for consistency.
π°οΈ WebSocket/Streaming Endpoints
All WebSocket endpoints use STOMP over WebSocket. Send messages to /app/{mapping} and subscribe to /topic/{channel} for real-time updates.
| Message Mapping | Description | Response Channel |
|---|---|---|
/request-prices |
Stream real-time price for a stock symbol | /topic/prices |
/request-quote |
Stream real-time quote data for symbols | /topic/quote |
/request-trending |
Stream trending stocks (top 20) | /topic/trending |
/request-most-active |
Stream most active stocks | /topic/most-active |
/request-top-gainers |
Stream top gainers | /topic/top-gainers |
/request-top-losers |
Stream top losers | /topic/top-losers |
/request-insights |
Stream insights for given symbols | /topic/insights |
Request: /request-prices
{
"symbol": "AAPL",
"userAgent": "Mozilla/5.0 ..."
}
| Field | Type | Description |
|---|---|---|
| symbol | string | Stock ticker symbol |
| userAgent | string | User agent string |
Response: /topic/prices
172.50
| Field | Type | Description |
|---|---|---|
| number | Latest price |
Request: /request-quote
{
"symbols": ["AAPL", "TSLA"],
"userAgent": "Mozilla/5.0 ..."
}
| Field | Type | Description |
|---|---|---|
| symbols | array | List of stock symbols |
| userAgent | string | User agent string |
Response: /topic/quote
{
"quoteResponse": {
"result": [
{ "symbol": "AAPL", "regularMarketPrice": 172.5 }
]
}
}
| Field | Type | Description |
|---|---|---|
| quoteResponse.result | array | List of quote objects |
Request: /request-trending
"Mozilla/5.0 ..."
| Field | Type | Description |
|---|---|---|
| string | User agent string |
Response: /topic/trending
{
"quotes": [
{ "ticker": "AAPL", "name": "Apple Inc.", "currentPrice": 172.5 }
]
}
| Field | Type | Description | | quotes | array | List of trending stocks |
Request: /request-insights
{
"symbols": ["AAPL"],
"reportsCount": 5
}
| Field | Type | Description |
|---|---|---|
| symbols | array | List of stock symbols |
| reportsCount | number | Number of reports |
Response: /topic/insights
{
"finance": {
// ...insights data
}
}
| Field | Type | Description |
|---|---|---|
| finance | object | insights data |
ποΈ Collections
| HTTP Method | Endpoint | Description |
|---|---|---|
| GET | /collections |
List all stock collections (paginated) |
| GET | /collections/search?name=Growth |
Search stock collections by name (paginated) |
| GET | /collections/{collectionId} |
Get stock collection details (with all stocks) |
| GET | /collections/{collectionId}/stocks |
Get stocks in a collection (optionally filter by ticker or name with q param) |
| POST | /collections |
Create a new stock collection |
| PUT | /collections/{collectionId} |
Update a stock collection |
| DELETE | /collections/{collectionId} |
Delete a stock collection |
All paginated API responses use the following envelope (PageBaseResponse<T>):
{
"requestId": "string",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Operation result message",
"data": [ /* array of items for this page */ ],
"page": 0,
"size": 20,
"totalElements": 100,
"totalPages": 5,
"metadata": { /* optional metadata */ }
}
Example: Paginated Collection List (GET /collections)
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Collections fetched successfully",
"data": [
{
"id": "uuid",
"name": "Growth Stocks",
"description": "High-growth companies",
"parentId": null,
"imageUrl": "https://example.com/growth.png",
"stockCount": 12
}
],
"page": 0,
"size": 20,
"totalElements": 1,
"totalPages": 1,
"metadata": null
}
Example: Single Collection (GET /collections/{collectionId})
All single-item API responses use the following envelope (BaseResponse<T>):
{
"requestId": "string",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Operation result message",
"data": { /* single item object */ },
"metadata": { /* optional metadata */ }
}
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Collection fetched successfully",
"data": {
"id": "uuid",
"name": "Growth Stocks",
"description": "High-growth companies",
"parentId": null,
"imageUrl": "https://example.com/growth.png",
"stockCount": 12,
"stocks": [
{
"id": "uuid",
"ticker": "AAPL",
"name": "Apple Inc.",
"exchange": "NASDAQ",
"currency": "USD",
"status": "ACTIVE",
"isin": "US0378331005",
"cusip": "037833100",
"sector": "Technology",
"industry": "Consumer Electronics",
"website": "https://www.apple.com",
"logoUrl": "https://logo.clearbit.com/apple.com",
"marketCap": 2500000000000,
"employees": 164000,
"description": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide.",
"created": "2024-01-01T00:00:00Z",
"updated": "2024-05-01T00:00:00Z"
}
// ...more stocks
]
},
"metadata": null
}
Example: Create Collection (POST /collections)
Request:
{
"name": "Growth Stocks",
"description": "High-growth companies",
"parentId": null,
"imageUrl": "https://example.com/growth.png",
"stockIds": ["uuid1", "uuid2"]
}
Example: Update Collection (PUT /collections/{collectionId})
Request:
{
"name": "Updated Collection Name",
"description": "Updated description",
"parentId": null,
"imageUrl": "https://example.com/updated.png",
"stockIds": ["uuid1", "uuid3"]
}
Example: Delete Collection (DELETE /collections/{collectionId})
Response:
{
"requestId": "b1c2d3e4-5678-90ab-cdef-1234567890ab",
"timestamp": "2025-05-10T12:34:56.789Z",
"success": true,
"message": "Collection deleted successfully",
"data": null,
"metadata": null
}
Request: Get Stocks in a Collection (with filter)
GET /api/v1/collections/{collectionId}/stocks?q=apple&page=0&size=10
Response: Paginated Stock List (see above)
- Supports all pagination fields and filtering by ticker or name using the
qparameter.
Common Pagination Parameters
| Parameter | Type | Description |
|---|---|---|
| page | int | Page number (0-based) |
| size | int | Page size |
| sort | string | Sort field, e.g. ticker,asc |
Note:
- All endpoints return standard error responses with fields: timestamp, status, error, message, path.
- For full request/response models, see the entity and dto packages.
News API
Get Finance News for Popular Symbols (with optional search)
GET /api/v1/news/popular-news
Query Parameters:
- query (optional): Search query for news articles (searches by title only)
- Pagination parameters (page, size, sort)
Response: - Returns a paginated list of news articles, each including all thumbnail resolutions as a set.
Get Finance News by Symbols
GET /api/v1/news/news
Query Parameters:
- symbols: List of stock symbols to fetch news for
- news_count: Number of news articles to fetch (default: 1)
Response: - Returns news articles for the specified symbols.
Search Finance News
GET /api/v1/news/search
Query Parameters:
- query: Search query for news articles (required, searches by title only)
- Pagination parameters (page, size, sort)
Response: - Returns a paginated list of news articles matching the query.
NewsResponse Example (with thumbnails)
{
"id": "6f09236c-b666-3b32-8521-1bf4ad2619da",
"title": "Big Tech Goes From Stock Marketβs Safest Bet to Biggest Question",
"publisher": "Bloomberg",
"link": "https://finance.yahoo.com/news/big-tech-goes-stock-market-120007963.html",
"providerPublishTime": 1747569607,
"type": "STORY",
"thumbnails": [
{
"url": "https://s.yimg.com/uu/api/res/1.2/o2WxiHXpgCDKyoavZFWzoQ--~B/aD04ODY7dz0xMjQwO2FwcGlkPXl0YWNoeW9u/https://media.zenfs.com/en/bloomberg_holding_pen_162/eb4dbfb6a0a8f68fca48805c88c7fa04",
"width": 1240,
"height": 886,
"tag": "original"
},
{
"url": "https://s.yimg.com/uu/api/res/1.2/NUKJfi5r6wxsiSsbqJ.5Ww--~B/Zmk9ZmlsbDtoPTE0MDtweW9mZj0wO3c9MTQwO2FwcGlkPXl0YWNoeW9u/https://media.zenfs.com/en/bloomberg_holding_pen_162/eb4dbfb6a0a8f68fca48805c88c7fa04",
"width": 140,
"height": 140,
"tag": "140x140"
}
]
}
- The
thumbnailsfield is a set of all available image resolutions for the news article. - Search endpoints only match on the news
title(not summary). - All news endpoints return thumbnails as part of the response.
Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bugfix.
- Submit a pull request with a detailed description of your changes.
License
This project is licensed under the MIT License. See the LICENSE file for details.