Skip to content

Commit

Permalink
Implement NEWS based API support for realtime NEWS and updates
Browse files Browse the repository at this point in the history
Related to #4

Add NEWS API support for real-time news and updates.

* **Configuration Changes**
  - Add `NEWS_API_KEY` and `NEWS_API_ENDPOINT` to `.env` file.
  - Update `config/api_config.py` to include `news_api_key` and `news_api_endpoint`.
  - Add `news_headers` method to `APIConfig` class.
  - Add `get_news_endpoint` method to `APIConfig` class.

* **News Data Fetcher**
  - Create `data/news_data_fetcher.py` with `NewsDataFetcher` class.
  - Add `fetch_news_data` method to `NewsDataFetcher` class.

* **Main Integration**
  - Import `NewsDataFetcher` in `main.py`.
  - Initialize `NewsDataFetcher` instance with `news_api_key` and `news_api_endpoint`.
  - Update `process_market_data` function to include `news_fetcher` parameter.
  - Fetch and process news data in `process_market_data` function.

* **Data Fetcher Updates**
  - Import `NewsDataFetcher` in `data/data_fetcher.py`.
  - Add `news_fetcher` attribute to `DataFetcher` class.
  - Initialize `news_fetcher` in `DataFetcher` constructor.
  - Add `fetch_and_process_news_data` method to `DataFetcher` class.
  • Loading branch information
vishwamartur committed Nov 5, 2024
1 parent c241bca commit 9eaf313
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ TELEGRAM_CHAT_ID=your_telegram_chat_id
# Weather API
WEATHER_API_KEY=your_weather_api_key
WEATHER_API_ENDPOINT=your_weather_api_endpoint

# News API
NEWS_API_KEY=your_news_api_key
NEWS_API_ENDPOINT=your_news_api_endpoint
19 changes: 19 additions & 0 deletions config/api_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def __init__(self):
self.weather_api_key = os.getenv("WEATHER_API_KEY")
self.weather_api_endpoint = os.getenv("WEATHER_API_ENDPOINT")

# News API configurations
self.news_api_key = os.getenv("NEWS_API_KEY")
self.news_api_endpoint = os.getenv("NEWS_API_ENDPOINT")

# Additional API configurations can be added here
# Example for other market data or sentiment analysis APIs:
# self.other_api_key = os.getenv("OTHER_API_KEY")
Expand Down Expand Up @@ -58,6 +62,15 @@ def weather_headers(self):
"Content-Type": "application/json",
}

def news_headers(self):
"""
Returns headers required for making requests to the News API.
"""
return {
"Authorization": f"Bearer {self.news_api_key}",
"Content-Type": "application/json",
}

def get_dhan_endpoint(self, path):
"""
Constructs and returns a full Dhan API endpoint for a given path.
Expand All @@ -75,3 +88,9 @@ def get_weather_endpoint(self):
Returns the Weather API endpoint.
"""
return self.weather_api_endpoint

def get_news_endpoint(self):
"""
Returns the News API endpoint.
"""
return self.news_api_endpoint
28 changes: 28 additions & 0 deletions data/data_fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Dict, Any
from datetime import datetime
from data.weather_data_fetcher import WeatherDataFetcher
from data.news_data_fetcher import NewsDataFetcher

logger = logging.getLogger(__name__)

Expand All @@ -26,6 +27,10 @@ def __init__(self, config: Dict[str, Any]):
api_key=config["api"]["weather_api_key"],
api_endpoint=config["api"]["weather_api_endpoint"]
)
self.news_fetcher = NewsDataFetcher(
api_key=config["api"]["news_api_key"],
api_endpoint=config["api"]["news_api_endpoint"]
)

