Números inteiros e decimais
O Python tem dois tipos de número para o trabalho diário. Um int é um número inteiro, como 200 ações. Um float é um número decimal, como 184.25, um preço. type() informa de qual tipo é um valor. Contagens (ações, lotes, dias) são int; preços, retornos e razões são float.
shares = 200
price = 184.25
print(type(shares), type(price)) # <class 'int'> <class 'float'>Três tipos de divisão
+, - e * se comportam como o esperado. A divisão tem três variantes. / sempre devolve um float, mesmo em 10 / 2 (ou seja, 5.0). // é a divisão inteira: divide e arredonda para baixo até um número inteiro. % dá o resto. ** eleva um número a uma potência.
# Division, floor division, remainder and power
print(7 / 2) # 3.5
print(7 // 2) # 3
print(7 % 2) # 1
print(2 ** 10) # 1024// arredonda em direção a menos infinito, então -7 // 2 é -4, não -3. Para números positivos parece descartar os decimais; para negativos, não.Quantas ações inteiras você consegue comprar?
A divisão inteira responde a «quantas vezes isto cabe?». Com 1.000 em caixa e um preço de 184,25, cash // price é o número de ações inteiras e cash - shares * price é o que sobra. Com floats, // devolve um float (5.0), então envolva-o em int() quando precisar de uma contagem de verdade.
# Whole shares for a cash budget, and the cash left over
cash, price = 1000, 184.25
shares = int(cash // price)
left = cash - shares * price
print(shares, left) # 5 78.75Floats são aproximações
Um float guarda o número em binário, e a maioria dos decimais como 0.1 não tem forma binária exata. O Python guarda o mais próximo, por isso aparecem erros minúsculos. Isso acontece em todas as linguagens e não é um bug do Python. A regra para um quant: nunca compare floats com ==. Use math.isclose, que aceita uma pequena tolerância.
# Floats are approximate: compare with isclose, not ==
import math
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
print(math.isclose(0.1 + 0.2, 0.3)) # TrueArredondar para o tick
round(x, n) arredonda para n casas decimais. As bolsas só aceitam preços em um tick (por exemplo, a cada 0,05): divida pelo tick, arredonde para um número inteiro de ticks e multiplique de volta. Note também que round leva uma metade exata ao par mais próximo: round(2.5) é 2 e round(3.5) é 4.
# Snap a price to the nearest 5-cent tick
price, tick = 184.267, 0.05
ticks = round(price / tick)
print(ticks, ticks * tick) # 3685 184.25
print(round(2.5), round(3.5)) # 2 4Dinheiro em centavos inteiros
Como os floats são aproximados, os sistemas que precisam ser exatos guardam o dinheiro como um número inteiro de centavos. Para converter, multiplique por 100 e arredonde. int() apenas corta os decimais, então 19.99 * 100, que na verdade é 1998.9999999999998, perderia um centavo.
# Dollars to integer cents: round, do not truncate
amount = 19.99
print(amount * 100) # 1998.9999999999998
print(int(amount * 100)) # 1998 (a cent is lost)
print(round(amount * 100)) # 1999- Contagens (ações, lotes, dias):
int. - Preços, retornos e razões:
float, comparados commath.isclose. - Dinheiro exato: centavos inteiros (ou o módulo
decimal).
A seguir: strings e f-strings, em que você transforma esses números em texto legível, como AAPL 184.25 x 184.50.
Lab: o que é avaliado
- Contar as ações inteiras que um orçamento compra com
shares_for_cash25 pts - Encontrar o dinheiro que sobra com
leftover_cash25 pts - Ajustar um preço ao tick mais próximo com
round_to_tick25 pts - Converter dólares em centavos inteiros exatos com
cents25 pts