예제 #1
0
class TestSymbols(unittest.TestCase):
    def setUp(self):
        self.symbols = Symbols()

        conn = pymongo.MongoClient()
        db = conn.test_marketdata
        symbols = db.test_symbols

        self.symbols._symbols = symbols  # replaces real db with test one
        self.symbols.clean()

    def test_clean(self):
        self.symbols.add(['AAPL'])
        self.symbols.clean()
        act = self.symbols.symbols()
        self.assertEquals(0, len(act))

    def test_add(self):
        exp = ['AAPL']
        self.symbols.add(exp)
        self.assertListEqual(exp, self.symbols.symbols())

    def test_remove(self):
        exp = ['AAPL']
        added = ['MSFT']
        self.symbols.add(exp + added)
        self.symbols.remove(added)
        self.assertListEqual(exp, self.symbols.symbols())
예제 #2
0
class UpdateMarketDataIntegrationTest(unittest.TestCase):
    def setUp(self):
        self.symbols = Symbols()

        conn = pymongo.MongoClient()
        db = conn.test_marketdata
        symbols = db.test_symbols

        self.symbols._symbols = symbols  # replaces real db with test one
        self.symbols.clean()
        self.symbols.add(['AAPL'])

    def test_update_marketdata(self):
        from_date = datetime(2012, 9, 20)
        to_date = datetime(2012, 9, 21)
        update_marketdata(from_date, to_date, self.symbols)

        res = self.symbols.select_historical_prices('AAPL', from_date, to_date)
        self.assertEqual(2, len(res))
        self.assertEqual(from_date, res[0]['date'])
        self.assertEqual(to_date, res[1]['date'])
        self.assertEqual(705.07, res[1]['high'])
