PIT z Binance w 5 minut dzięki Pythonowi
Jak szybko i wygodnie obliczyć PIT za pomocą biblioteki nbp_sdk
Wprowadzenie
Każda osoba inwestująca w kryptowaluty ma obowiązek złożenia rocznego zeznania podatkowego (formularz PIT-38) do 30 kwietnia. Ręczne wyliczanie podatku może być uciążliwe, dlatego pokażę Ci, jak szybko i wygodnie obliczyć go za pomocą biblioteki nbp_sdk
napisanej w Pythonie na przykładzie giełdy Binance.
Przygotowanie
Na swoim systemie operacyjnym zainstaluj pythona w wersji 3.10
albo wyżej. Jeśli nie wiesz jak to zrobić to zajrzyj na oficjalną stronę pobierania. Po wykonaniu tej czynności powinieneś posiadać domyślny menedżer instalacji pakietów pip
, ściągnij i wgraj paczkę nbp_sdk
za pomocą polecenia:
1
pip install nbp_sdk
Pobierz swoje sprawozdanie roczne ze strony binance, powinno posiadać następujące nagłówki:
1
"User_ID","UTC_Time","Account","Operation","Coin","Change","Remark"
Zapisz plik w głównym katalogu projektu – możesz nadać mu dowolną nazwę, np. 2024.csv
.
Na koniec utwórz plik z rozszerzeniem .py
, który będzie Twoim programem, np. app.py
.
Piszemy program
W pliku app.py
Dodaj bibliotekę do obsługi csv
1
import csv
Dodaj bibliotekę do zarządzania datami
1
from datetime import datetime
Zaimportuj typ Decimal
który jest idealny do liczb które muszą być precyzyjne jak kwoty na wyciągu oraz stałą ROUND_HALF_UP
która determinuje zachowanie zaokrąglania liczb, w tym przypadku zaokrąglamy w górę.
1
from decimal import Decimal, ROUND_HALF_UP
Dodaj paczkę do łączenia się z narodowym bankiem polskim w celu pobrania kursu przypadającego na dany dzień
1
from nbp_sdk.client import NBPApiClient, CurrencyType
Następnie zdefiniuj funkcję do zaokrąglania kwot. Liczba typu 3.233
zostanie zaokrąglona do 3.23
natomiast 5.5159
do 5.52
1
2
def rounded_decimal(d: Decimal) -> Decimal:
return d.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
Utwórz instancję klienta API NBP
1
api = NBPApiClient()
Oraz dwie zmienne;
expanses
czyli koszty, tutaj to kwota konwersji z euro na daną kryptowalutęrevenues
czyli przychodu, tutaj to kwota konwersji z danej kryptowaluty na euro
1
2
expanses = Decimal(0)
revenues = Decimal(0)
A teraz przechodzimy do mięska czyli obsługi i przeliczania kosztów oraz wydatków z pliku csv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
with open('2024.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
change = Decimal(row["Change"])
operation = row['Operation']
coin = row['Coin']
# expanses
if operation == "Binance Convert" and coin == "EUR" and change < 0:
print(row)
date = datetime.strptime(row["UTC_Time"], "%Y-%m-%d %H:%M:%S")
rate = api.get_currency_rate_from_working_day_before_date(CurrencyType.EUR, date)
print(f"Koszty przed: {rounded_decimal(expanses)}")
expanses += change * -1 * rate.average_rate
print(f"Koszty po dodaniu: {rounded_decimal(expanses)}")
# revenues
if operation == "Binance Convert" and coin == "EUR" and change > 0:
print(row)
date = datetime.strptime(row["UTC_Time"], "%Y-%m-%d %H:%M:%S")
rate = api.get_currency_rate_from_working_day_before_date(CurrencyType.EUR, date)
print(f"Przychody przed: {rounded_decimal(expanses)}")
revenues += change * rate.average_rate
print(f"Przychody po dodaniu: {rounded_decimal(expanses)}")
print(f"Koszty: {rounded_decimal(expanses)} PLN")
print(f"Przychody: {rounded_decimal(revenues)} PLN")
- Otwieramy plik csv
2024.csv
i zapisujemy to jako zmienna kontekstowacsvfile
- Wczytujemy plik do biblioteki CSV, do zmiennej
reader
.reader
przechowuje listę wierszy csv w postaci słownika{'Nazwa kolumny': 'wartość'}
- Iterujemy po wierszach
- Definiujemy 3 zmienne:
change
kwota transakcjioperation
typ operacjicoin
typ waluty. Dla Europejczyków będzie to euro
- Typ operacji
Binance Convert
oznacza przewalutowanie i jeślicoin
toEUR
to z/na euro. Jeślichange
jest wartością ujemną to mówimy o koszcie, jeśli dodatnia to o przychodzie - Średni kurs waluty należy pobrać z dnia roboczego poprzedzającego datę transakcji – na przykład, jeśli transakcja miała miejsce w piątek, obowiązuje kurs z czwartku; jeśli w poniedziałek, to z piątku.
- Podliczamy koszty i przychody
- Wyświetlamy podsumowanie.
Całość
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import csv
from datetime import datetime
from decimal import Decimal, ROUND_HALF_UP
from nbp_sdk.client import NBPApiClient, CurrencyType
def rounded_decimal(d: Decimal) -> Decimal:
return d.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
api = NBPApiClient()
expanses = Decimal(0)
revenues = Decimal(0)
with open('2024.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
change = Decimal(row["Change"])
operation = row['Operation']
coin = row['Coin']
# expanses
if operation == "Binance Convert" and coin == "EUR" and change < 0:
print(row)
date = datetime.strptime(row["UTC_Time"], "%Y-%m-%d %H:%M:%S")
rate = api.get_currency_rate_from_working_day_before_date(CurrencyType.EUR, date)
print(f"Koszty przed: {rounded_decimal(expanses)}")
expanses += change * -1 * rate.average_rate
print(f"Koszty po dodaniu: {rounded_decimal(expanses)}")
# revenues
if operation == "Binance Convert" and coin == "EUR" and change > 0:
print(row)
date = datetime.strptime(row["UTC_Time"], "%Y-%m-%d %H:%M:%S")
rate = api.get_currency_rate_from_working_day_before_date(CurrencyType.EUR, date)
print(f"Przychody przed: {rounded_decimal(expanses)}")
revenues += change * rate.average_rate
print(f"Przychody po dodaniu: {rounded_decimal(expanses)}")
print(f"Koszty: {rounded_decimal(expanses)} PLN")
print(f"Przychody: {rounded_decimal(revenues)} PLN")
Wsparcie
Jeśli artykuł ci się do czegoś przydał to postaw mi kawę ☕. Nie musi być to kawa z Starbucksa, taka biedronkowa też jest ok ;) Każda nawet najmniejsza dotacja to sygnał że to co robię jest dla Ciebie wartościowe.