Timers 有一下选项可以用于控制相关操作:
Timer based in absolute time input or with regards to session start/end times
Timezone specification for the time specification, be it directly or via pytz compatible objects or via data feed session end times
Starting offset with regards to the specified time
Repetitions intervals
Weekdays filter (with carry over option)
Monthdays filter (with carry over option)
-Custom callback filter
Usage pasttern
Both in Cerebro and Strategy subclasses the timer callback will be received in the following method.
def notify_timer(self, timer, when, *args, **kwargs):
'''Receives a timer notification where ``timer`` is the timer which was
returned by ``add_timer``, and ``when`` is the calling time. ``args``
and ``kwargs`` are any additional arguments passed to ``add_timer``
The actual ``when`` time can be later, but the system may have not be
able to call the timer before. This value is the timer value and not the
system time.
'''
- Adding timers - Via Strategy
- Adding timers - Via Cerebro
Done with the same method and just the addition of the parameter strats. If set to True the timer will not only be notified to the cerebro, it will also be notified to all strategies running in the system. strats 设定为True 则Timer作用于这个回测系统,不只是cerebro
def add_timer(self, when,
offset=datetime.timedelta(), repeat=datetime.timedelta(),
weekdays=[], weekcarry=False,
monthdays=[], monthcarry=True,
allow=None,
tzdata=None, cheat=False, strats=False,
*args, **kwargs):
'''
Parameters to add_timer
when
: can bedatetime.time
instance (see belowtzdata
)bt.timer.SESSION_START
to reference a session startbt.timer.SESSION_END
to reference a session endoffset which must be a datetime.timedelta instance
Used to offset the value when. It has a meaningful use in combination with SESSION_START and SESSION_END, to indicated things like a timer being called 15 minutes after the session start.
- repeat which must be a datetime.timedelta instance
Indicates if after a 1st call, further calls will be scheduled within the same session at the scheduled repeat delta
Once the timer goes over the end of the session it is reset to the original value for when
weekdays: a sorted iterable with integers indicating on which days (iso codes, Monday is 1, Sunday is 7) the timers can be actually invoked
If not specified, the timer will be active on all daysweekcarry (default: False). If True and the weekday was not seen (ex: trading holiday), the timer will be executed on the next day (even if in a new week)
monthdays: a sorted iterable with integers indicating on which days of the month a timer has to be executed. For example always on day 15 of the month
If not specified, the timer will be active on all days
monthcarry (default: True). If the day was not seen (weekend, trading holiday), the timer will be executed on the next available day.
allow (default: None). A callback which receives a datetime.date` instance and returns True if the date is allowed for timers or else returns False
tzdata which can be either None (default), a pytz instance or a data feed instance.
None: when is interpreted at face value (which translates to handling it as if it where UTC even if it’s not)
pytz instance: when will be interpreted as being specified in the local time specified by the timezone instance.
data feed instance: when will be interpreted as being specified in the local time specified by the tz parameter of the data feed instance.
[Note] Ifwhen
is eitherSESSION_START
orSESSION_END
andtzdata
is
None
, the 1st data feed in the system (akaself.data0
) will be
used as the reference to find out the session times.strats (default: False) call also the notify_timer of strategies
cheat (default False) if True the timer will be called before the broker has a chance to evaluate the orders. This opens the chance to issue orders based on opening price for example right before the session starts
*args: any extra args will be passed to notify_timer
**kwargs: any extra kwargs will be passed to notify_timer
Example for allow=callable
allow=callable where the callable accepts datetime.date instance. Notice this is not a datetime.datetime instance, because the allow callable is only meant to decide if a given day is suitable for timers or not.
To implement something like the rule laid out above:
class FutOpExp(object):
def __init__(self):
self.fridays = 0
self.curmonth = -1
def __call__(self, d):
_, _, isowkday = d.isocalendar()
if d.month != self.curmonth:
self.curmonth = d.month
self.fridays = 0
# Mon=1 ... Sun=7
if isowkday == 5 and self.curmonth in [3, 6, 9, 12]:
self.fridays += 1
if self.friday == 3: # 3rd Friday
return True # timer allowed
return False # timer disallowed
And one would pass allow=FutOpeExp() to the creation of the timer
This would allow a timer to kick in on the 3rd Friday of those months and may be close positions before the futures expire.