Skip to content

Commit

Permalink
Merge pull request #49 from alpacahq/getOrdersFix
Browse files Browse the repository at this point in the history
older orders should no longer be ignored
  • Loading branch information
ttt733 authored Nov 13, 2018
2 parents 6461b92 + 5824e83 commit d45611d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
20 changes: 15 additions & 5 deletions pylivetrader/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,19 @@ def get_open_orders(self, asset=None):
return self.get_all_orders(asset=asset, status='open')

@api_method
def get_all_orders(self, asset=None, before=None, status='all'):
def get_recent_orders(self, days_back=2):
'''
Returns all orders from the past n days.
'''
return self.get_all_orders(days_back=days_back)

@api_method
def get_all_orders(
self,
asset=None,
before=None,
status='all',
days_back=None):
'''
If asset is unspecified or None, returns a dictionary keyed by
asset ID. The dictionary contains a list of orders for each ID,
Expand All @@ -622,7 +634,7 @@ def get_all_orders(self, asset=None, before=None, status='all'):
before will not be returned. If provided, only orders of type
status ('closed' or 'open') will be returned.
'''
orders = self._backend.all_orders(before, status)
orders = self._backend.all_orders(before, status, days_back)

omap = {}
orders = sorted([
Expand All @@ -640,9 +652,7 @@ def get_all_orders(self, asset=None, before=None, status='all'):

@api_method
def get_order(self, order_id):
orders = self._backend.orders
if order_id in orders:
return orders[order_id].to_api_obj()
return self._backend.get_order(order_id).to_api_obj()

@api_method
def cancel_order(self, order_param):
Expand Down
47 changes: 36 additions & 11 deletions pylivetrader/backend/alpaca.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,20 +287,45 @@ def orders(self):
for o in self._api.list_orders('all')
}

def all_orders(self, before=None, status='all'):
until = pd.Timestamp.utcnow().isoformat() if before is None else before
def get_order(self, zp_order_id):
return self._order2zp(
self._api.get_order_by_client_order_id(zp_order_id)
)

def all_orders(self, before=None, status='all', days_back=None):
# Get all orders submitted days_back days before `before` or now.
now = pd.Timestamp.utcnow()
start = now.isoformat() if before is None else before.isoformat()

# A session label refers to the market date that an order submitted
# at a given minute would be executed on. We'll need to keep track of
# this if the function is bounded by days_back.
start_session_label = self._cal.minute_to_session_label(start)
reached_end_date = False

all_orders = {}
batch_size = 500
orders = self._api.list_orders(status, batch_size, until=until)
while len(orders) > 0:
batch_orders = {
o.client_order_id: self._order2zp(o)
for o in orders
}
# get the timestamp of the earliest order in the batch
until = pd.Timestamp(orders[-1].submitted_at).isoformat()

orders = self._api.list_orders(status, batch_size, until=start)
while len(orders) > 0 and not reached_end_date:
batch_orders = {}
for order in orders:
if days_back is not None:
# Verify that the order is not too old.
# `session_distance()` ignores holidays and weekends.
days_since_order = self._cal.session_distance(
self._cal.minute_to_session_label(order.submitted_at),
start_session_label
)
if days_since_order > days_back:
reached_end_date = True
break
batch_orders[order.client_order_id] = self._order2zp(order)
all_orders.update(batch_orders)
orders = self._api.list_orders(status, batch_size, until=until)
if not reached_end_date:
# Get the timestamp of the earliest order in the batch.
until = pd.Timestamp(orders[-1].submitted_at).isoformat()
orders = self._api.list_orders(status, batch_size, until=until)
return all_orders

def cancel_order(self, zp_order_id):
Expand Down

0 comments on commit d45611d

Please sign in to comment.