@@ -45,6 +45,47 @@ class Currency(enum.IntFlag):
4545 INR = enum .auto ()
4646
4747
48+ def calendar_events (time_to : Union [datetime , timedelta ] = None ,
49+ * ,
50+ time_from : Union [datetime , timedelta ] = None ,
51+ importance : Union [Iterable [str ], str , int ] = None ,
52+ currencies : Union [Iterable [str ], str , int ] = None ,
53+ function : Callable = None ,
54+ round_minutes : int = 15 ,
55+ cache_clear : bool = False ,
56+ language : str = None ,
57+ ** kwargs ,
58+ ) -> List [dict ]:
59+ """Get economic events from mql5.com/calendar. A call with empty args will results in all events for the next week.
60+ Since the function is memoized, the time is rounded to ``round_minutes`` and cached. This avoids repeat requests
61+ to the mql5.com server. In order to refresh the results on subsequest function calls you'll need to set the
62+ ``cache_clear`` param to True.
63+
64+ :param time_to: Can be a timedelta or datetime object. If timedelta then the to time is calculated as
65+ datetime.now() + time_to. If the the time_from param is specified the the time_to will be calculated as
66+ time_from + time_to. Can also do a history look-back by passing in a negative timedelta to this param.
67+ :param time_from: Can be a timedelta or datetime object. If a timedelta object is passed then the time_from is
68+ calculated as time_from + now(), thus it needs to be a negative delta.
69+ :param importance: Can be int flags from the Importance enum class, and iterable of strings or a (space and/or
70+ comma separated string)
71+ :param currencies: Can be int flags from the Importance enum class, and iterable of strings or a (space and/or
72+ comma separated string) Pairs are automatically separated to the respective currency codes.
73+ :param function: A callback function that receives an event dict and returns bool for filtering.
74+ :param round_minutes: Round the number of minutes to this factor. Rounding aides the memoization of parameters.
75+ :param cache_clear: Clear the memo cache to refresh events from the server.
76+ :param language: The language code for the calendar. Default is 'en'
77+ :param kwargs:
78+ :return:
79+ """
80+ cal_args = _construct_args (** locals ())
81+ if cache_clear :
82+ _get_calendar_events .cache_clear ()
83+ events = _get_calendar_events (language = language , ** cal_args )
84+ if function :
85+ events = list (filter (function , events ))
86+ return events
87+
88+
4889@functools .lru_cache
4990def _get_calendar_events (datetime_from : datetime ,
5091 datetime_to : datetime ,
@@ -72,11 +113,11 @@ def _get_calendar_events(datetime_from: datetime,
72113 e ['Url' ] = _BASE_URL + e ['Url' ]
73114 e ['ReleaseDate' ] = time
74115 e ['request' ] = data
75- filtered_events . append ( e )
76- filtered_events = [
77- { _camel_to_snake ( k ): v for k , v in x . items () if k not in _OMIT_RESULT_KEYS }
78- for x in filtered_events
79- ]
116+ formatted_event = {}
117+ for k , v in e . items ():
118+ if k not in _OMIT_RESULT_KEYS :
119+ formatted_event [ _camel_to_snake ( k )] = v
120+ filtered_events . append ( formatted_event )
80121 return filtered_events
81122
82123
@@ -106,10 +147,10 @@ def _camel_to_snake(w):
106147 return w
107148
108149
109- _camel_to_snake .pattern = re .compile (r'[A-Z][a-z]+ ' )
150+ _camel_to_snake .pattern = re .compile (r'[A-Z][a-z]* ' )
110151
111152
112- @functools .lru_cache
153+ @functools .lru_cache ( maxsize = 128 , typed = True )
113154def _make_flag (enum_cls : Union [Type [Importance ], Type [Currency ]],
114155 flags : Union [Iterable [str ], int , str ] = None
115156 ) -> int :
@@ -126,40 +167,12 @@ def _make_flag(enum_cls: Union[Type[Importance], Type[Currency]],
126167 return int (flag )
127168
128169
129- def calendar_events (time_to : Union [datetime , timedelta ] = None ,
130- * ,
131- time_from : Union [datetime , timedelta ] = None ,
132- importance : Union [Iterable [str ], str , int ] = None ,
133- currencies : Union [Iterable [str ], str , int ] = None ,
134- function : Callable = None ,
135- round_minutes : int = 15 ,
136- cache_clear : bool = False ,
137- language : str = None ,
138- ** kwargs ,
139- ) -> List [dict ]:
140- """Get economic events from mql5.com/calendar. A call with empty args will results in all events for the next week.
141- Since the function is memoized, the time is rounded to ``round_minutes`` and cached. This avoids repeat requests
142- to the mql5.com server. In order to refresh the results on subsequest function calls you'll need to set the
143- ``cache_clear`` param to True.
144-
145- :param time_to: Can be a timedelta or datetime object. If timedelta then the to time is calculated as
146- datetime.now() + time_to. If the the time_from param is specified the the time_to will be calculated as
147- time_from + time_to. Can also do a history look-back by passing in a negative timedelta to this param.
148- :param time_from: Can be a timedelta or datetime object. If a timedelta object is passed then the time_from is
149- calculated as time_from + now(), thus it needs to be a negative delta.
150- :param importance: Can be int flags from the Importance enum class, and iterable of strings or a (space and/or
151- comma separated string)
152- :param currencies: Can be int flags from the Importance enum class, and iterable of strings or a (space and/or
153- comma separated string) Pairs are automatically separated to the respective currency codes.
154- :param function: A callback function that receives an event dict and returns bool for filtering.
155- :param round_minutes: Round the number of minutes to this factor. Rounding aides the memoization of parameters.
156- :param cache_clear: Clear the memo cache to refresh events from the server.
157- :param language: The language code for the calendar. Default is 'en'
158- :param kwargs:
159- :return:
160- """
161- if cache_clear :
162- _get_calendar_events .cache_clear ()
170+ def _construct_args (** kw ):
171+ time_to = kw .get ('time_to' )
172+ time_from = kw .get ('time_from' )
173+ round_minutes = kw .get ('round_minutes' )
174+ importance = kw .get ('importance' )
175+ currencies = kw .get ('currencies' )
163176 now = datetime .now ()
164177 if time_to is None and time_from is None :
165178 time_to = now + timedelta (weeks = 1 )
@@ -174,11 +187,5 @@ def calendar_events(time_to: Union[datetime, timedelta] = None,
174187 _f = lambda x : tuple (x ) if isinstance (x , Iterable ) and not isinstance (x , str ) else x
175188 importance , currencies = _f (importance ), _f (currencies )
176189 i_flag , c_flag = _make_flag (Importance , importance ), _make_flag (Currency , currencies )
177- events = _get_calendar_events (datetime_from = time_from ,
178- datetime_to = time_to ,
179- importance = i_flag ,
180- currencies = c_flag ,
181- language = language )
182- if function :
183- events = list (filter (function , events ))
184- return events
190+ res_args = dict (datetime_to = time_to , datetime_from = time_from , importance = i_flag , currencies = c_flag )
191+ return res_args
0 commit comments