Closed brycelund closed 2 years ago
Adding a sleep(1) to wait for order to fill between orders works. Is there a way to specify a trailing stop on fill to remove the need to send an order, wait for fill, then send another order?
I added time.sleep(1.0) between my initial order and the submit order for the trailing stop as recommended by @brycelund and I'm still getting the following error message. Does the forbidden URL have anything to do with this? My long positions are going through on the paper trade api endpoint without issue and I'm able to submit trailing stop orders through Postman. I'm using Python 3.9.4.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/alpaca_trade_api/rest.py", line 208, in _one_request
resp.raise_for_status()
File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 953, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://paper-api.alpaca.markets/v2/orders
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/www/wedge_screener/wedge_screener.py", line 145, in <module>
main()
File "/var/www/wedge_screener/wedge_screener.py", line 137, in main
wedge_trader(final_selections, 10)
File "/var/www/wedge_screener/wedge_trader.py", line 31, in wedge_trader
api.submit_order(
File "/usr/local/lib/python3.9/dist-packages/alpaca_trade_api/rest.py", line 395, in submit_order
resp = self.post('/orders', params)
File "/usr/local/lib/python3.9/dist-packages/alpaca_trade_api/rest.py", line 227, in post
return self._request('POST', path, data)
File "/usr/local/lib/python3.9/dist-packages/alpaca_trade_api/rest.py", line 187, in _request
return self._one_request(method, url, opts, retry)
File "/usr/local/lib/python3.9/dist-packages/alpaca_trade_api/rest.py", line 216, in _one_request
raise APIError(error, http_error)
alpaca_trade_api.rest.APIError: cannot open a short sell while a long buy order is open
Here's the successful Postman POST in python:
import requests
url = "https://paper-api.alpaca.markets/v2/orders"
payload = "{\n \"symbol\": \"BNTX\",\n \"qty\": 10,\n \"side\": \"sell\",\n \"type\": \"trailing_stop\",\n \"trail_price\": 3.00,\n \"time_in_force\": \"gtc\"\n}"
headers = {
'APCA-API-KEY-ID': 'my_key_id',
'APCA-API-SECRET-KEY': 'my_secret_key',
'Content-Type': 'text/plain'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
And here's what I have in my code using the alpaca api:
import time
from alpaca_trade_api.rest import REST
import alpaca_trade_api as tradeapi
def wedge_trader(dataframe, quantity):
key_id = 'my_key'
secret_key = 'my_secret'
base_url = 'https://paper-api.alpaca.markets'
api = tradeapi.REST(key_id=key_id, secret_key=secret_key, base_url=base_url)
account = api.get_account()
symbols = [s for s in dataframe['ticker']] #get the symbols from the dataframe
atrs = [a for a in dataframe['atr']] #get the average true ranges from the dataframe
if account.status == 'ACTIVE':
for s, a in zip(symbols,atrs):
api.submit_order(
symbol=s,
side='buy',
type='market',
qty=quantity,
time_in_force='gtc'
)
time.sleep(1)
api.submit_order(
symbol=s,
qty=quantity,
side='sell',
type='trailing_stop',
trail_price=a, # stop price will be hwm - average true range$
time_in_force='gtc'
)
I found the error above. My code was attempting to place orders at market close and in doing so, was placing the long position, which wasn't being filled, at the same time as the short order for the trailing stop. I updated my code to call 1/2 hour before market close and now the trailing stops are going through without problems. In short, the long position has to be filled before the trailing stop can be entered. This is why adding the time.sleep(1.0) in @brycelund code worked.
I don't think this is an issue that needs to be addressed withe the Alpaca API code and instead is something we need to handle for when writing the logic for our applications.
I think this issue can be closed. Here's my response when running the trailing stop with the market still open:
>>> api.submit_order(symbol='MRNA', qty=10, side='sell', type='trailing_stop',trail_price=7.00,time_in_force='gtc')
Order({ 'asset_class': 'us_equity',
'asset_id': 'b02df0cc-0a0a-4ecb-8e92-201b1044ea21',
'canceled_at': None,
'client_order_id': '7a735f43-c586-4eee-a11f-2f9711df6fe3',
'created_at': '2021-11-18T14:30:37.444586527Z',
'expired_at': None,
'extended_hours': False,
'failed_at': None,
'filled_at': None,
'filled_avg_price': None,
'filled_qty': '0',
'hwm': '244.67',
'id': 'bcaddbc2-329b-4c5d-ab6b-ee40749aa7b5',
'legs': None,
'limit_price': None,
'notional': None,
'order_class': '',
'order_type': 'trailing_stop',
'qty': '10',
'replaced_at': None,
'replaced_by': None,
'replaces': None,
'side': 'sell',
'status': 'new',
'stop_price': '237.67',
'submitted_at': '2021-11-18T14:30:37.443143037Z',
'symbol': 'MRNA',
'time_in_force': 'gtc',
'trail_percent': None,
'trail_price': '7',
'type': 'trailing_stop',
'updated_at': '2021-11-18T14:30:37.444586527Z'})
>>>
@FergusClare. In your sell order above with hwm=244.67 and trail_price=7.00 shouldn't the stop_price=244.67+7 instead of stop_price=237.67. I'm confused as to why Alpaca puts stop_price below hmw in sell orders and above hmw in buy orders. This doesn't make sense given the explanation and diagram in their blog post https://alpaca.markets/blog/trailing-stop/
Following the Submit Trailing Stop Orders section from here I get the error alpaca_trade_api.rest.APIError: cannot open a short sell while a long buy order is open.