예제 #3
0
class DataSource(object):

    '''
    Spec for a Stock data source
    '''
    __metaclass__ = abc.ABCMeta

    def __init__(self, name, fields, exchanges=[]):
        '''
        Constructor
        '''
        self.name = name
        self.exchanges = exchanges
        self.rawpath = join(Config.DATA_BASEDIR, "raw/US", name)
        self.pklpath = join(Config.DATA_BASEDIR, "processed/US", name)
        self.date_from = datetime.datetime(1990, 1, 1)
        self.date_to = datetime.datetime.now()
        self.symbols = Symbols()

        self.csv_delimiter = ","
        self.csv_skiprows = 1
        self.csv_cols = range(0, 7)  # date, o, h, l, c, v, adj_close

        self.fields = fields
        self.field_name_to_idx = {f[1]: f[0] for f in enumerate(fields)}
        self.raw_datefile = join(Config.MYDIR, "NYSE_dates.txt")
        self.datefile = join(Config.DATA_BASEDIR, "NYSE_dates.pkl")
        self.dates = None
        self.dtype = self._setup_dtype()

        self.num_workers = 4

        if not os.path.exists(self.rawpath):
            os.makedirs(self.rawpath)

        if not os.path.exists(self.pklpath):
            os.makedirs(self.pklpath)

        if not os.path.exists(self.datefile):
            self._setup_dataframe()

    def __repr__(self):
        res = "name: " + self.name
        res += "\n  rawpath: " + self.rawpath
        res += "\n  pklpath: " + self.pklpath
        res += "\n  exchanges: " + ", ".join([x.name for x in self.exchanges])
        return res

    def _setup_dtype(self):
        """
        Data types need to be specified for the columns of CSV files.

        * Date object is stored in object format.
        * All other fields are parsed as float.
        """

        names = []
        formats = []
        for f in self.fields:
            names.append(f)
            if f == DataItem.DATE:
                formats.append("O")  # date in object format
            else:
                formats.append(float)
        return {'names': names, 'formats': formats}

    def _csvfile(self, sym):
        """
        CVS file for a given symbol
        """
        return join(self.rawpath, sym + ".csv")

    def _pklfile(self, sym):
        """
        Pickle file for a given symbol
        """
        return join(self.pklpath, sym + ".pkl")

    @property
    def symbol_list(self):
        """
        Returns a list of symbols for all exchanges
        """
        return reduce(lambda x, y: x + y.symbol_list(), self.exchanges, [])

    @abc.abstractmethod
    def _hist_url(self, date_from, date_to, symbol):
        """
        Returns a URL for getting the historical data from the web
        """
        return

    @abc.abstractmethod
    def _csv_field_converters(self):
        """
        Converters for the CSV columns.

        Numpy can do the simple conversions, But converters need to be
        specified for complex fields. E.g. parsing a Data string to
        datetime object
        """
        return

    def _setup_dataframe(self, datefile=None):
        """
        Setup an empty dataframe using NYSE dates as index.

        This will be used to as base frame for the stock data.
        """
        if datefile is None:
            datefile = self.raw_datefile
        dates = np.loadtxt(datefile, dtype='O',
                           converters={
                               0: lambda x: dt.strptime(x, "%m/%d/%Y")
                           })
        dateIdx = pandas.tseries.index.DatetimeIndex(dates)
        empty_df = pandas.DataFrame(index=dateIdx)
        empty_df.save(self.datefile)

    def _load_dataframe(self):
        """
        Load the previously saved dataframe
        """
        return read_pickle(self.datefile)

    def download(self, symbol):
        """Download data for a given symbol

        This will store the data in pickle file
        """
        url = self._hist_url(self.date_from, self.date_to, symbol)
        url_get = urllib2.urlopen(url)
        # url_get = open(DataSource.TESTFILE, "rb")
        csvfile = open(self._csvfile(symbol), "wb")
        csvfile.write(url_get.read())
        csvfile.close()

        self._pickle(symbol)

        return symbol

    def _load_csv(self, symbol):
        """
        Load a CSV file into a pandas Dataframe
        """
        data_file = self._csvfile(symbol)
        data = np.loadtxt(data_file,
                          dtype=self.dtype,
                          delimiter=self.csv_delimiter,
                          skiprows=self.csv_skiprows,
                          converters=self._csv_field_converters(),
                          usecols=self.csv_cols)
        data = data[::-1]  # reverse the order
        fields = data.dtype.names[1:]  # all except the date
        df = pandas.DataFrame({f: data[f]
                              for f in fields}, index=data[DataItem.DATE])
        return df

    def _pickle(self, symbol):
        """
        Load CSV data and save the object to a file.

        load_csv is expensive, as it needs to convert data to appropriate
        datatypes. pickle saves the processed data that can efficiently
        reloaded.
        """
        df = self._load_csv(symbol)
        df.save(self._pklfile(symbol))
        return symbol

    def load(self, symbol):
        """
        load symbol dataframe from a pre saved file

        This loads the pre-processed data that was previously stored using
        pickle().
        """
        return read_pickle(self._pklfile(symbol))

    def loadData(self, symbols, field="adj_close", from_=None, to_=None):
        """
        Load data for symbols for given date range.

        Returns a DataFrame. Columns are indexed by symbols

        e.g:

        from_date = datetime.datetime.strptime("2012/1/1", "%Y/%M/%d")
        to_date = datetime.datetime.now()
        syms=["AAPL", "GOOG", "COG"]
        ds.loadData(syms, "close", from_date, to_date)

        # DataFrame
        <class 'pandas.core.frame.DataFrame'>
        DatetimeIndex: 248 entries, 2012-01-03 00:00:00 to 2012-12-24 00:00:00
        Data columns:
        AAPL    245  non-null values
        GOOG    245  non-null values
        COG     245  non-null values
        dtypes: float64(3)


        # df[:3]
                      AAPL    GOOG    COG
        2012-01-03  411.23  665.41  76.80
        2012-01-04  413.44  668.28  82.32
        2012-01-05  418.03  659.01  82.71

        """

        if from_ is None:
            from_ = self.date_from

        if to_ is None:
            to_ = self.date_to

        df = self._load_dataframe()[from_:to_]

        for s in symbols:
            df[s] = self.load(s)[field]

        return df

    def create_symbol_list(self):
        for exch in self.exchanges:
            exch.get_symbol_list()
            self.symbols.add(exch)
예제 #4
0
screen = pygame.display.set_mode((300, 300))  # creates the screen
background = pygame.Surface((300, 300))  # creates the background image
background = background.convert()
board = pygame.Surface((300, 300))
pygame.draw.rect(background, WHITE, [50, 50, 201, 201])
draw_lines()
screen.blit(background, (0, 0))  # blits background onto screen
pygame.display.flip()  # updates display
symbols = Symbols()
symbol = Symbol()


while not end:
    for event in pygame.event.get():  # deteremines which key is pressed
        if event.type == pygame.QUIT:  # if you click the quit :(
            end = True  # breaks the while loop
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            mx = mouse_pos[0]
            my = mouse_pos[1]
            if 50 <= mx <= 251 and 50 <= my <= 251:
                grid_pos = (get_pos(mx), get_pos(my))
                if occupied_check(symbols, grid_pos):
                    symbol.add(grid_pos)
                    draw_symbol(symbol)
                    symbols.add(symbol)
                    symbol.switch()
                # print("line check", symbols.line_check(symbol))
                # print(grid_pos)
