Skip to content

Instantly share code, notes, and snippets.

@laserpez
Last active May 17, 2025 14:29
Show Gist options
  • Select an option

  • Save laserpez/39ccfbb15ac63898a721ecae4f307e51 to your computer and use it in GitHub Desktop.

Select an option

Save laserpez/39ccfbb15ac63898a721ecae4f307e51 to your computer and use it in GitHub Desktop.
Average stock price calculator with LIFO strategy
#!/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