borgoat / ex_twelve_data

Elixir client for Twelve Data
MIT License
1 stars 2 forks source link

Contributing other endpoints #2

Open nathany-copia opened 9 months ago

nathany-copia commented 9 months ago

We are currently using Twelve Data in production but have yet to split out a separate open source library. We aren't using the Websockets API right now, but other endpoints, especially the time series endpoint.

For these API client libraries, our typical approach is to use Tesla for the client and write custom functions for each API. We like to translate the JSON into Structs with common Elixir formats, such as Date, DateTime, Decimal, Money and atoms for enumerations. We also like to translate HTTP status codes into error tuples so that HTTP and the client library used (Tesla) are implementation details that aren't exposed to the caller.

Does this align with what you'd like to see? If not, what changes would you make?

Will you have time to dedicate to reviewing contributions, and releasing the hex packages?

borgoat commented 7 months ago

Hey @nathany-copia - absolutely I'd be happy to review these contributions! Currently, I have been releasing to Hex manually, since I was the only one merging things in. But I wanted to move it to an Action workflow, and I guess now it's a good time to do that 🙂

I don't have any strong opinion on which HTTP client to use: the idea of this library was just like you say, to try and hide away some of Twelve Data quirks, and expose it through idiomatic Elixir. I didn't even think too much about the structure back when I started to be honest, so if you have some ideas there on how we could move things around to squeeze in the HTTP API, that'd great!

Similarly, if you have a proposal for managing structs definitions: the Twelve Data docs are sometimes confusing, and some things we only learned through trial and error. It'd be nice if structs acted as documentation, too. (In our company, this is the approach we take with our internal TypeScript client for Twelve Data, were we use typing and template literals to try to avoid errors...) A few structs are shared between the HTTP and WS API, so they should be at the top level. Especially as Elixir now moves towards gradual typing maybe I'm sure we could do something better than what I did. Right now things are really

BTW I'm not an Elixir expert, so any suggestion is really appreciated!

nathany-copia commented 7 months ago

Hi @borgoat. Nice to meet you! And thank you for the detailed reply.

Regarding quirks, I have noted one small example:

Rename fields if the existing names to make more sense: e.g. https://twelvedata.com/docs#end-of-day-price returns "datetime": "2021-09-16", which should be translated to date: ~D[2021-09-16]

I'm sure there are others.

I think having multiple companies/people using the client library will definitely help to correct and/or document common quirks, while avoiding going too far into company-specific logic in the client library.

Based on timelines handed down to me, I think we're a month or two away from being able to dedicate one or two people to this effort.

Are you using the Elixir client at your company or is it a side project, with the TypeScript client used in production?

borgoat commented 7 months ago

I have another example that has to do with date times which I found odd (and gave us a lot of headaches when designing previous day and intraday quote prices spark lines), which is timezones sometimes coming in a separate exchange_timezone field, sometimes not being there at all. We ended up having a map from MIC codes to timezones embedded both in our frontend and backend (that'd be our TypeScript client). This could be another thing that we could improve by correctly using the DateTime struct in Elixir. In TS we went for Luxon for this.

When it comes to prices, another quirk was the scaling that is sometimes applied to some forex rates (Japanese Yen and Swedish Krona comes to mind, but I remember there are others...), and is not noted anywhere. Some prices are returned as strings, sometimes as JSON numbers. Another idea here would have been to use Elixir Money^1. We use Dinero.js on the TS side.

At yeekatee we also use this Elixir client in prod, as part of a larger Phoenix-based service (API only, we basically only use Phoenix Channels), which we use for all our real time messages (we have a chat and other social network features, together with the market data).

nathany-copia commented 6 months ago

We've also run into the scaling issue with Yen. It would be great to handle that in this library and use Elixir Money.