예제 #5
0
class TestMarketDataDb(unittest.TestCase):
    def setUp(self):
        self.symbols = Symbols()

        conn = pymongo.MongoClient()
        db = conn.test_marketdata
        symbols = db.test_symbols

        self.symbols._symbols = symbols  # replaces real db with test one
        self.symbols.clean()
        self.symbols.add(['AAPL'])

    def test_single_hist_price(self):
        dt = datetime(2013, 7, 13)
        self.symbols.insert_historical_prices(
            'AAPL', [(dt, 100.0, 101.0, 99.0, 100.0, 100, 100.0)])
        res = self.symbols.select_historical_prices('AAPL', dt, dt)
        self.assertEqual(1, len(res))
        self.assertEqual(dt, res[0]['date'])
        self.assertEqual(100.0, res[0]['open'])
        self.assertEqual(101.0, res[0]['high'])
        self.assertEqual(99.0, res[0]['low'])
        self.assertEqual(100.0, res[0]['close'])
        self.assertEqual(100, res[0]['volume'])
        self.assertEqual(100.0, res[0]['adj_close'])

    def test_hist_price_for_undefined_date(self):
        dt = datetime(2013, 7, 13)
        res = self.symbols.select_historical_prices('AAPL', dt, dt)
        self.assertEqual([], res)

    def test_three_hist_price(self):
        d1 = datetime(2013, 7, 13)
        d2 = datetime(2013, 7, 14)
        d3 = datetime(2013, 7, 15)
        self.symbols.insert_historical_prices(
            'AAPL', [(d1, 100.0, 101.0, 99.0, 100.0, 100, 100.0)])
        self.symbols.insert_historical_prices(
            'AAPL', [(d3, 99.0, 100.0, 98.0, 99.0, 99, 99.0)])
        self.symbols.insert_historical_prices(
            'AAPL', [(d2, 101.0, 102.0, 100.0, 101.0, 101, 101.0)])
        res = self.symbols.select_historical_prices('AAPL', d1, d3)
        self.assertEqual(3, len(res))
        self.assertEqual(d1, res[0]['date'])
        self.assertEqual(100.0, res[0]['open'])
        self.assertEqual(d2, res[1]['date'])
        self.assertEqual(101.0, res[1]['open'])
        self.assertEqual(d3, res[2]['date'])
        self.assertEqual(99.0, res[2]['open'])

    def test_date_filtering(self):
        d1 = datetime(2013, 7, 13)
        d2 = datetime(2013, 7, 14)
        d3 = datetime(2013, 7, 15)
        d4 = datetime(2013, 7, 16)
        self.symbols.insert_historical_prices(
            'AAPL', [(d1, 100.0, 101.0, 99.0, 100.0, 100, 100.0)])
        self.symbols.insert_historical_prices(
            'AAPL', [(d2, 101.0, 102.0, 100.0, 101.0, 101, 101.0)])
        self.symbols.insert_historical_prices(
            'AAPL', [(d3, 99.0, 100.0, 98.0, 99.0, 99, 99.0)])
        self.symbols.insert_historical_prices(
            'AAPL', [(d4, 98.0, 99.0, 97.0, 98.0, 98, 98.0)])
        res = self.symbols.select_historical_prices('AAPL', d2, d3)
        self.assertEqual(2, len(res))
        self.assertEqual(d2, res[0]['date'])
        self.assertEqual(101.0, res[0]['open'])
        self.assertEqual(d3, res[1]['date'])
        self.assertEqual(99.0, res[1]['open'])

    def test_reinsert_historical_prices(self):
        d1 = datetime(2013, 7, 13)
        d2 = datetime(2013, 7, 14)
        d3 = datetime(2013, 7, 15)
        self.symbols.insert_historical_prices(
            'AAPL', [(d1, 100.0, 101.0, 99.0, 100.0, 100, 100.0),
                     (d2, 101.0, 102.0, 100.0, 101.0, 101, 101.0),
                     (d3, 99.0, 100.0, 98.0, 99.0, 99, 99.0)])
        res = self.symbols.select_historical_prices('AAPL', d1, d3)
        self.assertEqual(3, len(res))
        self.symbols.insert_historical_prices(
            'AAPL', [(d2, 101.0, 102.0, 100.0, 101.0, 101, 101.0)])
        res = self.symbols.select_historical_prices('AAPL', d1, d3)
        self.assertEqual(3, len(res))
        self.assertEqual(d1, res[0]['date'])
        self.assertEqual(100.0, res[0]['open'])
        self.assertEqual(d2, res[1]['date'])
        self.assertEqual(101.0, res[1]['open'])
        self.assertEqual(d3, res[2]['date'])
        self.assertEqual(99.0, res[2]['open'])

    def test_last_date(self):
        d = [
            datetime(2013, 7, 16),
            datetime(2013, 7, 14),
            datetime(2013, 7, 13),
            datetime(2013, 7, 17),
            datetime(2013, 7, 12),
            datetime(2013, 7, 15)
        ]
        for x in d:
            self.symbols.insert_historical_prices(
                'AAPL', [(x, 1.0, 1.0, 1.0, 1.0, 1, 1.0)])
        res = self.symbols.last_date('AAPL')
        self.assertEquals(datetime(2013, 7, 17), res)

    def test_last_date_when_no_data(self):
        res = self.symbols.last_date('AAPL')
        self.assertEquals(None, res)