prepare_from_sqlite.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from __future__ import annotations
  2. import collections
  3. import sqlite3
  4. import sys
  5. import typing
  6. import prepare
  7. def main() -> None:
  8. month, sqlite_path, run_id_s = sys.argv[1:]
  9. run_id = int(run_id_s)
  10. db = sqlite3.connect(sqlite_path)
  11. db.row_factory = sqlite3.Row
  12. cur = db.execute('SELECT started_at, finished_at, type, range, materials_failed FROM runs WHERE id = ?', (run_id,))
  13. (run,) = cur.fetchall()
  14. print(', '.join(f'{k}: {run[k]}' for k in run.keys())) # noqa: SIM118
  15. assert run['type'] == 'PRODUCTION' and run['range'] == 'DAYS_30' and run['materials_failed'] == 0
  16. with open(f'rawData/{month}-prices.json', 'r') as f:
  17. prices = prepare.get_prices(f)
  18. prod_data, company_data = get_prod_and_company_data(db, run_id, prices)
  19. with open(f'rawData/{month}.csv', 'r', newline='') as f:
  20. data = prepare.read_data(f)
  21. prepare.write_data(month, data, prod_data, company_data)
  22. prepare.check_missing_tickers(prod_data)
  23. def get_prod_and_company_data(db: sqlite3.Connection, run_id: int, prices: typing.Mapping[str, float]
  24. ) -> tuple[typing.Mapping[str, prepare.ProdData], typing.Mapping[str, typing.Any]]:
  25. cur = db.execute('''
  26. SELECT ticker, entity_id, score, rank FROM leaderboard_scores
  27. JOIN materials ON materials.material_pk = leaderboard_scores.material_rowid
  28. JOIN entities ON entities.id = leaderboard_scores.entity_rowid
  29. WHERE run_id = ?''', (run_id,))
  30. individual: dict[str, dict[str, prepare.CompanyTickerData]] = collections.defaultdict(dict)
  31. company_totals: dict[str, prepare.CompanyTotals] = collections.defaultdict(lambda: {'volume': 0.0})
  32. universe_total_score: dict[str, float] = collections.defaultdict(int)
  33. while row := cur.fetchone():
  34. ticker = row['ticker']
  35. price = prices[ticker]
  36. universe_total_score[ticker] += row['score']
  37. amount = row['score'] / 30
  38. volume = amount * price
  39. individual[row['entity_id']][ticker] = {
  40. 'amount': amount,
  41. 'volume': volume,
  42. 'rank': row['rank'],
  43. }
  44. company_totals[row['entity_id']]['volume'] += volume
  45. prod: dict[str, prepare.ProdData] = {} # TODO: universe / 30
  46. for ticker, total_score in universe_total_score.items():
  47. amount = total_score / 30
  48. prod[ticker] = {'amount': amount, 'volume': amount * prices[ticker]}
  49. company_data = {'totals': prepare.add_company_ranks(company_totals), 'individual': dict(individual)}
  50. return prod, company_data
  51. if __name__ == '__main__':
  52. main()