ENH: Add simulated random trade source.

This adds a new data source that emits events
with certain user-specified frequency (minute
or daily).

This allows users to backtest and debug an
algorithm in minute mode to provide a cleaner
path towards Quantopian.
This commit is contained in:
twiecki
2014-03-22 21:22:22 -04:00
committed by Eddie Hebert
parent 803b58c8aa
commit 3eb810ad97
4 changed files with 213 additions and 4 deletions
+15 -1
View File
@@ -16,6 +16,7 @@
from unittest import TestCase
from datetime import timedelta
import numpy as np
import pandas as pd
from mock import MagicMock
from zipline.utils.test_utils import setup_logger
@@ -48,7 +49,9 @@ from zipline.utils.test_utils import drain_zipline, assert_single_position
from zipline.sources import (SpecificEquityTrades,
DataFrameSource,
DataPanelSource)
DataPanelSource,
RandomWalkSource)
from zipline.transforms import MovingAverage
from zipline.finance.trading import SimulationParameters
from zipline.utils.api_support import set_algo_instance
@@ -214,6 +217,17 @@ class TestTransformAlgorithm(TestCase):
algo.run(self.df)
def test_minute_data(self):
source = RandomWalkSource(freq='minute',
start=pd.Timestamp('2000-1-1',
tz='UTC'),
end=pd.Timestamp('2000-1-1',
tz='UTC'))
algo = TestOrderInstantAlgorithm(sim_params=self.sim_params,
data_frequency='minute',
instant_fill=True)
algo.run(source)
class TestPositions(TestCase):
+57 -1
View File
@@ -15,13 +15,17 @@
import pandas as pd
import pytz
from itertools import cycle
import numpy as np
from six import integer_types
from unittest import TestCase
import zipline.utils.factory as factory
from zipline.sources import DataFrameSource, DataPanelSource
from zipline.sources import (DataFrameSource,
DataPanelSource,
RandomWalkSource)
from zipline.utils import tradingcalendar as calendar_nyse
class TestDataFrameSource(TestCase):
@@ -75,3 +79,55 @@ class TestDataFrameSource(TestCase):
self.assertIn(check_field, event)
self.assertTrue(isinstance(event['volume'], (integer_types)))
self.assertEqual(next(stocks_iter), event['sid'])
class TestRandomWalkSource(TestCase):
def test_minute(self):
np.random.seed(123)
start_prices = {0: 100,
1: 500}
start = pd.Timestamp('1990-01-01', tz='UTC')
end = pd.Timestamp('1991-01-01', tz='UTC')
source = RandomWalkSource(start_prices=start_prices,
calendar=calendar_nyse, start=start,
end=end)
self.assertIsInstance(source.start, pd.lib.Timestamp)
self.assertIsInstance(source.end, pd.lib.Timestamp)
for event in source:
self.assertIn(event.sid, start_prices.keys())
self.assertIn(event.dt.replace(minute=0, hour=0),
calendar_nyse.trading_days)
self.assertGreater(event.dt, start)
self.assertLess(event.dt, end)
self.assertGreater(event.price, 0,
"price should never go negative.")
self.assertEqual(event.volume, 1000)
self.assertTrue(13 <= event.dt.hour <= 21,
"event.dt.hour == %i, not during market \
hours." % event.dt.hour)
def test_day(self):
np.random.seed(123)
start_prices = {0: 100,
1: 500}
start = pd.Timestamp('1990-01-01', tz='UTC')
end = pd.Timestamp('1992-01-01', tz='UTC')
source = RandomWalkSource(start_prices=start_prices,
calendar=calendar_nyse, start=start,
end=end, freq='day')
self.assertIsInstance(source.start, pd.lib.Timestamp)
self.assertIsInstance(source.end, pd.lib.Timestamp)
for event in source:
self.assertIn(event.sid, start_prices.keys())
self.assertIn(event.dt.replace(minute=0, hour=0),
calendar_nyse.trading_days)
self.assertGreater(event.dt, start)
self.assertLess(event.dt, end)
self.assertGreater(event.price, 0,
"price should never go negative.")
self.assertEqual(event.volume, 1000)
self.assertTrue(13 <= event.dt.hour <= 21,
"event.dt.hour == %i, not during market \
hours." % event.dt.hour)