schedule function offsets

Makes `AfterOpen` an offset from the actual market open, not from the first bar of data for a day.

Prevents offsets of 0 from being passed to `AfterOpen` or `BeforeClose`.
In another branch, I rewrote the tests to be much more complete. I think this caching is a requirement because it made the tests run 4 times faster.