async def process_data_async(self, raw_data: Dict[str, Any]) -> Dict[str, Any]:
"""
Expand Down Expand Up @@ -186,3 +191,26 @@ async def fetch_and_process_weather_data(self, location: str) -> Dict[str, Any]:
except Exception as e:
self.logger.error(f"Error fetching or processing weather data: {str(e)}")
return {}

async def fetch_and_process_news_data(self, topic: str) -> Dict[str, Any]:
"""
Fetch and process news data for a given topic.
Args:
topic: Topic for which to fetch news data
Returns:
Dictionary containing processed news data
"""
try:
self.logger.info(f"Fetching news data for topic: {topic}")
news_data = self.news_fetcher.fetch_news_data(topic)
processed_news_data = {
"topic": topic,
"articles": news_data.get("articles", [])
}
self.logger.info(f"News data processing complete for topic: {topic}")
return processed_news_data
except Exception as e:
self.logger.error(f"Error fetching or processing news data: {str(e)}")
return {}
43 changes: 43 additions & 0 deletions data/news_data_fetcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import requests
import logging

class NewsDataFetcher:
"""
Fetches news data from the News API.
"""

def __init__(self, api_key: str, api_endpoint: str):
"""
Initialize the NewsDataFetcher with API key and endpoint.
Args:
api_key: API key for the News API
api_endpoint: Endpoint URL for the News API
"""
self.api_key = api_key
self.api_endpoint = api_endpoint
self.logger = logging.getLogger(__name__)

def fetch_news_data(self, topic: str) -> dict:
"""
Fetch news data for a given topic.
Args:
topic: Topic for which to fetch news data
Returns:
Dictionary containing news data
"""
try:
self.logger.info(f"Fetching news data for topic: {topic}")
response = requests.get(
self.api_endpoint,
params={"q": topic, "apiKey": self.api_key}
)
response.raise_for_status()
news_data = response.json()
self.logger.info(f"News data fetched successfully for topic: {topic}")
return news_data
except requests.RequestException as e:
self.logger.error(f"Error fetching news data: {str(e)}")
return {}
25 changes: 20 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import telegram
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from data.weather_data_fetcher import WeatherDataFetcher
from data.news_data_fetcher import NewsDataFetcher

# Load environment variables and validate required keys
load_dotenv()
Expand All @@ -30,7 +31,9 @@
"TELEGRAM_BOT_API_KEY",
"TELEGRAM_CHAT_ID",
"WEATHER_API_KEY",
"WEATHER_API_ENDPOINT"
"WEATHER_API_ENDPOINT",
"NEWS_API_KEY",
"NEWS_API_ENDPOINT"
]
for var in required_env_vars:
if not os.getenv(var):
Expand All @@ -55,7 +58,8 @@ async def process_market_data(
order_executor: OrderExecution,
notifier: Notifier,
investment_banking_tracker: InvestmentBankingTracker,
weather_fetcher: WeatherDataFetcher
weather_fetcher: WeatherDataFetcher,
news_fetcher: NewsDataFetcher
) -> None:
"""
Process incoming market data asynchronously and execute trading strategies
Expand All @@ -70,9 +74,10 @@ async def process_market_data(
sentiment_task = asyncio.create_task(chatgpt_integration.analyze_sentiment_async(processed_data))
investment_banking_task = asyncio.create_task(investment_banking_tracker.process_investment_banking_trades(data))
weather_task = asyncio.create_task(weather_fetcher.fetch_and_process_weather_data("New York"))
news_task = asyncio.create_task(news_fetcher.fetch_news_data("market"))

futures_signal, options_signal, sentiment, _, weather_data = await asyncio.gather(
futures_task, options_task, sentiment_task, investment_banking_task, weather_task
futures_signal, options_signal, sentiment, _, weather_data, news_data = await asyncio.gather(
futures_task, options_task, sentiment_task, investment_banking_task, weather_task, news_task
)

# Handle futures signals
Expand All @@ -97,6 +102,11 @@ async def process_market_data(
logger.info(f"Weather Data: {weather_data}")
await notifier.send_async(f"Weather update: {weather_data}")

# Process news data
if news_data:
logger.info(f"News Data: {news_data}")
await notifier.send_async(f"News update: {news_data}")

except Exception as e:
logger.error(f"Error processing market data: {str(e)}")
await notifier.send_async(f"Error in market data processing: {str(e)}")
Expand Down Expand Up @@ -133,6 +143,10 @@ async def main():
api_key=config["api"]["weather_api_key"],
api_endpoint=config["api"]["weather_api_endpoint"]
)
news_fetcher = NewsDataFetcher(
api_key=config["api"]["news_api_key"],
api_endpoint=config["api"]["news_api_endpoint"]
)

# Run backtesting with performance metrics
backtester = Backtester()
Expand All @@ -154,7 +168,8 @@ async def on_message(data: Dict) -> None:
order_executor,
notifier,
investment_banking_tracker,
weather_fetcher
weather_fetcher,
news_fetcher
)

# Start WebSocket connection
Expand Down

0 comments on commit 9eaf313

Please sign in to comment.