[PHP] Float met een specifieke precision zonder nullen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Voor een trading bot die communiceert met de Bitvavo API loop ik tegen een probleem aan, waarbij Bitvavo mijn orders niet accepteert vanwege een probleem met het amount bedrag.

Ze verwachten een float met een precision van X (bijvoorbeeld 5). Na eerder contact met hun support kreeg ik het volgende terug:
"Het ligt hier aan de precision. Als u een amount van 0.00014152 (5 getallen, de 0 uitgezonderd) zou gebruiken zou dit wel moeten werken."

Mijn laatste order had een amount van 8.16246765, en .. inderdaad, zoals verwacht gaat dit dus fout en krijg ik een fout terug vanuit Bitvavo.

Mijn vraag: Hoe zorg ik dat de getallen via PHP juist afgerond worden? De standaard functies (round() of number_format() werken niet, want die houden bij de precision geen rekening met 0-en.

Nog een stukje uit de Bitvavo API documentatie (https://docs.bitvavo.com/#tag/General/paths/~1markets/get):
pricePrecision (string)
Price precision determines how many significant digits are allowed. The rationale behind this is that for higher amounts, smaller price increments are less relevant. Examples of valid prices for precision 5 are: 100010, 11313, 7500.10, 7500.20, 500.12, 0.0012345. Examples of precision 6 are: 11313.1, 7500.11, 7500.25, 500.123, 0.00123456.

Hoe los ik dit dus op een nette manier op. Ik kan hele omslachtige manieren bedenken (omzetten naar string, punten verwijderen, alle leading zeros verwijderen en dan alles na string lengte volgens de opgegeven precision verwijderen zodat je bijvoorbeeld 5 getallen overhoudt. En dan weer de punt op de juiste(?) plek terugzetten, o.i.d.), maar volgens mij moeten er makkelijkere manieren of standaard methodes te bedenken zijn om dit robuust aan te pakken?

Iemand ervaring hiermee?

Beste antwoord (via Wolf3D op 31-05-2022 15:35)


  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Wolf3D schreef op dinsdag 31 mei 2022 @ 14:19:
[...]

Thanks!! Ik heb er even wat getallen doorheen laten lopen, en het gaat redelijk goed. Alleen bij getallen boven de 0 houdt hij vast aan de 5 getallen achter de komma (met $digits = 5).
Ah, ik dacht dat dat de bedoeling was. De voorbeelden zijn niet uitputtend. Moet 1234567.89 afgerond worden naar 1234600 of naar 1234567?

Ik denk dat als je de functie versimpelt naar
code:
1
2
3
4
function roundsignficant($number,$digits)
{
    return round($number,$digits-floor(log10($number)+1));
}

dat het dan al behoorlijk goed werkt (niet getest trouwens). En als je ook negatieve getallen aan moet kunnen, dan moet je die even apart testen. Misschien moet je hier en daar een minteken toevoegen/weghalen om het goed te laten werken.

Anyway, ik denk dat je er zo wel uitkomt. Mocht je je eerste miljoen verdiend hebben, dan hoor ik dat graag.

When life gives you lemons, start a battery factory

Alle reacties


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Kijk eens naar BCMath ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
Bedankt voor je antwoord. Die kende ik nog niet! Helaas .. weet ik niet zo goed wat ik ermee moet.
Ik heb de function lijst doorlopen (https://www.php.net/manual/en/ref.bc.php) maar, heb eigenlijk nog steeds geen idee hoe deze me kunnen helpen bij mijn vraagstuk.

Ik denk dat ik nog een extra duwtje in de juiste richting nodig heb ... :-)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Nee, sorry, mijn suggestie klopt(e) niet. Ik was klaarblijkelijk nog niet helemaal wakker :P

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Je wilt afronden op significante digits. De eerste link die ik vond (stackoverflow natuurlijk) geeft hopelijk een handvat:
https://stackoverflow.com...significant-digits-in-php

Wat daar gebeurt, is dat je afronding (op 5 decimalen bijvoorbeeld) gecorrigeerd wordt voor het aantal voorloopnullen (de log10 in de link).

[ Voor 25% gewijzigd door KabouterSuper op 31-05-2022 13:10 ]

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
KabouterSuper schreef op dinsdag 31 mei 2022 @ 13:09:
Je wilt afronden op significante digits. De eerste link die ik vond (stackoverflow natuurlijk) geeft hopelijk een handvat:
https://stackoverflow.com...significant-digits-in-php

Wat daar gebeurt, is dat je afronding (op 5 decimalen bijvoorbeeld) gecorrigeerd wordt voor het aantal voorloopnullen (de log10 in de link).
Significante digits! Nooit van gehoord, je moet maar net weten waar je op moet zoeken.... :-)
Dat ziet er in ieder geval veelbelovend uit! Ik ga het uitproberen

Acties:
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Wolf3D schreef op dinsdag 31 mei 2022 @ 13:19:
[...]


Significante digits! Nooit van gehoord, je moet maar net weten waar je op moet zoeken.... :-)
Dat ziet er in ieder geval veelbelovend uit! Ik ga het uitproberen
Het zal zoiets worden:
code:
1
2
3
4
function roundsignficant($number,$digits)
{
    return round($number,$digits-floor(min(0,log10($number)+1)));
}

Wel graag goed testen voordat je een miljoen verliest met een trading bot.

