ahmedsakr / wstrade-api

API Wrapper for Wealthsimple Trade

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Identifying securities by their symbol alone can lead to ambiguous results

bufutda opened this issue · comments

A given symbol can be listed in multiple exchanges. getSecurity simply returns the first security with a given symbol, but not necesarrily the security you want.

If the security is listed on multiple exchanges then it's not a problem since those get combined in the results. However, if two exchanges have different securities with the same symbol, you can get an unexpected result.

Furthermore, since the underlying endpoint is just for searching, you may get a security with an entirely different symbol than what you searched for as the first result.

For example, querying for PSI gives

  • NYSE:PSI, Invesco Dynamic Semiconductors ETF
  • TSE:PSI, Pason Systems Inc.

NYSE:PSI is always returned since it is the first result.

Since this endpoint is used many places in the wrapper for example when trying to place a trade, this is a potentially large problem.


I propose the following solution:
getSecurity(token, exchange, symbol) queries for the symbol and only returns the result if the symbol and exchange exactly match.
getSecurity(token, symbol) queries for the symbol and searches the results for securities with exactly the same symbol. If there is more than one candidate, reject the promise
getSecurity(token, symbol, id) queries for the symbol and returns a security if it has the same internal ID. Unfortunately I don't know of any way to get a security directly from it's ID so this would be nice to have

Thank you for noticing this very important issue. I have taken a look at your proposal and your pull request.

Like you've mentioned, getSecurity is used in other calls (namely the placeOrder ones) to get the security id. I think this issue is severe enough that along with this amendment to getSecurity, we should propagate the ability to choose exchange on all the placing order API calls. However, those API calls are already loaded with necessary parameters (>=4), and adding a few more will start to make those API calls quite bulky.

With this consideration in mind, i was wondering if you would be accepting of an alternative solution where the ticker parameter is modified to allow for the postfixing of the exchange symbol. Using your example, the getSecurity ticker parameter can be specified as 'PSI.NYSE' to retrieve PSI from NYSE, or 'PSI.TSE' for the TSX version. An example is shown below:

getSecurity(data.tokens, 'PSI.TSE')
    .then(data => console.log("I got the TSX version!");

getSecurity(data.tokens, 'PSI.NYSE')
    .then(data => console.log("I got the NYSE version!");

getSecurity(data.tokens, 'PSI')
    .catch(error=> console.log("Oh no, i didn't specify exchange, so my call is being rejected for safety reasons"));

To facilitate this change, the getSecurity implementation would have to check if that exchange postfix exists in the ticker, and handle it accordingly.

That sounds great. There is a handy list of exchange suffixes here: https://help.yahoo.com/kb/SLN2310.html

While using a standard exchange suffix would be nice (PSI.TO in this case), I think it's better to use the WealthSimple exchange name as you have listed because it will reduce the amount of mapping we need to do. To reduce user confusion it might be a better to not present the suffix in this way though as at a first glance it looks like the standard suffix notation. I propose using a colon instead: PSI:TSE

It would still be very nice to get a security by internal ID. For example, if you are starting from an order response, exchange information is not included. How would a solution to that fit into this scheme?

I've updated the pull request with a solution that accepts exchange suffixing as well as exchange and id filtering. ticker may now be a string or an object with the new parameters in it.

hey @bufutda, sorry for being MIA. I started a new job recently, so i've been really busy with setup and all.

I am glad you agreed with my suggested amendment to your proposal. Thanks for updating your PR. I will take a look at it now.

Also, if you would still like to add an optional 3rd parameter to getSecurity for internal id: go for it! I think it could be useful for some people.

Edit: My bad, you did support the internal id. Ignore my last comment.