code: def PumpEvents(timeout=-1, hevt=None, cb=None):
      """This following code waits for 'timeout' seconds in the way
      required for COM, internally doing the correct things depending
      on the COM appartment of the current thread.  It is possible to
      terminate the message loop by pressing CTRL+C, which will raise
      a KeyboardInterrupt.
      """
      # XXX Should there be a way to pass additional event handles which
      # can terminate this function?
  
      # XXX XXX XXX
      #
      # It may be that I misunderstood the CoWaitForMultipleHandles
      # function.  Is a message loop required in a STA?  Seems so...
      #
      # MSDN says:
      #
      # If the caller resides in a single-thread apartment,
      # CoWaitForMultipleHandles enters the COM modal loop, and the
      # thread's message loop will continue to dispatch messages using
      # the thread's message filter. If no message filter is registered
      # for the thread, the default COM message processing is used.
      #
      # If the calling thread resides in a multithread apartment (MTA),
      # CoWaitForMultipleHandles calls the Win32 function
      # MsgWaitForMultipleObjects.
  
      # Timeout expected as float in seconds - *1000 to miliseconds
      # timeout = -1 -> INFINITE 0xFFFFFFFF;
      # It can also be a callable which should return an amount in seconds
  
      if hevt is None:
          hevt = ctypes.windll.kernel32.CreateEventA(
              None, True, False, None
          )
  
      handles = _handles_type(hevt)
      RPC_S_CALLPENDING = -2147417835
  
      # @ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint)
      def HandlerRoutine(dwCtrlType):
          if dwCtrlType == 0:  # CTRL+C
              ctypes.windll.kernel32.SetEvent(hevt)
              return 1
          return 0
  
      HandlerRoutine = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint)(
          HandlerRoutine
      )
  
      ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 1)
      while True:
          try:
              tmout = timeout()  # check if it's a callable
          except TypeError:
              tmout = timeout  # it seems to be a number
  
          if tmout > 0:
              tmout *= 1000
          tmout = int(tmout)
  
          try:
              res = ctypes.oledll.ole32.CoWaitForMultipleHandles(
                  0,  # COWAIT_FLAGS
                  int(tmout),  # dwtimeout
                  len(handles),  # number of handles in handles
                  handles,  # handles array
                  # pointer to indicate which handle was signaled
                  ctypes.byref(ctypes.c_ulong()),
              )
  
          except WindowsError as details:
              if (
                  details.args[0] == RPC_S_CALLPENDING
              ):  # timeout expired
                  if cb is not None:
                      cb()
  
                  continue
  
              else:
                  ctypes.windll.kernel32.CloseHandle(hevt)
                  ctypes.windll.kernel32.SetConsoleCtrlHandler(
                      HandlerRoutine, 0
                  )
                  raise  # something else happened
          else:
              ctypes.windll.kernel32.CloseHandle(hevt)
              ctypes.windll.kernel32.SetConsoleCtrlHandler(
                  HandlerRoutine, 0
              )
              raise KeyboardInterrupt
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import collections
  from datetime import date, datetime, time, timedelta
  import os.path
  import threading
  import time
  import ctypes
  from backtrader import TimeFrame, Position
  from backtrader.feed import DataBase
  from backtrader.metabase import MetaParams
  from backtrader.utils.py3 import MAXINT, range, queue, string_types, with_metaclass
  from backtrader.utils import AutoDict
label_desc: Use image node_id 1 for calling a global function with example usage: PumpEvents(timeout, hevt, cb) and returns: int, int