Skip to content

Commit 0e65be7

Browse files
author
Octave Belot
committed
Added a get_future_daily dataframe helpers
1 parent fec4af0 commit 0e65be7

File tree

1 file changed

+105
-3
lines changed

1 file changed

+105
-3
lines changed

src/systemathics/apis/helpers/dataframe_helpers.py

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
This module helps to create tokens to access Systemathics Ganymede authenticated API.
44
55
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.
79
"""
810

911

@@ -18,6 +20,8 @@
1820
from systemathics.apis.type.shared.v1 import date_interval_pb2 as date_interval
1921
import systemathics.apis.type.shared.v1.sampling_pb2 as sampling
2022
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
2125
import systemathics.apis.services.daily.v2.get_daily_pb2 as get_daily
2226
import systemathics.apis.services.daily.v2.get_daily_pb2_grpc as get_daily_service
2327
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
189193
print(f"Error: {str(e)}")
190194
return pd.DataFrame()
191195

192-
193-
194196
def get_cds_index_intraday(ticker, start_date=None, end_date=None, sampling=sampling.SAMPLING_ONE_MINUTE, selected_fields=None, provider="Markit"):
195197
"""
196198
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
311313
print(f"Error: {str(e)}")
312314
return pd.DataFrame()
313315

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+
314416
def _python_date_to_google_date(py_date):
315417
"""Convert Python date to Google Date protobuf message"""
316418
return date_pb2.Date(year=py_date.year, month=py_date.month, day=py_date.day)

0 commit comments

Comments
 (0)