class_docstr: OnlineManager can manage online models with `Online Strategy <#Online Strategy>`_.
  It also provides a history recording of which models are online at what time.
docstr: Typical update process for every strategy and record the online history.
  
  The typical update process after a routine, such as day by day or month by month.
  The process is: Update predictions -> Prepare tasks -> Prepare online models -> Prepare signals.
  
  If using DelayTrainer, it can finish training all together after every strategy's prepare_tasks.
  
  Args:
      cur_time (Union[str,pd.Timestamp], optional): run routine method in this time. Defaults to None.
      task_kwargs (dict): the params for `prepare_tasks`
      model_kwargs (dict): the params for `prepare_online_models`
      signal_kwargs (dict): the params for `prepare_signals`
docstr_tok: ["Typical","update","process","for","every","strategy","and","record","the","online","history",".","The","typical","update","process","after","a","routine",",","such","as","day","by","day","or","month","by","month",".","The","process","is",":","Update","predictions","-",">","Prepare","tasks","-",">","Prepare","online","models","-",">","Prepare","signals",".","If","using","DelayTrainer",",","it","can","finish","training","all","together","after","every","strategy","'s","prepare_tasks",".","Args",":","cur_time","(","Union","[","str",",","pd.Timestamp","]",",","optional",")",":","run","routine","method","in","this","time",".","Defaults","to","None",".","task_kwargs","(","dict",")",":","the","params","for","`","prepare_tasks","`","model_kwargs","(","dict",")",":","the","params","for","`","prepare_online_models","`","signal_kwargs","(","dict",")",":","the","params","for","`","prepare_signals","`"]
code: def routine(
      self,
      cur_time: Union[str, pd.Timestamp] = None,
      task_kwargs: dict = {},
      model_kwargs: dict = {},
      signal_kwargs: dict = {},
  ):
      """
      Typical update process for every strategy and record the online history.
  
      The typical update process after a routine, such as day by day or month by month.
      The process is: Update predictions -> Prepare tasks -> Prepare online models -> Prepare signals.
  
      If using DelayTrainer, it can finish training all together after every strategy's prepare_tasks.
  
      Args:
          cur_time (Union[str,pd.Timestamp], optional): run routine method in this time. Defaults to None.
          task_kwargs (dict): the params for `prepare_tasks`
          model_kwargs (dict): the params for `prepare_online_models`
          signal_kwargs (dict): the params for `prepare_signals`
      """
      if cur_time is None:
          cur_time = D.calendar(freq=self.freq).max()
      self.cur_time = pd.Timestamp(cur_time)  # None for latest date
  
      models_list = []
      for strategy in self.strategies:
          self.logger.info(
              f"Strategy `{strategy.name_id}` begins routine..."
          )
  
          tasks = strategy.prepare_tasks(self.cur_time, **task_kwargs)
          models = self.trainer.train(
              tasks, experiment_name=strategy.name_id
          )
          models_list.append(models)
          self.logger.info(f"Finished training {len(models)} models.")
          online_models = strategy.prepare_online_models(
              models, **model_kwargs
          )
          self.history.setdefault(self.cur_time, {})[
              strategy
          ] = online_models
  
          # The online model may changes in the above processes
          # So updating the predictions of online models should be the last step
          if self.status == self.STATUS_ONLINE:
              strategy.tool.update_online_pred()
  
      if not self._postpone_action():
          for strategy, models in zip(self.strategies, models_list):
              models = self.trainer.end_train(
                  models, experiment_name=strategy.name_id
              )
          self.prepare_signals(**signal_kwargs)
  
imports: import logging
  from typing import Callable, List, Union
  import pandas
  from qlib import get_module_logger
  from qlib.data.data import D
  from qlib.log import set_global_logger_level
  from qlib.model.ens.ensemble import AverageEnsemble
  from qlib.model.trainer import Trainer, TrainerR
  from qlib.utils.serial import Serializable
  from qlib.workflow.online.strategy import OnlineStrategy
  from qlib.workflow.task.collect import MergeCollector
label_desc: Use image node_id 4 for calling the OnlineManager obj's underlying member method code with example usage: obj.routine(cur_time, task_kwargs, model_kwargs, signal_kwargs) without return types