Last active
May 17, 2025 14:29
-
-
Save laserpez/39ccfbb15ac63898a721ecae4f307e51 to your computer and use it in GitHub Desktop.
Average stock price calculator with LIFO strategy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import csv | |
| import argparse | |
| from collections import defaultdict | |
| BUY = "Buy" | |
| SELL = "Sell" | |
| class Transaction: | |
| def __init__(self, shares, price): | |
| self.shares = shares | |
| self.price = price | |
| def calculate_lifo_average(transactions): | |
| portfolios = defaultdict(list) | |
| def print_sale_average(transaction, sold_lots): | |
| total_cost = sum(lot['shares'] * lot['price'] for lot in sold_lots) | |
| total_shares = sum(lot['shares'] for lot in sold_lots) | |
| avg_price = total_cost / total_shares if total_shares > 0 else 0 | |
| print(f"{transaction['date']}: [{transaction['stock']}] Prezzo medio di carico delle azioni vendute: {avg_price:.2f} euro per azione per un totale di {total_cost:.2f} euro") | |
| for transaction in reversed(transactions): | |
| stock = transaction['stock'] | |
| if transaction['type'] == BUY: | |
| portfolios[stock].append(Transaction(transaction['shares'], transaction['price'])) | |
| elif transaction['type'] == SELL: | |
| shares_to_sell = transaction['shares'] | |
| sold_lots = [] # <-- Per tenere traccia dei blocchi venduti (LIFO) | |
| while shares_to_sell > 0 and portfolios[stock]: | |
| top = portfolios[stock][-1] | |
| if top.shares <= shares_to_sell: | |
| sold_lots.append({'shares': top.shares, 'price': top.price}) | |
| shares_to_sell -= top.shares | |
| portfolios[stock].pop() | |
| else: | |
| sold_lots.append({'shares': shares_to_sell, 'price': top.price}) | |
| top.shares -= shares_to_sell | |
| shares_to_sell = 0 | |
| print(f"Transazione: {transaction}") | |
| print_sale_average(transaction, sold_lots) | |
| else: | |
| print(f"Tipo di transazione non riconosciuto: {transaction['type']}") | |
| def read_transactions_from_csv(file_path): | |
| transactions = [] | |
| with open(file_path, mode='r') as file: | |
| reader = csv.DictReader(file) | |
| # print(reader.fieldnames) | |
| for row in reader: | |
| transaction = { | |
| 'date': row[reader.fieldnames[0]], | |
| 'stock': row['Symbol'], | |
| 'type': row['Type'], | |
| 'shares': float(row['Quantity']), | |
| 'price': float(row['Price']), | |
| 'total': float(row['Total(€)']) | |
| } | |
| transactions.append(transaction) | |
| return transactions | |
| def main(): | |
| parser = argparse.ArgumentParser(description='Calcola il prezzo medio di acquisto delle azioni.') | |
| parser.add_argument('file_path', type=str, help='Il percorso del file CSV con le transazioni.') | |
| args = parser.parse_args() | |
| # Leggi le transazioni dal file CSV | |
| transactions = read_transactions_from_csv(args.file_path) | |
| # Calcola e stampa il prezzo medio dopo ogni transazione | |
| calculate_lifo_average(transactions) | |
| if __name__ == '__main__': | |
| main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment