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()
|