├── .gitignore ├── MANIFEST.in ├── requirements.txt ├── rqalpha_mod_event_queue ├── __init__.py ├── mod.py └── queued_event_bus.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | *.iml 4 | *.pyc 5 | dist 6 | *.ipynb 7 | *.log 8 | *.con 9 | .coverage 10 | .idea 11 | *.egg-info 12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | rqalpha -------------------------------------------------------------------------------- /rqalpha_mod_event_queue/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | def load_mod(): 4 | from .mod import EventQueueMod 5 | return EventQueueMod() 6 | -------------------------------------------------------------------------------- /rqalpha_mod_event_queue/mod.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from rqalpha.interface import AbstractMod 4 | from rqalpha.const import RUN_TYPE 5 | 6 | from .queued_event_bus import QueuedEventBus 7 | 8 | 9 | class EventQueueMod(AbstractMod): 10 | def __init__(self): 11 | self._env = None 12 | self._mod_config = None 13 | 14 | def start_up(self, env, mod_config): 15 | self._env = env 16 | self._mod_config = mod_config 17 | if self._env.config.base.run_type == RUN_TYPE.BACKTEST: 18 | return 19 | self._env.event_bus = QueuedEventBus(self._env.event_bus) 20 | self._env.event_bus.start() 21 | 22 | def tear_down(self, code, exception=None): 23 | if self._env.config.base.run_type == RUN_TYPE.BACKTEST: 24 | return 25 | 26 | if isinstance(self._env.event_bus, QueuedEventBus): 27 | self._env.event_bus.stop() 28 | 29 | -------------------------------------------------------------------------------- /rqalpha_mod_event_queue/queued_event_bus.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | try: 4 | from queue import Queue, Empty 5 | except ImportError: 6 | from Queue import Queue, Empty 7 | 8 | from threading import Thread 9 | 10 | from rqalpha.events import EventBus, EVENT 11 | 12 | 13 | EVENT.TIMER = 'timer' 14 | 15 | 16 | class QueuedEventBus(EventBus): 17 | def __init__(self, event_bus=None): 18 | super(QueuedEventBus, self).__init__() 19 | 20 | self._event_queue = Queue() 21 | self._thread = Thread(target=self.run) 22 | self._running = False 23 | 24 | if event_bus: 25 | self._listeners = event_bus._listeners 26 | 27 | DISTINCT_EVENTS = [ 28 | EVENT.TICK, 29 | EVENT.BAR, 30 | EVENT.DO_PERSIST, 31 | EVENT.TIMER, 32 | ] 33 | 34 | def publish_event(self, event): 35 | self._event_queue.put(event) 36 | 37 | def run(self): 38 | while self._running: 39 | try: 40 | events = [self._event_queue.get(timeout=1)] 41 | except Empty: 42 | continue 43 | while True: 44 | try: 45 | events.append(self._event_queue.get_nowait()) 46 | except Empty: 47 | break 48 | 49 | last_pos = {} 50 | 51 | for i, e in enumerate(events): 52 | if e.event_type in self.DISTINCT_EVENTS: 53 | last_pos[e.event_type] = i 54 | 55 | for i, e in enumerate(events): 56 | if e.event_type in self.DISTINCT_EVENTS and i != last_pos[e.event_type]: 57 | continue 58 | for l in self._listeners[e.event_type]: 59 | # 如果返回 True ,那么消息不再传递下去 60 | if l(e): 61 | break 62 | 63 | def start(self): 64 | self._running = True 65 | self._thread.start() 66 | 67 | def stop(self): 68 | self._running = False 69 | self._thread.join() 70 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from setuptools import setup, find_packages 4 | from pip.req import parse_requirements 5 | 6 | 7 | setup( 8 | name='rqalpha-mod-event-queue', 9 | version='0.0.5', 10 | description='A mod for RQAlpha to replace its default event bus with a queued event bus.', 11 | packages=find_packages(exclude=[]), 12 | author='cuizi7', 13 | author_email='cuizi7@163.com', 14 | license='Apache License v2', 15 | package_data={'': ['*.*']}, 16 | install_requires=[str(ir.req) for ir in parse_requirements("requirements.txt", session=False)], 17 | zip_safe=False, 18 | classifiers=[ 19 | 'Programming Language :: Python', 20 | 'Operating System :: Microsoft :: Windows', 21 | 'Operating System :: Unix', 22 | 'Programming Language :: Python :: 2.7', 23 | 'Programming Language :: Python :: 3.4', 24 | 'Programming Language :: Python :: 3.5', 25 | 'Programming Language :: Python :: 3.6', 26 | ], 27 | ) 28 | --------------------------------------------------------------------------------