erovira / transa-script

Shell script to compute the Itaú/BROU mean USD/UYU exchange rate
6 stars 2 forks source link

Add true inter-bank exchange from BCU #16

Closed sebastian-correa closed 4 months ago

sebastian-correa commented 5 months ago

Summary

The real inter-bank exchange is given by BCU (Banco Central del Uruguay) in this page.

I think it's probably the fairest exchange rate there is, so adding it to transa-script might be useful.

I can help with implementation if we decide we want to move forwards.

Tech details

When looking at how it works, it does a POST to https://www.bcu.gub.uy/_layouts/15/BCU.Cotizaciones/handler/CotizacionesHandler.ashx?op=getcotizaciones.

Sample body
```json { "KeyValuePairs": { "Monedas": [ { "Val": "2225", "Text": "DLS. USA BILLETE" } ], "FechaDesde": "01/04/2024", "FechaHasta": "09/04/2024", "Grupo": "2" } } ``` For the purposes of `transa-script` we should only care about this currency (USD). The `FechaDesde` and `FechaHasta` give the range from which we want rates to be picked up. In our case, we'd set both to "today" (probably, see caveats below).
Sample response
```json { "operation": "getcotizaciones", "cotizacionesoutlist": { "Moneda": null, "RespuestaStatus": { "status": 1, "codigoError": 0, "mensaje": "" }, "Cotizaciones": [ { "Fecha": "/Date(1711940400000)/", "Moneda": 2225, "Nombre": "DLS. USA BILLETE", "CodigoISO": "DLS.", "Emisor": "ESTADOS UNIDOS", "TCC": 37.8570, "TCV": 37.8570, "ArbAct": 1.000000, "FormaArbitrar": 0 }, { "Fecha": "/Date(1712026800000)/", "Moneda": 2225, "Nombre": "DLS. USA BILLETE", "CodigoISO": "DLS.", "Emisor": "ESTADOS UNIDOS", "TCC": 38.1220, "TCV": 38.1220, "ArbAct": 1.000000, "FormaArbitrar": 0 }, { "Fecha": "/Date(1712113200000)/", "Moneda": 2225, "Nombre": "DLS. USA BILLETE", "CodigoISO": "DLS.", "Emisor": "ESTADOS UNIDOS", "TCC": 38.2470, "TCV": 38.2470, "ArbAct": 1.000000, "FormaArbitrar": 0 }, { "Fecha": "/Date(1712199600000)/", "Moneda": 2225, "Nombre": "DLS. USA BILLETE", "CodigoISO": "DLS.", "Emisor": "ESTADOS UNIDOS", "TCC": 38.2400, "TCV": 38.2400, "ArbAct": 1.000000, "FormaArbitrar": 0 }, { "Fecha": "/Date(1712286000000)/", "Moneda": 2225, "Nombre": "DLS. USA BILLETE", "CodigoISO": "DLS.", "Emisor": "ESTADOS UNIDOS", "TCC": 38.5210, "TCV": 38.5210, "ArbAct": 1.000000, "FormaArbitrar": 0 } ] } } ``` As seen, we could average `TCC` and `TCV` (which are equal) to get the inter-bank exchange rate.
Sample headers
I am not sure if they check anything, but these are the headers I used: ```text Accept: application/json, text/javascript, */*; q=0.01 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.5 ```

Caveats

BCU only publishes exchange rates on working days, and at some (unknown to me but probably predictable) time. Therefore, we need to solve the cases where a user asks for a transa and there's no data for "today". We could solve this by requesting the data from the past week/month and keeping the last (by date) entry, as the exchange rate in a non-working day should be that of the last working day (ITAU does the same but they publish the same data daily).

erovira commented 5 months ago

Thanks for opening this issue!

I think adding the BCU exchange is a great idea and the proposed implementation seems very feasible.

I can help with implementation if we decide we want to move forwards

By all means!

Some comments on implementation personal preferences. Although I don't think I've stated it anywhere, one of the goals I had in mind for this script was for it to be easily installable/usable. I.e. I would try to implement BCU either: a. Using builtin utils (even if it takes many pipes or lines of code) b. Getting the response in XML and using xmllint, which is already being used in the script. I'd restrain from adding extra dependencies, such as e.g. jq, to keep the script lean.

erovira commented 5 months ago

Hey @sebastian-correa , as discussed offline, I'm ok with a solution involving jq. Main reason being that this would only be required by the special case of bcu and would not impact the default itau behavior.