summaryrefslogtreecommitdiff
path: root/ledger-price-db-update.py
blob: 5167c13c93f733dd9a866982199ae684af607e53 (plain) (blame)
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import traceback
from configparser import ConfigParser
import requests
import json
import datetime
from codecs import open

# Config sample:
#
# [fixer]
# access_key = 00000000000000000000000000000000
# base=RUB
#
# [exchange-symbols]
# USD=$
# EUR=€
# RUB=R
#
# [stocks]
# symbols=V,AMD
#
# [etf]
# symbols=FXUS
#
# [bond]
# RUS-20=XS0088543193

CONFIG_FILE = '~/.ledger-commodities'
config = ConfigParser()
config.readfp(open(os.path.expanduser(CONFIG_FILE), 'r', 'utf-8'))


def get_json(url, **kwargs):
    response = requests.get(url, **kwargs)
    return json.loads(response.content)


def print_price(symbol, price, base, date=datetime.datetime.now()):
    date_str = date.strftime('%Y/%m/%d %H:%M:%S')
    print ('P %s %s %f %s'  % (date_str, symbol, price, base)).encode('utf-8')


def exchange_rates():
    base = config.get('fixer', 'base')
    symbols = dict([(symbol.upper(), commodity) for symbol, commodity in config.items('exchange-symbols')])
    params = {
            "access_key": config.get('fixer', 'access_key'),
            "symbols": ','.join(symbols.keys() + [base,])
    }

    rates = get_json(r'http://data.fixer.io/api/latest', params=params)['rates']
    base_value = rates[base]
    for symbol, value in rates.items():
        if symbol != base:
            print_price(symbols[symbol], base_value / value, symbols[base])


def stocks():
    for symbol in config.get('stocks', 'symbols').split(','):
        post_data = {
                'msg': 'min',
                'symbol': symbol,
                'qesymbol': symbol
        }
        response = requests.post(r'https://www.nasdaq.com/callbacks/NLSHandler2.ashx', data=post_data)
        data = json.loads(response.content)
        price = data['data'][-1]['price']
        print_price(symbol, price, '$')

def get_moex_value(data, name):
    if 'columns' in data:
        index = data['columns'].index(name)
        if 'data' in data:
            if len(data['data']) > 0:
                return data['data'][0][index]
    return None

def etfs():
    symbols = config.get('etf', 'symbols')
    for symbol in symbols.split(','):
        data = get_json(r'http://iss.moex.com/iss/engines/stock/markets/shares/boards/TQTF/securities/%s.jsonp' % symbol)['marketdata']

        value = get_moex_value(data, 'LAST')
        print_price(symbol, value, 'R')

def bonds():
    symbols = config.items('bond')
    date = datetime.datetime.now() - datetime.timedelta(days=1)
    date_str = date.strftime('%Y-%m-%d')
    for short, symbol in symbols:
        url = r'https://iss.moex.com/iss/history/engines/stock/markets/bonds/boards/TQOD/securities/%s.jsonp?from=%s' % (symbol, date_str)
        data = get_json(url)['history']
        if len(data['data']) > 0:
            value = get_moex_value(data, 'CLOSE')
            nominal = get_moex_value(data, 'FACEVALUE')
            currency = get_moex_value(data, 'FACEUNIT')
            if currency == 'USD':
                currency = '$'
            elif currency == 'EUR':
                currency = '€'
            elif currency == 'RUB':
                currency = 'R'
            if value is None or nominal is None or currency is None:
                continue
            print_price(short.upper(), value * nominal / 100.0, currency, date)


def main():
    updates = [exchange_rates, stocks, etfs, bonds]
    for update in updates:
        try:
            update()
        except Exception as e:
            print >> sys.stderr, 'Oops, update method `%s` failed: %s' % (update, e)
            traceback.print_exc()

if __name__ == '__main__':
    main()