create a decorator the the re-try / push-backs from server instead of copying.
github-actions opened this issue · comments
create a decorator the the re-try / push-backs from server instead of copying.
LiuAlgoTrader/liualgotrader/trading/alpaca.py
Line 428 in 8b2c3ff
return self.to_order(o)
async def _post_request(self, url: str, payload: Dict) -> Dict:
response = requests.post(
url=url,
json=payload,
auth=HTTPBasicAuth(
self.alpaca_brokage_api_key, self.alpaca_brokage_api_secret
),
)
if response.status_code in (429, 504):
if "x-ratelimit-reset" in response.headers:
tlog(
f"ALPACA BROKERAGE rate-limit till {response.headers['x-ratelimit-reset']}"
)
asyncio.sleep(
int(time.time())
- int(response.headers["x-ratelimit-reset"])
)
tlog("ALPACA BROKERAGE going to retry")
else:
tlog(
f"ALPACA BROKERAGE push-back w/ {response.status_code} and no x-ratelimit-reset header"
)
asyncio.sleep(10.0)
return await self._post_request(url, payload)
if response.status_code in (200, 201, 204):
return response.json()
raise AssertionError(
f"HTTP ERROR {response.status_code} from ALPACA BROKERAGE API with error {response.text}"
)
async def _get_request(self, url: str) -> Dict:
response = requests.get(
url=url,
auth=HTTPBasicAuth(
self.alpaca_brokage_api_key, self.alpaca_brokage_api_secret
),
)
if response.status_code in (429, 504):
if "x-ratelimit-reset" in response.headers:
tlog(
f"ALPACA BROKERAGE rate-limit till {response.headers['x-ratelimit-reset']}"
)
asyncio.sleep(
int(time.time())
- int(response.headers["x-ratelimit-reset"])
)
tlog("ALPACA BROKERAGE going to retry")
else:
tlog(
f"ALPACA BROKERAGE push-back w/ {response.status_code} and no x-ratelimit-reset header"
)
asyncio.sleep(10.0)
return await self._get_request(url)
if response.status_code in (200, 201, 204):
return response.json()
raise AssertionError(
f"HTTP ERROR {response.status_code} from ALPACA BROKERAGE API with error {response.text}"
)
async def _delete_request(self, url: str) -> int:
response = requests.delete(
url=url,
auth=HTTPBasicAuth(
self.alpaca_brokage_api_key, self.alpaca_brokage_api_secret
),
)
# TODO: create a decorator the the re-try / push-backs from server instead of copying.
if response.status_code in (429, 504):
if "x-ratelimit-reset" in response.headers:
tlog(
f"ALPACA BROKERAGE rate-limit till {response.headers['x-ratelimit-reset']}"
)
asyncio.sleep(
int(time.time())
- int(response.headers["x-ratelimit-reset"])
)
tlog("ALPACA BROKERAGE going to retry")
else:
tlog(
f"ALPACA BROKERAGE push-back w/ {response.status_code} and no x-ratelimit-reset header"
)
asyncio.sleep(10.0)
return await self._delete_request(url)
return response.status_code
async def _order_on_behalf(
self,
symbol: str,
qty: float,
side: str,
order_type: str,
time_in_force: str,
limit_price: str = None,
stop_price: str = None,
client_order_id: str = None,
extended_hours: bool = None,
order_class: str = None,
take_profit: dict = None,
stop_loss: dict = None,
trail_price: str = None,
trail_percent: str = None,
on_behalf_of: str = None,
) -> Order:
if not self.alpaca_brokage_api_baseurl:
raise AssertionError(
"order_on_behalf can't be called, if brokerage configs incomplete"
)
endpoint: str = f"/v1/trading/accounts/{on_behalf_of}/orders"
url: str = self.alpaca_brokage_api_baseurl + endpoint
payload = {
"symbol": symbol.upper(),
"qty": qty,
"side": side,
"type": order_type,
}
if limit_price:
payload["limit_price"] = limit_price
if time_in_force:
payload["time_in_force"] = time_in_force
json_response: Dict = await self._post_request(
url=url, payload=payload
)
tlog(f"ALPACA BROKERAGE RESPONSE: {json_response}")
return self._json_to_order(json_response, on_behalf_of)
async def submit_order(
self,
symbol: str,
qty: float,
side: str,
order_type: str,
time_in_force: str = "day",
limit_price: str = None,
stop_price: str = None,
client_order_id: str = None,
extended_hours: bool = None,
order_class: str = None,
take_profit: dict = None,
stop_loss: dict = None,
trail_price: str = None,
trail_percent: str = None,
on_behalf_of: str = None,
) -> Order:
if on_behalf_of:
return await self._order_on_behalf(
symbol,
qty,
side,
order_type,
time_in_force,
limit_price,
stop_price,
client_order_id,
extended_hours,
order_class,
take_profit,
stop_loss,
trail_price,
trail_percent,
on_behalf_of,
)
else:
return await self._personal_submit(
symbol,
qty,
side,
order_type,
time_in_force,
limit_price,
stop_price,
client_order_id,
extended_hours,
order_class,
take_profit,
stop_loss,
trail_price,
trail_percent,
on_behalf_of,
)
@classmethod
def _trade_from_dict(cls, trade_dict: Entity) -> Optional[Trade]:
if trade_dict.event == "new":
return None
return Trade(
order_id=trade_dict.order["id"],
symbol=trade_dict.order["symbol"].lower(),
28086bc3f6b502d71d763e50eb2ac34bd0a61bfa
Stale issue message