Skip to content

Commit b342fef

Browse files
author
Shlomi Kushchi
authored
Merge pull request #191 from alpacahq/rc4
Fix exception handling, timestamp precisions
2 parents a735f24 + 8e884e3 commit b342fef

File tree

6 files changed

+36
-18
lines changed

6 files changed

+36
-18
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ the corresponding channel names. For example, if you subscribe to
205205
`trade_updates`, a WebSocket connects to Alpaca stream API, and
206206
if `AM.*` given to the `subscribe()` method, a WebSocket connection is
207207
established to Polygon's interface. If your account is enabled for
208-
Alpaca Data API streaming, adding `polyfeed/` prefix to `T.<symbol>`,
208+
Alpaca Data API streaming, adding `alpacadatav1/` prefix to `T.<symbol>`,
209209
`Q.<symbol>` and `AM.<symbol>` will also connect to the data stream
210210
interface.
211211

@@ -249,7 +249,7 @@ async def on_second_bars(conn, channel, bar):
249249
conn.run(['trade_updates', 'AM.*'])
250250

251251
# if Data API streaming is enabled
252-
# conn.run(['trade_updates', 'polyfeed/AM.SPY'])
252+
# conn.run(['trade_updates', 'alpacadatav1/AM.SPY'])
253253

254254
```
255255

alpaca_trade_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .rest import REST # noqa
22
from .stream2 import StreamConn # noqa
33

4-
__version__ = '0.47rc3'
4+
__version__ = '0.47rc4'

alpaca_trade_api/entity.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,20 @@ def __getattr__(self, key):
134134
if key in self._raw:
135135
val = self._raw[key]
136136
if key == 'timestamp':
137-
return pd.Timestamp(val, tz=NY, unit='ms')
137+
return pd.Timestamp(val, tz=NY, unit=self.unit)
138138
return val
139139
return getattr(super(), key)
140140

141141

142-
class Agg(_Timestamped, Entity):
142+
class _NanoTimestamped(_Timestamped):
143+
unit = 'ns'
144+
145+
146+
class _MilliTimestamped(_Timestamped):
147+
unit = 'ms'
148+
149+
150+
class Agg(_MilliTimestamped, Entity):
143151
pass
144152

145153

@@ -185,11 +193,11 @@ def df(self):
185193
return self._df
186194

187195

188-
class Trade(_Timestamped, Entity):
196+
class Trade(_NanoTimestamped, Entity):
189197
pass
190198

191199

192-
class Quote(_Timestamped, Entity):
200+
class Quote(_NanoTimestamped, Entity):
193201
pass
194202

195203

@@ -247,7 +255,7 @@ def df(self):
247255

248256

249257
trade_mapping = {
250-
"sym": "symbol",
258+
"T": "symbol",
251259
"c": "conditions",
252260
"x": "exchange",
253261
"p": "price",
@@ -268,7 +276,7 @@ def df(self):
268276
}
269277

270278
agg_mapping = {
271-
"sym": "symbol",
279+
"T": "symbol",
272280
"o": "open",
273281
"c": "close",
274282
"h": "high",

alpaca_trade_api/polygon/streamconn.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ async def _recv(self):
9898
await self.close()
9999
asyncio.ensure_future(self._ensure_ws())
100100

101+
async def consume(self):
102+
if self._consume_task:
103+
await self._consume_task
104+
101105
async def _consume_msg(self):
102106
async for data in self._stream:
103107
stream = data.get('ev')

alpaca_trade_api/stream2.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .common import get_base_url, get_data_url, get_credentials
77
from .entity import Account, Entity, trade_mapping, agg_mapping, quote_mapping
88
from . import polygon
9-
from .polygon.entity import Trade, Quote, Agg
9+
from .entity import Trade, Quote, Agg
1010
import logging
1111

1212

@@ -52,6 +52,10 @@ async def _connect(self):
5252

5353
self._consume_task = asyncio.ensure_future(self._consume_msg())
5454

55+
async def consume(self):
56+
if self._consume_task:
57+
await self._consume_task
58+
5559
async def _consume_msg(self):
5660
ws = self._ws
5761
try:
@@ -239,26 +243,28 @@ async def subscribe(self, channels):
239243
async def unsubscribe(self, channels):
240244
'''Handle unsubscribing from channels.'''
241245

242-
data_prefixes = ('Q.', 'T.', 'AM.')
243-
if self._data_stream == 'polygon':
244-
data_prefixes = ('Q.', 'T.', 'A.', 'AM.')
245-
246246
data_channels = [
247247
c for c in channels
248-
if c.startswith(data_prefixes)
248+
if c.startswith(self._data_prefixes)
249249
]
250250

251251
if data_channels:
252252
await self.data_ws.unsubscribe(data_channels)
253253

254+
async def consume(self):
255+
await asyncio.gather(
256+
self.trading_ws.consume(),
257+
self.data_ws.consume(),
258+
)
259+
254260
def run(self, initial_channels=[]):
255261
'''Run forever and block until exception is raised.
256262
initial_channels is the channels to start with.
257263
'''
258264
loop = self.loop
259265
try:
260266
loop.run_until_complete(self.subscribe(initial_channels))
261-
loop.run_forever()
267+
loop.run_until_complete(self.consume())
262268
except KeyboardInterrupt:
263269
logging.info("Exiting on Interrupt")
264270
finally:

tests/test_rest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def test_data(reqmock):
399399
"cond2": 16,
400400
"cond3": 0,
401401
"cond4": 0,
402-
"timestamp": 1518086464720
402+
"timestamp": 1518101436000900000
403403
}
404404
}
405405
'''
@@ -422,7 +422,7 @@ def test_data(reqmock):
422422
"bidprice": 159.45,
423423
"bidsize": 20,
424424
"bidexchange": 12,
425-
"timestamp": 1518086601843
425+
"timestamp": 1518101436000900000
426426
}
427427
}'''
428428
)

0 commit comments

Comments
 (0)