How to Diagnose Bot vs Alpaca Holdings Discrepancies


python 3.8.11


I am looking for ideas on how to diagnose a problem with my trading bot. I am trying to diagnose why my bot and Alpaca have differences in the number of shares of AMD I own. (Alpaca thinks I have 4 shares . My bot thinks I have 1 or 0 shares - the number fluctuates throughout each day depending on when the bot buys and sells)

I am doing paper trading. I have some code (see below), it does not thrown an error, returns something, but does not give me the needed diagnostic info.

Can there be a bug in my Bot? Sure. But I suspect that what’s happening is that the bot will issue a buy or a sell order and then for some reason that order does not happen. How can I detect or rule out such a case?

More importantly, how can detect that a buy or sell happened going back in history, i.e. since I first got my keys - about 1 month ago.

Is there a way to see the global history of all orders I ever made, regardless of whether they succeeded or not?

What other kind of approaches can I use to figure this out?

I’ve tried to find a way to look up what happened to any given order using the ‘id’ field or the ‘client_order_id’ but have not succeeded. Any thoughts? Is there such a way?

Here (immediately below this paragraph) are two concrete pieces of code that seem to do something, but it doesn’t look like they do what I want. The call to check_orders() returns the empty list. The call to portfolio_history() returns a json containing fields like ‘timestamp’, ‘equity’, ‘profit_loss’ such that the value of each field/key is a list of about 50 numbers. Doesn’t seem to provide the kinds of clues I am looking for.

mport requests
import json

API_KEY = "i'dtellyoubut..."
SECRET_KEY = "ifitoldyouiwouldhavetokillyou"

ACCOUNT_URL = "{}/v2/account".format(BASE_URL)
ORDERS_URL = "{}/v2/orders".format(BASE_URL)
HISTORY_URL =  "{}/v2/account/portfolio/history".format(BASE_URL)

#from Analysis.MyAlpaca.simple_buy_or_sell import HEADERS                                                                   

def check_orders():
        data = {
                "symbol" : "AMD"
        r = requests.get(ORDERS_URL, json=data, headers = HEADERS)


def portfolio_history():
	data = {
                "period" : "A",
        r = requests.get(HISTORY_URL, json=data, headers = HEADERS)
	#r = requests.get(HISTORY_URL, headers = HEADERS)                                                                   


One partial approach I am thinking of doing is have my bot frequently (maybe 1x per minute) check what Alpaca thinks my stock positions are and why my bot thinks my positions are and if it detects a discrepancy send me a text message alert. Then I can rummage around and see if I can figure out what is going wrong. But what rummaging around would I do? I mean I already have logs. There are a 15 exceptions thrown over the course of 30 days. If an exception in a log shows up when the next discrepancy is detected, maybe that would be a clue to what is breaking?

Something I read somewhere seemed to suggest I use a websocket that can receive a continual stream of updates regarding an order. I dunno nuthin 'bout websockets but maybe that is just what I have to figure out – looks scary though!

For the last 30 days it’s been running fine doing paper trading of about 20 buys and sells per day.

It only ever buys one share of any given stock at a time, and if it owns 1 share, then it will not buy another share.

The particular problem, is that I’ve recently noticed that Alpaca believes I own 4 shares of AMD but my bot believes it owns only 1 or 0 shares (the number fluctuates throughout the day as it buys and sells).

Finally, I’ve looked at the json returned from my calls to buy and
sell of AMD. Everything seems fine.

More precisely: I’m not sure how to find an anomalous event (any
ideas?) but I have verified that for each buy and sell, the json returned from Alpaca always had the following properties:

‘status’: ‘accepted’
‘canceled at’: ‘None’
‘failed_at’: None

To me this suggests that at least when the order first was transmitted there were no problems. But maybe there are other things to look for in said json.

One more thing…For historical reasons, I get prices from yfinance which uses Yahoo, not Alpaca. I just use Alpaca to act - to buy or sell. Here are the all the cases that “error” or “Error” occurs in my logs. Maybe one of these exceptions is a clue to why the discrepancies are occurring?

quant-log.2021-10-04.txt:    raise JSONDecodeError("Expecting value", s, err.value) from None
quant-log.2021-10-04.txt:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
quant-log.2021-10-14.txt:    raise JSONDecodeError("Expecting value", s, err.value) from None
quant-log.2021-10-14.txt:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
quant-log.2021-10-19.txt:ConnectionResetError: [Errno 104] Connection reset by peer
quant-sma-log.2021-10-19.txt:    raise six.reraise(type(error), error, _stacktrace)
quant-log.2021-10-19.txt:urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by\
quant-sma-log.2021-10-19.txt:    raise ConnectionError(err, request=request)
quant-sma-log.2021-10-19.txt:requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset\
 by peer'))
quant-sma-log.2021-11-04.txt:    raise JSONDecodeError("Expecting value", s, err.value) from None
quant-sma-log.2021-11-04.txt:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)