|
3 | 3 | This module helps to create tokens to access Systemathics Ganymede authenticated API. |
4 | 4 |
|
5 | 5 | functions: |
6 | | - get_cds_index - Get CDS Index data as a DataFrame using Ganymede gRPC API. |
| 6 | + get_cds_index_daily - Get CDS Index daily data as a DataFrame using Ganymede gRPC API. |
| 7 | + get_cds_index_intraday - Get CDS Index intraday data as a DataFrame using Ganymede gRPC API. |
| 8 | + get_future_daily - Get future daily data as a DataFrame using Ganymede gRPC API. |
7 | 9 | """ |
8 | 10 |
|
9 | 11 |
|
|
18 | 20 | from systemathics.apis.type.shared.v1 import date_interval_pb2 as date_interval |
19 | 21 | import systemathics.apis.type.shared.v1.sampling_pb2 as sampling |
20 | 22 | import systemathics.apis.type.shared.v1.identifier_pb2 as identifier |
| 23 | +import systemathics.apis.services.daily.v1.daily_bars_pb2 as daily_bars |
| 24 | +import systemathics.apis.services.daily.v1.daily_bars_pb2_grpc as daily_bars_service |
21 | 25 | import systemathics.apis.services.daily.v2.get_daily_pb2 as get_daily |
22 | 26 | import systemathics.apis.services.daily.v2.get_daily_pb2_grpc as get_daily_service |
23 | 27 | import systemathics.apis.services.intraday.v2.get_intraday_pb2 as get_intraday |
@@ -189,8 +193,6 @@ def get_cds_index_daily(ticker, start_date=None, end_date=None, batch=None, sele |
189 | 193 | print(f"Error: {str(e)}") |
190 | 194 | return pd.DataFrame() |
191 | 195 |
|
192 | | - |
193 | | - |
194 | 196 | def get_cds_index_intraday(ticker, start_date=None, end_date=None, sampling=sampling.SAMPLING_ONE_MINUTE, selected_fields=None, provider="Markit"): |
195 | 197 | """ |
196 | 198 | Fetch CDS Index intraday data from gRPC API for a given ticker and date range. |
@@ -311,6 +313,106 @@ def get_cds_index_intraday(ticker, start_date=None, end_date=None, sampling=samp |
311 | 313 | print(f"Error: {str(e)}") |
312 | 314 | return pd.DataFrame() |
313 | 315 |
|
| 316 | +def get_future_daily(ticker, start_date=None, end_date=None, provider="FirstRateData"): |
| 317 | + """ |
| 318 | + Fetch Future daily data from gRPC API for a given ticker and optionally filter by date range. |
| 319 | + |
| 320 | + Parameters: |
| 321 | + ticker (str): The ticker symbol |
| 322 | + start_date (datetime.date or str, optional): Start date for data retrieval (format: '2025-05-28'). |
| 323 | + If None, no start limit is applied |
| 324 | + end_date (datetime.date or str, optional): End date for data retrieval (format: '2025-05-28'). |
| 325 | + If None, no end limit is applied |
| 326 | + provider (str): Data provider, default is "FirstRateData" |
| 327 | +
|
| 328 | + # Example usage: |
| 329 | + # df = get_future_daily('CL1 Comdty') # Get all available data |
| 330 | + # df = get_future_daily('CL1 Comdty', start_date='2024-01-01') # From Jan 1, 2024 onwards |
| 331 | + # df = get_future_daily('CL1 Comdty', end_date='2024-12-31') # Up to Dec 31, 2024 |
| 332 | + # df = get_future_daily('CL1 Comdty', start_date='2024-01-01', end_date='2024-12-31') # Full year 2024 |
| 333 | + |
| 334 | + Returns: |
| 335 | + pd.DataFrame: DataFrame with Date as index and all available fields as columns |
| 336 | + """ |
| 337 | + |
| 338 | + def _parse_date_for_filtering(date_input): |
| 339 | + """Parse date input for DataFrame filtering (returns date object, not Google date)""" |
| 340 | + if date_input is None: |
| 341 | + return None |
| 342 | + if isinstance(date_input, date): |
| 343 | + return date_input |
| 344 | + if isinstance(date_input, datetime): |
| 345 | + return date_input.date() |
| 346 | + if isinstance(date_input, str): |
| 347 | + return datetime.strptime(date_input, '%Y-%m-%d').date() |
| 348 | + raise ValueError(f"Invalid date type: {type(date_input)}") |
| 349 | + |
| 350 | + id = identifier.Identifier( |
| 351 | + ticker=ticker, |
| 352 | + asset_type=asset.AssetType.ASSET_TYPE_FUTURE |
| 353 | + ) |
| 354 | + id.provider.value = provider |
| 355 | + |
| 356 | + request = daily_bars.DailyBarsRequest(identifier=id) |
| 357 | + |
| 358 | + try: |
| 359 | + # Open gRPC channel |
| 360 | + with channel_helpers.get_grpc_channel() as channel: |
| 361 | + # Send request and receive response |
| 362 | + token = token_helpers.get_token() |
| 363 | + |
| 364 | + # Create service stub |
| 365 | + service = daily_bars_service.DailyBarsServiceStub(channel) |
| 366 | + response = service.DailyBars(request=request, metadata=[('authorization', token)]) |
| 367 | + |
| 368 | + # Process the response |
| 369 | + if not response or not response.data: |
| 370 | + print("No data received") |
| 371 | + return pd.DataFrame() |
| 372 | + |
| 373 | + dates = [datetime(b.date.year, b.date.month, b.date.day) for b in response.data] |
| 374 | + opens = [b.open for b in response.data] |
| 375 | + highs = [b.high for b in response.data] |
| 376 | + lows = [b.low for b in response.data] |
| 377 | + closes = [b.close for b in response.data] |
| 378 | + volumes = [b.volume for b in response.data] |
| 379 | + |
| 380 | + data_dict = {'Date': dates, 'Open': opens, 'High': highs, 'Low': lows, 'Close': closes, 'Volume': volumes} |
| 381 | + df = pd.DataFrame(data=data_dict) |
| 382 | + df = df.set_index('Date') |
| 383 | + |
| 384 | + # Sort by date for better readability |
| 385 | + df = df.sort_index() |
| 386 | + |
| 387 | + # Apply date filtering if specified |
| 388 | + if start_date is not None or end_date is not None: |
| 389 | + # Parse date inputs |
| 390 | + if start_date is not None: |
| 391 | + start_date_parsed = _parse_date_for_filtering(start_date) |
| 392 | + start_datetime = datetime.combine(start_date_parsed, datetime.min.time()) |
| 393 | + |
| 394 | + if end_date is not None: |
| 395 | + end_date_parsed = _parse_date_for_filtering(end_date) |
| 396 | + end_datetime = datetime.combine(end_date_parsed, datetime.max.time()) |
| 397 | + |
| 398 | + # Filter the DataFrame |
| 399 | + if start_date is not None and end_date is not None: |
| 400 | + df = df[(df.index >= start_datetime) & (df.index <= end_datetime)] |
| 401 | + elif start_date is not None: |
| 402 | + df = df[df.index >= start_datetime] |
| 403 | + elif end_date is not None: |
| 404 | + df = df[df.index <= end_datetime] |
| 405 | + |
| 406 | + return df |
| 407 | + |
| 408 | + except grpc.RpcError as e: |
| 409 | + print(f"gRPC Error: {e.code().name}") |
| 410 | + print(f"Details: {e.details()}") |
| 411 | + return pd.DataFrame() |
| 412 | + except Exception as e: |
| 413 | + print(f"Error: {str(e)}") |
| 414 | + return pd.DataFrame() |
| 415 | + |
314 | 416 | def _python_date_to_google_date(py_date): |
315 | 417 | """Convert Python date to Google Date protobuf message""" |
316 | 418 | return date_pb2.Date(year=py_date.year, month=py_date.month, day=py_date.day) |
|
0 commit comments