@@ -84,10 +84,13 @@ def signal_query(
84
84
self ,
85
85
signal : Union [str , Column , Sequence [Union [str , Column ]]],
86
86
bloomberg_ticker : Union [str , Sequence [str ]] = None ,
87
+ * ,
87
88
factset_id : Union [str , Sequence [str ]] = None ,
88
89
tag : Union [str , Sequence [str ]] = None ,
89
90
start_time : Union [str , pd .Timestamp ] = None ,
90
91
end_time : Union [str , pd .Timestamp ] = None ,
92
+ identifier : Union [Column , Sequence [Column ]] = None ,
93
+ version : Union [str , pd .Timestamp , Sequence [str ], Sequence [pd .Timestamp ]] = None ,
91
94
) -> Union [pd .Series , pd .DataFrame ]:
92
95
"""
93
96
Run a query for one or more signals.
@@ -106,6 +109,15 @@ def signal_query(
106
109
or with any of the provided tags if several.
107
110
start_time: the first date to retrieve data for
108
111
end_time: the last date to retrieve data for
112
+ identifier: the identifier(s) to return to identify the entities in the result.
113
+ By default, will use Signals.NAME if multiple identifiers
114
+ or a tag are given, or else no identifier.
115
+ version: the Point-in-Time at which to evaluate the signals,
116
+ or a list of such dates at which to evaluate the signals.
117
+ If a list of dates is provided, 'version' will be included as a column
118
+ in the result.
119
+ If no version is specified, then the signals will be evaluated with the
120
+ latest available data (the default).
109
121
110
122
Returns:
111
123
A pandas Series if the result is a single time series,
@@ -116,6 +128,8 @@ def signal_query(
116
128
"""
117
129
if not signal :
118
130
raise ValueError ("Must specify signal to retrieve" )
131
+
132
+ # Specify entity filter
119
133
multi_company = False
120
134
predicates : List [Predicate ] = []
121
135
if factset_id :
@@ -138,18 +152,41 @@ def signal_query(
138
152
multi_company = True
139
153
if len (predicates ) > 1 :
140
154
raise ValueError ("At most one company identification method can be specified" )
141
- if multi_company :
142
- index = [Signals .NAME , Signals .TIME ]
155
+
156
+ # Specify the identifier(s)
157
+ index : List [Column ] = []
158
+ if identifier is None :
159
+ if multi_company :
160
+ index .append (Signals .NAME )
161
+ elif isinstance (identifier , Column ):
162
+ index .append (identifier )
143
163
else :
144
- index = [Signals .TIME ]
164
+ index .extend (identifier )
165
+ index .append (Signals .TIME )
166
+
167
+ # Specify version(s), if provided
168
+ if version :
169
+ if isinstance (version , (str , pd .Timestamp )):
170
+ predicates .append (Signals .VERSION .equal (version ))
171
+ else :
172
+ predicates .append (Signals .VERSION .in_list (* version ))
173
+ index .insert (0 , Signals .VERSION )
174
+
175
+ # The columns to query for
145
176
columns : List [Union [str , Column ]] = list (index )
146
177
if isinstance (signal , (str , Column )):
147
178
columns .append (signal )
148
179
else :
149
180
columns .extend (signal )
181
+
182
+ # Execute the query
150
183
query = Signals .query (
151
184
columns , start_time = start_time , end_time = end_time , predicates = predicates
152
185
)
153
186
df = self .run_query (query .sql ())
187
+
188
+ # Set the row index
154
189
df .set_index ([col .name for col in index ], inplace = True )
190
+ # Squeeze to a Series if a single time series was returned,
191
+ # and fix the data type (the backend returns a DataFrame with dtype=object)
155
192
return df .squeeze (axis = 1 ).infer_objects ()
0 commit comments