-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathsource.py
83 lines (66 loc) · 2.71 KB
/
source.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from typing import Dict, List, Optional
import requests
import logging
# Create a logger instance for the module
logger = logging.getLogger(__name__)
class SourceManager:
"""
A class to manage fetching and aggregating prices from various market sources.
Attributes:
source_data (Dict[int, str]): A dictionary mapping market IDs to their respective API URLs.
"""
def __init__(self, source_data: Dict[int, str]) -> None:
"""
Initialize the SourceManager with a dictionary of market IDs and their API URLs.
Args:
source_data (Dict[int, str]): A dictionary where keys are market IDs and values are API URLs.
"""
self.source_data = source_data
def fetch_price(self, market_id: int) -> Optional[float]:
"""
Fetch the latest price for a given market ID from the configured source.
Args:
market_id (int): The ID of the market to fetch the price for.
Returns:
Optional[float]: The latest price if successful, otherwise None.
"""
if market_id not in self.source_data:
logger.error(f"No source URL configured for market_id={market_id}.")
return None
try:
response = requests.get(self.source_data[market_id])
response.raise_for_status()
data = response.json()
latest_price = float(sorted(data, key=lambda x: x["T"])[-1]["p"])
logger.info(
f"Successfully fetched price for market_id={market_id}: {latest_price}."
)
return latest_price
except Exception as e:
logger.error(f"Failed to fetch price for market_id={market_id}: {str(e)}")
return None
def aggregate_price(self, prices: List[float]) -> float:
"""
Aggregate a list of prices into a single value (e.g., average).
Args:
prices (List[float]): A list of prices to aggregate.
Returns:
float: The aggregated price (average of the list).
"""
if not prices:
logger.warning("No prices provided for aggregation.")
return 0.0
return sum(prices) / len(prices)
def get_fair_price(self, market_id: int) -> float:
"""
Calculate the fair price for a given market ID.
Args:
market_id (int): The ID of the market to calculate the fair price for.
Returns:
float: The calculated fair price. Returns 0.0 if the price cannot be fetched.
"""
price = self.fetch_price(market_id)
if price is None:
logger.error(f"Unable to calculate fair price for market_id={market_id}.")
return 0.0
return price