When life gives you lemons, start a battery factory


Acties:
  • +2 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wolf3D schreef op dinsdag 31 mei 2022 @ 13:19:
Significante digits! Nooit van gehoord, je moet maar net weten waar je op moet zoeken....
Wolf3D schreef op dinsdag 31 mei 2022 @ 12:33:
Price precision determines how many significant digits are allowed.
8)7 :+

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
KabouterSuper schreef op dinsdag 31 mei 2022 @ 13:23:
[...]

Het zal zoiets worden:
code:
1
2
3
4
function roundsignficant($number,$digits)
{
    return round($number,$digits-floor(min(0,log10($number)+1)));
}

Wel graag goed testen voordat je een miljoen verliest met een trading bot.
Ik wou dat ik een miljoen kon verliezen! :P
Thanks!! Ik heb er even wat getallen doorheen laten lopen, en het gaat redelijk goed. Alleen bij getallen boven de 0 houdt hij vast aan de 5 getallen achter de komma (met $digits = 5). Als ik dan lees bij Bitvavo "Examples of valid prices for precision 5 are: 100010, 11313, 7500.10, 7500.20, 500.12, 0.0012345. Examples of precision 6 are: 11313.1, 7500.11, 7500.25, 500.123, 0.00123456"
Dan zou 100010.11111 dus 100010 terug moeten geven, maar nu is dat 100010.11111.

Ik heb daarom wat code toegevoegd:

code:
1
2
3
4
5
6
7
8
9
10
11
function roundsignficant($number, $digits) {
  $length = strlen(round($number));

  if ($length > 1) {
    $decimals = max(0, $digits - strlen(round($number, 0)));
    return round($number, $decimals);
  }
  else {
    return round($number,$digits - floor(min(0,log10($number) + 1)));
  }
}


Een lijstje met getallen geeft via roundsignficant($number, 5):
code:
1
2
3
4
5
6
7
8
9
10
11
12
10 => 10
0.1 => 0.1
0.0001 => 0.0001
1.2434E-5 => 1.2434E-5
0.123125 => 0.12313
8.16246765 => 8.16247
20 => 20
0.00014152 => 0.00014152
7500.251232 => 7500.3
10010.11111 => 10010
7500.102 => 7500.1
1111.11 => 1111.1


Volgens mij lijkt dit zo te kloppen!
:z euhm .... ja! Ik geloof dat ik ook nog wakker moest worden. Inderdaad gelezen, maar niet geregistreerd in mijn hersenpan. Oei........

[ Voor 8% gewijzigd door Wolf3D op 31-05-2022 14:22 ]


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Wolf3D schreef op dinsdag 31 mei 2022 @ 14:19:
[...]

Thanks!! Ik heb er even wat getallen doorheen laten lopen, en het gaat redelijk goed. Alleen bij getallen boven de 0 houdt hij vast aan de 5 getallen achter de komma (met $digits = 5).
Ah, ik dacht dat dat de bedoeling was. De voorbeelden zijn niet uitputtend. Moet 1234567.89 afgerond worden naar 1234600 of naar 1234567?

Ik denk dat als je de functie versimpelt naar
code:
1
2
3
4
function roundsignficant($number,$digits)
{
    return round($number,$digits-floor(log10($number)+1));
}

dat het dan al behoorlijk goed werkt (niet getest trouwens). En als je ook negatieve getallen aan moet kunnen, dan moet je die even apart testen. Misschien moet je hier en daar een minteken toevoegen/weghalen om het goed te laten werken.

Anyway, ik denk dat je er zo wel uitkomt. Mocht je je eerste miljoen verdiend hebben, dan hoor ik dat graag.

When life gives you lemons, start a battery factory


Acties:
  • 0 Henk 'm!

  • Wolf3D
  • Registratie: Augustus 2001
  • Laatst online: 22-08 12:03
KabouterSuper schreef op dinsdag 31 mei 2022 @ 14:37:
[...]

Ah, ik dacht dat dat de bedoeling was. De voorbeelden zijn niet uitputtend. Moet 1234567.89 afgerond worden naar 1234600 of naar 1234567?

Ik denk dat als je de functie versimpelt naar
code:
1
2
3
4
function roundsignficant($number,$digits)
{
    return round($number,$digits-floor(log10($number)+1));
}

dat het dan al behoorlijk goed werkt (niet getest trouwens). En als je ook negatieve getallen aan moet kunnen, dan moet je die even apart testen. Misschien moet je hier en daar een minteken toevoegen/weghalen om het goed te laten werken.

Anyway, ik denk dat je er zo wel uitkomt. Mocht je je eerste miljoen verdiend hebben, dan hoor ik dat graag.
Super bedankt! En jouw laatste oplossing is natuurlijk ook veel simpeler dan mijn bedachte code, en werkt zelfs nog ietsje beter. Zag dat er in mijn methode nog één getal fout ging, wat met jouw code goed gaat. Dus top!! Negatieve nummers zijn niet mogelijk, dus dat scheelt!

De trading bot draait al een tijdje (gaat maar af en toe fout), maar helaas kan ik nog niet verhuizen naar m'n villa! Zodra ik dankzij jouw code een klapper maak nodig ik je uit in mijn nieuwe villa voor één (of meerdere) biertje(s)! :9B
Pagina: 1