Skip to content

Commit

Permalink
- add : 添加了使用 mock 更改时间戳的说明
Browse files Browse the repository at this point in the history
  • Loading branch information
lamter committed Jul 14, 2016
1 parent 4a5c0eb commit d0b9a93
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 53 deletions.
4 changes: 2 additions & 2 deletions easyquant/main_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class MainEngine:
"""主引擎,负责行情 / 事件驱动引擎 / 交易"""

def __init__(self, broker=None, need_data=None, quotation_engines=None,
log_handler=DefaultLogHandler(), now=None, tzinfo=None):
log_handler=DefaultLogHandler(), tzinfo=None):
"""初始化事件 / 行情 引擎并启动事件引擎
"""
self.log = log_handler
Expand All @@ -46,7 +46,7 @@ def __init__(self, broker=None, need_data=None, quotation_engines=None,
self.log.info('选择了无交易模式')

self.event_engine = EventEngine()
self.clock_engine = ClockEngine(self.event_engine, now, tzinfo)
self.clock_engine = ClockEngine(self.event_engine, tzinfo)

quotation_engines = quotation_engines or [DefaultQuotationEngine]

Expand Down
40 changes: 19 additions & 21 deletions easyquant/push_engine/clock_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,15 @@ class ClockEngine:
"""
EventType = 'clock_tick'

def __init__(self, event_engine, now=None, tzinfo=None):
def __init__(self, event_engine, tzinfo=None):
"""
:param event_engine:
:param event_engine: tzinfo
:return:
"""
# 默认使用当地时间的时区
self.tzinfo = tzinfo or tz.tzlocal()
# 引擎启动的时间,默认为当前.测试时可手动设置模拟各个时间段.
self.time_delta = self._delta(now)
# self.start_time = self.now_dt.replace(hour=0, minute=0, second=0, microsecond=0)

self.event_engine = event_engine
self.is_active = True
self.clock_engine_thread = Thread(target=self.clocktick)
Expand Down Expand Up @@ -150,23 +148,23 @@ def close():
for interval in (0.5, 1, 5, 15, 30, 60):
self.register_interval(interval)

def _delta(self, now):
if now is None:
return 0
if now.tzinfo is None:
now = arrow.get(datetime.datetime(
now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond, self.tzinfo,
))

return (arrow.now() - now).total_seconds()
# def _delta(self, now):
# if now is None:
# return 0
# if now.tzinfo is None:
# now = arrow.get(datetime.datetime(
# now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond, self.tzinfo,
# ))
#
# return (arrow.now() - now).total_seconds()

@property
def now(self):
"""
now 时间戳统一接口
:return:
"""
return time.time() - self.time_delta
return time.time()

@property
def now_dt(self):
Expand All @@ -175,13 +173,13 @@ def now_dt(self):
"""
return arrow.get(self.now).to(self.tzinfo)

def reset_now(self, now=None):
"""
调试用接口,请勿在生产环境使用
:param now:
:return:
"""
self.time_delta = self._delta(now)
# def reset_now(self, now=None):
# """
# 调试用接口,请勿在生产环境使用
# :param now:
# :return:
# """
# self.time_delta = self._delta(now)

def start(self):
self.clock_engine_thread.start()
Expand Down
45 changes: 15 additions & 30 deletions unitest_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"""
import time
import unittest
from unittest import mock
import datetime
import pandas as pd
from easyquant.easydealutils.time import get_next_trade_date, is_trade_date
import arrow

from dateutil import tz
from easyquant.main_engine import MainEngine
Expand Down Expand Up @@ -57,7 +59,7 @@ def setUp(self):

now = datetime.datetime.combine(self.trade_date, self.time)
# 此处重新定义 main_engine
self._main_engine = MainEngine('ht', now=now)
self._main_engine = MainEngine('ht', 'tmp/ht.json')

# 设置为不在交易中
self.clock_engine.trading_state = False
Expand Down Expand Up @@ -86,41 +88,24 @@ def tearDown(self):
def test_set_now(self):
"""
重设 clock_engine 的时间
通过 mock 来重设时间戳
mock 只能重设 time.time 函数的时间戳,但是不能重设 datetime.datetime.now 函数的时间戳,详情见:
http://stackoverflow.com/questions/4481954/python-trying-to-mock-datetime-date-today-but-not-working
:return:
"""

tzinfo = tz.tzlocal()
now = datetime.datetime.combine(
self.trade_date,
datetime.time(8, 59, 00, tzinfo=tzinfo),
)
clock_engien = ClockEngine(EventEngine(), now, tzinfo)

# 去掉微秒误差后比较
self.assertEqual(clock_engien.now_dt.replace(microsecond=0), now)

def test_reset_now(self):
"""
重设时钟引擎当前时间为其他时间点
:return:
"""
tzinfo = tz.tzlocal()
clock_engien = ClockEngine(EventEngine())
now = datetime.datetime.combine(
self.trade_date,
datetime.time(8, 59, 00, tzinfo=tzinfo),
)
clock_engien.reset_now(now)
# 使用datetime 类构建时间戳,转化为浮点数时间戳
now = datetime.datetime(1990, 10, 16, 19, 27, 16)

# 去掉微秒误差后比较
self.assertEqual(clock_engien.now_dt.replace(microsecond=0), now)
# 通过mock ,将 time.time() 函数的返回值重设为上面的打算模拟的值
time.time = mock.Mock(return_value=now)

# 重设为当前时间
clock_engien.reset_now()
now = datetime.datetime.now(tzinfo).replace(microsecond=0)
# 生成一个时钟引擎
clock_engien = ClockEngine(EventEngine(), tzinfo)

# 去掉微秒误差后比较
self.assertEqual(clock_engien.now_dt.replace(microsecond=0), now)
# 去掉微秒误差后验证其数值
self.assertEqual(clock_engien.now, now) # time.time 时间戳
self.assertEqual(clock_engien.now_dt, arrow.get(now)) # datetime 时间戳

def test_clock_moment_is_active(self):
# 设置时间
Expand Down

0 comments on commit d0b9a93

Please sign in to comment.