Skip to content

Instantly share code, notes, and snippets.

@zdxerr
Last active August 29, 2015 14:02
Show Gist options
  • Save zdxerr/5796facee4c3c4c1e695 to your computer and use it in GitHub Desktop.
Save zdxerr/5796facee4c3c4c1e695 to your computer and use it in GitHub Desktop.
Stock analysis tool.
{
"Accounts": {
"Comdirect Tagesgeld": {
"Actions": [
{
"Action": "payment",
"Date": "2014-06-10",
"Quantity": 1.0,
"Value": 2289.12
}
],
"BIC": "COBADEHD044",
"IBAN": "DE22200411440496732900"
},
"flatex Cashkonto": {
"Actions": [
{
"Action": "payment",
"Date": "2014-06-10",
"Quantity": 1.0,
"Value": 2604.11
}
],
"BIC": "BIWBDE33XXX",
"IBAN": "DE24101308001000947715"
}
},
"Stocks": {
"Sinopipe": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-02-03",
"Description": "",
"Quantity": 1000.0,
"Taxes": 0.0,
"Value": 0.2
}
],
"Places": [
"f"
],
"Symbol": "3si"
},
"Bayer": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-09-26",
"Description": "TA.-Nr. 40345152",
"Quantity": 50.0,
"Taxes": 0.0,
"Value": 37.31
},
{
"Action": "bonus",
"Cost": 0.0,
"Date": "2013-04-29",
"Description": "",
"Quantity": 50.0,
"Taxes": 25.05,
"Value": 1.9
},
{
"Action": "sell",
"Cost": 7.02,
"Date": "2013-05-13",
"Description": "TA.-Nr. 590267786",
"Quantity": -50.0,
"Taxes": 605.45,
"Value": 83.5
}
],
"Places": [
"de"
],
"Symbol": "bayn"
},
"Commerzbank": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-02-03",
"Description": "",
"Quantity": 380.0,
"Taxes": 0.0,
"Value": 4.033
},
{
"Action": "capital reduction",
"Cost": 0.0,
"Date": "2013-04-24",
"Description": "Kapitalherabsetzung",
"Quantity": -380.0,
"Taxes": 0.0,
"Value": 4.033
},
{
"Action": "capital reduction",
"Cost": 0.0,
"Date": "2013-04-24",
"Description": "Kapitalherabsetzung",
"Quantity": 60.0,
"Taxes": 0.0,
"Value": 25.543000000000003
},
{
"Action": "buy",
"Cost": 5.0,
"Date": "2013-05-31",
"Description": "Kapitalerh\u00f6hung",
"Quantity": 57.0,
"Taxes": 0.0,
"Value": 4.5
}
],
"Places": [
"de"
],
"Symbol": "cbk"
},
"cmid.f": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-02-03",
"Description": "",
"Quantity": 25.0,
"Taxes": 0.0,
"Value": 17.56
},
{
"Action": "sell",
"Cost": 10.97,
"Date": "2013-09-20",
"Description": "",
"Quantity": -25.0,
"Taxes": 0.0,
"Value": 0.114
}
],
"Places": [
"f"
],
"Symbol": "cmid"
},
"Deutsche Post": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-09-23",
"Description": "TA.-Nr. 403152122",
"Quantity": 80.0,
"Taxes": 0.0,
"Value": 9.0
},
{
"Action": "sell",
"Cost": 6.99,
"Date": "2013-05-14",
"Description": "TA.-Nr. 590591860",
"Quantity": -80.0,
"Taxes": 213.67,
"Value": 19.3
}
],
"Places": [
"de"
],
"Symbol": "dpw"
},
"Forsys Metals": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-02-03",
"Description": "",
"Quantity": 2000.0,
"Taxes": 0.0,
"Value": 2.09425
},
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-03-16",
"Description": "TA.-Nr. 332738263",
"Quantity": 500.0,
"Taxes": 0.0,
"Value": 1.444
},
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-09-21",
"Description": "TA.-Nr. 402067343",
"Quantity": 1000.0,
"Taxes": 0.0,
"Value": 0.42
},
{
"Action": "sell",
"Cost": 10.97,
"Date": "2013-11-26",
"Description": "",
"Quantity": -3500.0,
"Taxes": 0.0,
"Value": 0.265
}
],
"Places": [
"f"
],
"Symbol": "f2t"
},
"njf.f": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-02-03",
"Description": "",
"Quantity": 1000.0,
"Taxes": 0.0,
"Value": 0.39799999999999996
}
],
"Places": [
"f"
],
"Symbol": "njf"
},
"Thyssenkrupp": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2012-06-12",
"Description": "TA.-Nr. 489505577",
"Quantity": 100.0,
"Taxes": 0.0,
"Value": 12.0
}
],
"Places": [
"de"
],
"Symbol": "tka"
},
"Tesla Motors": {
"Actions": [
{
"Action": "buy",
"Cost": 7.01,
"Date": "2014-04-16",
"Description": "",
"Quantity": 15.0,
"Taxes": 0.0,
"Value": 142.0
}
],
"Places": [
"de"
],
"Symbol": "tl0"
},
"TUI": {
"Actions": [
{
"Action": "buy",
"Cost": 0.0,
"Date": "2011-09-14",
"Description": "TA.-Nr. 399498167",
"Quantity": 200.0,
"Taxes": 0.0,
"Value": 3.97
},
{
"Action": "sell",
"Cost": 7.0,
"Date": "2013-05-13",
"Description": "TA.-Nr. 590260878",
"Quantity": -200.0,
"Taxes": 269.57,
"Value": 9.15
}
],
"Places": [
"de"
],
"Symbol": "tui1"
},
"Lufthansa": {
"Actions": [
{
"Action": "buy",
"Cost": 6.99,
"Date": "2014-06-17",
"Description": "TA-Nr. 62400143",
"Quantity": 100.0,
"Taxes": 0.0,
"Value": 16.0
}
],
"Places": [
"de"
],
"Symbol": "lha"
},
"Daimler": {
"Actions": [
{
"Action": "buy",
"Cost": 7.1,
"Date": "2014-07-28",
"Description": "TA-Nr. 742154935",
"Quantity": 30.0,
"Taxes": 0.0,
"Value": 65.0
}
],
"Places": [
"de"
],
"Symbol": "dai"
}
}
}
"""
"""
import csv
import decimal
import functools
import requests
import pandas
from pandas.io.data import DataReader
from datetime import datetime, date
import dateutil
import collections
from pprint import pprint
import logging
logger = logging.getLogger(__name__)
from utils import JSONFile
YAHOO_TODAY_URL = 'http://download.finance.yahoo.com/d/quotes.csv'
YAHOO_TODAY_FORMAT = 'sd1ohgl1vl1'
class Stock:
def __init__(self, symbol, locations):
self.symbol = symbol
self.locations = locations
def __str__(self):
return '%s.%s' % (self.symbol, self.locations[0])
@functools.lru_cache()
def today(self):
params = {
's': str(self),
'f': YAHOO_TODAY_FORMAT,
}
response = requests.get(YAHOO_TODAY_URL, params=params)
reader = csv.reader(
response.text.splitlines(),
delimiter=',',
quotechar='"',
)
name, date_str, *values = next(reader)
today = dateutil.parser.parse(date_str)
df = pandas.DataFrame(
index=pandas.DatetimeIndex(start=today, end=today, freq='D'),
columns=['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close'],
dtype=decimal.Decimal)
df.ix[0] = list(map(decimal.Decimal, values))
return df
@functools.lru_cache()
def history(self, since=datetime(2010,1,1)):
history = DataReader(
str(self),
'yahoo',
datetime(2012,1,1),
datetime.today(),
)
return history.append(self.today())
def _asdict(self):
return {
'symbol': self.symbol,
'locations': self.locations,
}
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
stock = Stock('cbk', ['de'])
# print(stock.history())
pprint(stock._asdict())
data = JSONFile('moneymaker.json')
stocks = data.setdefault('Stocks', dict())
for name, infos in stocks.items():
# print(name)
s = Stock(infos['Symbol'], infos['Places'])
print(s)
actions = infos.get('Actions', list())
s.actions = pandas.DataFrame(actions, columns=['Date', 'Action', 'Quantity', 'Value', 'Description'])
from dateutil import parser
s.actions['Date'] = s.actions['Date'].map(parser.parse)
print(s.actions)
# pprint(stocks)
"""
Utility classes and functions.
"""
import os
import json
import collections
import decimal
import logging
logger = logging.getLogger(__name__)
class JSONFile(dict):
"""
Handle JSON files.
"""
def __init__(self, path):
super(JSONFile, self).__init__()
self.path = os.path.abspath(path)
logger.debug("Open JSON file `%s`", path)
try:
with open(path) as fp:
try:
self.update(json.load(
fp,
object_pairs_hook=collections.OrderedDict,
parse_float=decimal.Decimal,
))
except ValueError:
logger.error("Invalid json file: %s", path)
except FileNotFoundError:
logger.warn("File not found `%s`", path)
self.flush()
@classmethod
def decimal_default(cls, obj):
"""
Decimal handler for JSON endocding.
"""
try:
return obj._asdict()
except AttributeError:
pass
try:
return float(obj)
except IOError:
pass
raise TypeError("Not serializeable %r of type %s." % (obj, type(obj)))
def to_json(self):
"""
Dumpt formated string of the files contents.
"""
return json.dumps(self,
indent=4,
sort_keys=True,
default=self.decimal_default
)
def flush(self):
"""Save changes to file."""
try:
os.makedirs(os.path.dirname(self.path))
except FileExistsError:
pass
with open(self.path, 'w+') as fp:
logger.debug("Write to `%s`", self.path)
fp.write(self.to_json())
if __name__ == '__main__':
from pprint import pprint
logging.basicConfig(level=logging.DEBUG)
json_file = JSONFile('test.json')
json_file['dec'] = decimal.Decimal('1.0000000001')
print(json_file)
json_file.flush()
json_read = JSONFile('test.json')
print(str(json_read))
pprint(dict(json_read))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment