Created
February 14, 2023 05:16
-
-
Save williamd1k0/d74c07f84998ad0688c021a5106a0260 to your computer and use it in GitHub Desktop.
Format TradingView Financials data for compatibility with LibreOffice Calc.
This file contains 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/python | |
# This script is designed to be used with TextPieces | |
# Argument 1: Base (K/M/B/T) | |
# Argument 2: Base Format ({n} = number; {b} = base) | |
import sys, re | |
from decimal import Decimal | |
diff_pattern = re.compile(r'[\+\-−][0-9\.]+%') | |
date_pattern = re.compile(r'[0-9]{4}|(TTM)|(Current)') | |
number_pattern = re.compile(r'[\—\-0-9\.]+[KMBT]?') | |
d = { | |
'K': 3, | |
'M': 6, | |
'B': 9, | |
'T': 12, | |
} | |
def parse_number(text): | |
if text == "—": | |
return "*" | |
if text[-1] in d: | |
num, magnitude = text[:-1], text[-1] | |
return int(Decimal(num) * 10 ** d[magnitude]) | |
else: | |
return float(Decimal(text)) | |
def to_base(number, b=None, b_fmt="{n}{b}"): | |
if b is None or type(number) is not int: | |
return str(number) | |
elif type(number) is int and abs(number) >= 100: | |
return b_fmt \ | |
.replace("{n}", str(number / 10 ** d[base])) \ | |
.replace("{b}", base) | |
def is_header(line): | |
return date_pattern.match(line.strip()) | |
def is_number(line): | |
return number_pattern.match(line.strip()) | |
base = None | |
base_fmt = "{n}{b}" | |
if len(sys.argv) > 1: | |
base = sys.argv[1].strip() | |
if base == "": | |
base = None | |
if len(sys.argv) > 2: | |
base_fmt = sys.argv[2].strip() | |
if base_fmt == "": | |
base_fmt = "{n}{b}" | |
data = sys.stdin.read() | |
lines = [x for x in data.split('\n') if not diff_pattern.match(x)] | |
headers = ["Years"] | |
rows = [] | |
row = -1 | |
for line in lines: | |
line_fixed = line \ | |
.strip() \ | |
.replace("\u202a", "") \ | |
.replace("\u202c", "") \ | |
.replace("−", "-") | |
if is_header(line_fixed): | |
headers.append(line_fixed) | |
elif is_number(line_fixed) and len(rows[-1]) > 0: | |
rows[row].append(to_base(parse_number(line_fixed), base, base_fmt)) | |
else: | |
row += 1 | |
rows.append([line_fixed]) | |
result = "\t".join(headers) + "\n" | |
result += "\n".join(["\t".join(r) for r in rows]) | |
sys.stdout.write(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment