def test_records(account_checking, asset_krw): with Transaction.create() as t: record = Record.create( created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=1000) # Make sure the record type has been set implictly assert RecordType.deposit == record.type with Transaction.create() as t: record = Record.create( created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=-2000) # Make sure the record type has been set implictly assert RecordType.withdraw == record.type with Transaction.create() as t: record = Record.create( created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=3000, type=RecordType.balance_adjustment) # Make sure the record type has been set explicitly assert RecordType.balance_adjustment == record.type
def test_portfolio_balance(account_checking, account_savings, account_sp500, asset_krw, asset_sp500): """Ensures a portfolio, which is essentially a collection of accounts, calculates its balance correctly. """ portfolio = Portfolio() portfolio.base_asset = asset_krw portfolio.add_accounts(account_checking, account_savings, account_sp500) assert portfolio.balance(parse_date('2016-05-20')) == {} deposit(account_checking, asset_krw, 1500, parse_date('2016-05-01')) deposit(account_savings, asset_krw, 3000, parse_date('2016-05-01')) deposit(account_sp500, asset_sp500, 120, parse_date('2016-05-01')) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 4500, asset_sp500: 120} deposit(account_savings, asset_krw, 4000, parse_date('2016-05-02')) deposit(account_savings, asset_krw, 5000, parse_date('2016-05-03')) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 13500, asset_sp500: 120} balance_adjustment(account_savings, asset_krw, 10000, parse_date('2016-05-04')) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 11500, asset_sp500: 120} db.session.delete(portfolio) db.session.commit()
def import_fund(code, from_date, to_date): """Imports fund data from KOFIA. :param code: e.g., KR5223941018 :param from_date: e.g., 2016-01-01 :param to_date: e.g., 2016-02-28 """ provider = Kofia() app = create_app(__name__) with app.app_context(): asset = get_asset_by_fund_code(code) # FIXME: Target asset should also be determined by asset.data.code base_asset = Asset.query.filter_by(name='KRW').first() data = provider.fetch_data( code, parse_date(from_date), parse_date(to_date)) for date, unit_price, quantity in data: log.info('Import data on {}', date) unit_price /= 1000.0 try: AssetValue.create( asset=asset, base_asset=base_asset, evaluated_at=date, close=unit_price, granularity=Granularity.day, source='kofia') except IntegrityError: log.warn('Identical record has been found for {}. Skipping.', date) db.session.rollback()
def test_records(account_checking, asset_krw): with Transaction.create() as t: record = Record.create(created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=1000) # Make sure the record type has been set implictly assert RecordType.deposit == record.type with Transaction.create() as t: record = Record.create(created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=-2000) # Make sure the record type has been set implictly assert RecordType.withdraw == record.type with Transaction.create() as t: record = Record.create(created_at=parse_date('2016-03-14'), transaction=t, account=account_checking, asset=asset_krw, quantity=3000, type=RecordType.balance_adjustment) # Make sure the record type has been set explicitly assert RecordType.balance_adjustment == record.type
def fetch_stock_values(stock_code, start_date, end_date): """Fetches daily stock values from Yahoo Finance.""" start_date = date_to_datetime( parse_date(start_date if start_date is not None else -30 * 3600 * 24)) end_date = date_to_datetime( parse_date(end_date if end_date is not None else 0)) if start_date > end_date: raise ValueError('start_date must be equal to or less than end_date') provider = Yahoo() rows = provider.asset_values( stock_code, start_date, end_date, Granularity.day) for row in rows: # TODO: Write a function to handle this for generic cases # TODO: Convert the timestamp to an ISO format # NOTE: The last column is data source. Not sure if this is an elegant # way to handle this. # FIXME: Think of a better way to handle this dt = row[0].isoformat() print(', '.join([dt] + [str(c) for c in row[1:]] + ['yahoo']))
def fetch_stock_values(stock_code, start_date, end_date): """Fetches daily stock values from Yahoo Finance.""" start_date = date_to_datetime( parse_date(start_date if start_date is not None else -30 * 3600 * 24)) end_date = date_to_datetime( parse_date(end_date if end_date is not None else 0)) if start_date > end_date: raise ValueError("start_date must be equal to or less than end_date") provider = Yahoo() rows = provider.asset_values(stock_code, start_date, end_date, Granularity.day) for row in rows: # TODO: Write a function to handle this for generic cases # TODO: Convert the timestamp to an ISO format # NOTE: The last column is data source. Not sure if this is an elegant # way to handle this. # FIXME: Think of a better way to handle this dt = row[0].isoformat() print(", ".join([dt] + [str(c) for c in row[1:]] + ["yahoo"]))
def import_fund(code, from_date, to_date): """Imports fund data from KOFIA. :param code: e.g., KR5223941018 :param from_date: e.g., 2016-01-01 :param to_date: e.g., 2016-02-28 """ provider = Kofia() app = create_app(__name__) with app.app_context(): asset = get_asset_by_fund_code(code) # FIXME: Target asset should also be determined by asset.data.code base_asset = Asset.query.filter_by(name="KRW").first() data = provider.fetch_data(code, parse_date(from_date), parse_date(to_date)) for date, unit_price, quantity in data: log.info("Import data on {}", date) unit_price /= 1000.0 try: AssetValue.create( asset=asset, base_asset=base_asset, evaluated_at=date, close=unit_price, granularity=Granularity.day, source="kofia", ) except IntegrityError: log.warn("Identical record has been found for {}. Skipping.", date) db.session.rollback()
def import_stock_values(code, from_date, to_date): """Import stock price information.""" app = create_app(__name__) with app.app_context(): # NOTE: We assume all Asset records are already in the database, but # this is a temporary workaround. We should implement some mechanism to # automatically insert an Asset record when it is not found. import_stock_values_(code, parse_date(from_date), parse_date(to_date))
def test_kofia_get_request_body(): provider = Kofia() body = provider.get_request_body( 'KR5223941018', parse_date('2016-06-02'), parse_date('2016-06-03')) # TODO: Parse XML for assertion assert '20160602' in body assert '20160603' in body
def request_import_stock_values_handler(event, context): codes = ["AMD", "AMZN", "BRK-A", "BRK-B", "ESRT", "NVDA", "SBUX", "SPY"] start_time = date_to_datetime(parse_date(-3)) end_time = date_to_datetime(parse_date(0)) for code in codes: request_import_stock_values(code, start_time, end_time) log.info("Requested to import stock values: {0}", ", ".join(codes))
def test_date_range(): start, end = parse_date("2016-01-01"), parse_date("2016-01-15") r = date_range(start, end) assert isinstance(r, types.GeneratorType) r = list(r) assert 14 == len(r) assert r[0] == parse_date("2016-01-01") assert r[13] == parse_date("2016-01-14")
def request_import_stock_values_handler(event, context): codes = ['AMD', 'AMZN', 'BRK-A', 'BRK-B', 'ESRT', 'NVDA', 'SBUX', 'SPY'] start_time = date_to_datetime(parse_date(-3)) end_time = date_to_datetime(parse_date(0)) for code in codes: request_import_stock_values(code, start_time, end_time) log.info('Requested to import stock values: {0}', ', '.join(codes))
def test_kofia_get_request_body(): provider = Kofia() body = provider.get_request_body( "KR5223941018", parse_date("2016-06-02"), parse_date("2016-06-03") ) # TODO: Parse XML for assertion assert "20160602" in body assert "20160603" in body
def test_kofia_fetch_data(): provider = Kofia() from_date, to_date = parse_date("2016-05-01"), parse_date("2016-05-30") data = provider.fetch_data("KR5223941018", from_date, to_date) for date, unit_price, quantity in data: assert isinstance(date, datetime) assert from_date <= date <= to_date assert isinstance(unit_price, float) assert isinstance(quantity, float)
def test_kofia_fetch_data(): provider = Kofia() from_date, to_date = parse_date('2016-05-01'), parse_date('2016-05-30') data = provider.fetch_data('KR5223941018', from_date, to_date) for date, unit_price, quantity in data: assert isinstance(date, datetime) assert from_date <= date <= to_date assert isinstance(unit_price, float) assert isinstance(quantity, float)
def test_account_net_worth_2(account_checking, account_sp500, asset_krw, asset_sp500): AssetValue.create( evaluated_at=parse_date('2016-02-25'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.77) AssetValue.create( evaluated_at=parse_date('2016-02-24'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=932.00) AssetValue.create( evaluated_at=parse_date('2016-02-23'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.06) AssetValue.create( evaluated_at=parse_date('2016-02-22'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.76) with Transaction.create() as t: Record.create( created_at=parse_date('2016-02-25'), transaction=t, account=account_sp500, asset=asset_sp500, quantity=1000) Record.create( created_at=parse_date('2016-02-25'), transaction=t, account=account_checking, asset=asset_krw, quantity=-1000 * 921.77) assert 921770 == account_sp500.net_worth( evaluated_at=parse_date('2016-02-25'), base_asset=asset_krw) assert 921770 == account_sp500.net_worth( evaluated_at=parse_date('2016-03-01'), approximation=True, base_asset=asset_krw)
def test_balance(account_checking, asset_krw, asset_usd): assert account_checking.balance() == {} Record.create( created_at=parse_date('2016-05-01'), account=account_checking, asset=asset_krw, quantity=1000) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 1000} Record.create( created_at=parse_date('2016-05-02'), account=account_checking, asset=asset_krw, quantity=-500) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500} Record.create( created_at=parse_date('2016-05-03'), account=account_checking, asset=asset_usd, quantity=25) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 25} Record.create( created_at=parse_date('2016-05-04'), account=account_checking, asset=asset_usd, quantity=40, type=RecordType.balance_adjustment) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 40}
def test_balance(account_checking, asset_krw, asset_usd): assert account_checking.balance() == {} Record.create(created_at=parse_date('2016-05-01'), account=account_checking, asset=asset_krw, quantity=1000) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 1000} Record.create(created_at=parse_date('2016-05-02'), account=account_checking, asset=asset_krw, quantity=-500) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500} Record.create(created_at=parse_date('2016-05-03'), account=account_checking, asset=asset_usd, quantity=25) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 25} Record.create(created_at=parse_date('2016-05-04'), account=account_checking, asset=asset_usd, quantity=40, type=RecordType.balance_adjustment) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 40}
def test_account_net_worth_2(account_checking, account_sp500, asset_krw, asset_sp500): AssetValue.create(evaluated_at=parse_date('2016-02-25'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.77) AssetValue.create(evaluated_at=parse_date('2016-02-24'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=932.00) AssetValue.create(evaluated_at=parse_date('2016-02-23'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.06) AssetValue.create(evaluated_at=parse_date('2016-02-22'), asset=asset_sp500, base_asset=asset_krw, granularity=Granularity.day, close=921.76) with Transaction.create() as t: deposit(account_sp500, asset_sp500, 1000, parse_date('2016-02-25'), t) deposit(account_checking, asset_krw, -1000 * 921.77, parse_date('2016-02-25'), t) assert 921770 == account_sp500.net_worth( evaluated_at=parse_date('2016-02-25'), base_asset=asset_krw) assert 921770 == account_sp500.net_worth( evaluated_at=parse_date('2016-03-01'), approximation=True, base_asset=asset_krw)
def test_balance(account_checking, asset_krw, asset_usd): assert account_checking.balance() == {} deposit(account_checking, asset_krw, 1000, parse_date("2016-05-01")) assert account_checking.balance(parse_date("2016-05-19")) == { asset_krw: 1000 } deposit(account_checking, asset_krw, -500, parse_date("2016-05-02")) assert account_checking.balance(parse_date("2016-05-19")) == { asset_krw: 500 } deposit(account_checking, asset_usd, 25, parse_date("2016-05-03")) assert account_checking.balance(parse_date("2016-05-19")) == { asset_krw: 500, asset_usd: 25, } balance_adjustment(account_checking, asset_usd, 40, parse_date("2016-05-04")) assert account_checking.balance(parse_date("2016-05-19")) == { asset_krw: 500, asset_usd: 40, }
def test_yahoo_fetch_data(): provider = Yahoo() from_date, to_date = parse_date('2014-01-01'), parse_date('2015-12-31') data = provider.fetch_data('005380.KS', from_date, to_date) for date, open_, high, low, close_, volume, adj_close in data: assert isinstance(date, datetime) # assert from_date <= date <= to_date assert isinstance(open_, float) assert isinstance(high, float) assert isinstance(low, float) assert isinstance(close_, float) assert isinstance(volume, int) assert isinstance(adj_close, float)
def import_sp500(): app = create_app(__name__) with app.app_context(): account_checking = Account.get(id=1001) account_sp500 = Account.get(id=7001) asset_krw = Asset.query.filter_by(name='KRW').first() asset_sp500 = Asset.query.filter_by(name='KB S&P500').first() with open('sample-data/sp500.csv') as fin: for line in fin: cols = line.split() if len(cols) != 5: continue date = parse_date(cols[0], '%Y.%m.%d') _type = cols[1] quantity_krw, quantity_sp500 = \ [int(extract_numbers(v)) for v in cols[2:4]] print(cols) withdraw = _type == '일반입금' with Transaction.create() as t: if withdraw: Record.create( created_at=date, account=account_checking, asset=asset_krw, quantity=-quantity_krw, transaction=t) Record.create( created_at=date, account=account_sp500, asset=asset_sp500, quantity=quantity_sp500, transaction=t) print(account_sp500.net_worth(make_date('2016-02-25'), target_asset=asset_krw))
def gen_records(rows): for row in rows: date = parse_date(extract_div_text(row, class_='Cell_445'), DATE_FORMAT) principle = etnc(row, 'Cell_451', int) interest = etnc(row, 'Cell_448', int) tax = etnc(row, 'Cell_449', int) fees = etnc(row, 'Cell_452', int) # NOTE: Early payments may cause some portion of the fees # to be refunded refunded_fees = etnc(row, 'Cell_759', int) returned = etnc(row, 'Cell_453', int) # Make sure the parsed data is correct try: assert returned \ == principle + interest - (tax + fees - refunded_fees) except AssertionError: import pdb pdb.set_trace() pass yield date, principle, interest, tax, fees - refunded_fees
def test_date_to_datetime(): date = parse_date("2018-01-13") dt_beginning = parse_datetime("2018-01-13 00:00:00") dt_end = parse_datetime("2018-01-13 23:59:59") assert date_to_datetime(date) == dt_beginning assert date_to_datetime(date, True) == dt_end
def import_sp500_records(): """Import S&P500 fund sample data. Expects a tab seprated value document. """ app = create_app(__name__) app.app_context().push() account_checking = Account.get(id=1001) account_sp500 = Account.get(id=7001) asset_krw = Asset.query.filter_by(name='KRW').first() asset_sp500 = Asset.query.filter_by(name='KB S&P500').first() # Expected number of columns expected_col_count = 6 with open('sample-data/sp500.csv') as fin: # Skip the first row (headers) headers = next(fin) col_count = len(headers.split()) if col_count != expected_col_count: raise Exception( 'Expected number of columns = {}, ' 'actual number of columns = {}'.format( expected_col_count, col_count)) for line in fin: cols = line.split('\t') if len(cols) != expected_col_count: continue date = parse_date(cols[0], '%Y.%m.%d') _type = cols[1] quantity_krw, quantity_sp500 = \ [int(extract_numbers(v)) for v in cols[3:5]] log.info(', '.join([c.strip() for c in cols])) if not (_type == '일반입금' or _type == '일반신규'): log.info('Record type \'{}\' will be ignored', _type) continue with Transaction.create() as t: # NOTE: The actual deposit date and the buying date generally # differ by a few days. Need to figure out how to parse this # properly from the raw data. try: Record.create( created_at=date, account=account_checking, asset=asset_krw, quantity=-quantity_krw, transaction=t) except IntegrityError: log.warn('Identical record exists') db.session.rollback() try: Record.create( created_at=date, account=account_sp500, asset=asset_sp500, quantity=quantity_sp500, transaction=t) except IntegrityError: log.warn('Identical record exists') db.session.rollback()
def test_portfolio_balance(account_checking, account_savings, account_sp500, asset_krw, asset_sp500): portfolio = Portfolio() portfolio.base_asset = asset_krw portfolio.add_accounts(account_checking, account_savings, account_sp500) assert portfolio.balance(parse_date('2016-05-20')) == {} Record.create(created_at=parse_date('2016-05-01'), account=account_checking, asset=asset_krw, quantity=1500) Record.create(created_at=parse_date('2016-05-01'), account=account_savings, asset=asset_krw, quantity=3000) Record.create(created_at=parse_date('2016-05-01'), account=account_sp500, asset=asset_sp500, quantity=120) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 4500, asset_sp500: 120} Record.create(created_at=parse_date('2016-05-02'), account=account_savings, asset=asset_krw, quantity=4000) Record.create(created_at=parse_date('2016-05-03'), account=account_savings, asset=asset_krw, quantity=5000) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 13500, asset_sp500: 120} Record.create(created_at=parse_date('2016-05-04'), account=account_savings, asset=asset_krw, quantity=10000, type=RecordType.balance_adjustment) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 11500, asset_sp500: 120} db.session.delete(portfolio) db.session.commit()
def test_account_net_worth_4(account_checking, asset_usd): """Ensures Account.net_worth() works with explicit `created_at`.""" deposit(account_checking, asset_usd, 1000, parse_datetime('2018-08-30 23:00:00')) net_worth = account_checking.net_worth( base_asset=asset_usd, evaluated_at=parse_date('2018-08-30')) assert net_worth == 1000
def test_net_worth_without_asset_value(request, account_sp500, asset_krw, asset_sp500): asset_values = AssetValue.query.filter_by(asset=asset_sp500) for asset_value in asset_values: db.session.delete(asset_value) db.session.commit() record = Record.create( created_at=parse_date('2016-05-27'), account=account_sp500, asset=asset_sp500, quantity=1000) with pytest.raises(AssetValueUnavailableException): account_sp500.net_worth(parse_date('2016-05-28'), base_asset=asset_krw) def teardown(): db.session.delete(record) db.session.commit() request.addfinalizer(teardown)
def test_net_worth_without_asset_value(request, account_sp500, asset_krw, asset_sp500): asset_values = AssetValue.query.filter_by(asset=asset_sp500) for asset_value in asset_values: db.session.delete(asset_value) db.session.commit() record = deposit(account_sp500, asset_sp500, 1000, parse_date('2016-05-27')) with pytest.raises(AssetValueUnavailableException): account_sp500.net_worth(parse_date('2016-05-28'), base_asset=asset_krw) def teardown(): db.session.delete(record) db.session.commit() request.addfinalizer(teardown)
def import_sp500_records(): """Import S&P500 fund sample data. Expects a tab seprated value document. """ app = create_app(__name__) app.app_context().push() account_checking = Account.get(id=1001) account_sp500 = Account.get(id=7001) asset_krw = Asset.query.filter_by(name="KRW").first() asset_sp500 = Asset.query.filter_by(name="KB S&P500").first() # Expected number of columns expected_col_count = 6 with open("sample-data/sp500.csv") as fin: # Skip the first row (headers) headers = next(fin) col_count = len(headers.split()) if col_count != expected_col_count: raise Exception("Expected number of columns = {}, " "actual number of columns = {}".format( expected_col_count, col_count)) for line in fin: cols = line.split("\t") if len(cols) != expected_col_count: continue date = parse_date(cols[0], "%Y.%m.%d") _type = cols[1] quantity_krw, quantity_sp500 = [ int(extract_numbers(v)) for v in cols[3:5] ] log.info(", ".join([c.strip() for c in cols])) if not (_type == "일반입금" or _type == "일반신규"): log.info("Record type '{}' will be ignored", _type) continue with Transaction.create() as t: # NOTE: The actual deposit date and the buying date generally # differ by a few days. Need to figure out how to parse this # properly from the raw data. try: deposit(account_checking, asset_krw, -quantity_krw, date, t) except IntegrityError: log.warn("Identical record exists") db.session.rollback() try: deposit(account_sp500, asset_sp500, quantity_sp500, date, t) except IntegrityError: log.warn("Identical record exists") db.session.rollback()
def test_account_net_worth_4(account_checking, asset_usd): """Ensures Account.net_worth() works with explicit `created_at`.""" Record.create( account=account_checking, asset=asset_usd, quantity=1000, type=RecordType.deposit, created_at=parse_datetime('2018-08-30 23:00:00')) net_worth = account_checking.net_worth( base_asset=asset_usd, evaluated_at=parse_date('2018-08-30')) assert net_worth == 1000
def test_8percent_parse_data(): sample_file = os.path.join(PROJECT_PATH, 'tests', 'data', '8percent-829.html') with open(sample_file) as fin: raw = fin.read() stored_data = [ ('2016-04-11', 1694, 613, 160, 340), ('2016-05-11', 1916, 390, 90, 0), ('2016-06-13', 1920, 386, 90, 0), ('2016-07-11', 1982, 324, 80, 0), ('2016-08-10', 1963, 343, 80, 0), ('2016-09-12', 1979, 327, 80, 0), ('2016-10-10', 2005, 301, 70, 0), ('2016-11-14', 1992, 314, 70, 0), ('2016-12-12', 2054, 252, 60, 0), ('2017-01-10', 2044, 262, 60, 0), ('2017-02-13', 2053, 253, 60, 0), ('2017-03-13', 2099, 207, 50, 0), ('2017-04-10', 2101, 205, 50, 0), ('2017-05-15', 2098, 208, 50, 0), ('2017-06-12', 2145, 161, 40, 0), ('2017-07-10', 2151, 155, 30, 0), ('2017-08-14', 2153, 153, 30, 0), ('2017-09-11', 2188, 118, 20, 0), ('2017-10-11', 2198, 108, 20, 0), ('2017-11-13', 2216, 90, 20, 0), ('2017-12-11', 2238, 68, 10, 0), ('2018-01-10', 2251, 55, 10, 0), ('2018-02-12', 2270, 36, 0, 0), ('2018-03-12', 2290, 16, 0, 0), ] provider = _8Percent() parsed_data = provider.parse_data(raw) assert parsed_data['name'] assert parsed_data['grade'] assert isinstance(parsed_data['duration'], int) assert isinstance(parsed_data['annual_percentage_yield'], float) assert 0.0 < parsed_data['annual_percentage_yield'] <= 0.3 assert isinstance(parsed_data['amount'], int) assert 0 < parsed_data['amount'] flag = True for expected, actual in zip(stored_data, parsed_data['records']): assert len(expected) == len(actual) expected = list(expected) expected[0] = parse_date(expected[0]) for exp, act in zip(expected, actual): flag = False assert exp == act if flag: pytest.fail('parse_8percent_data() did not return any data')
def test_account_net_worth_4(account_checking, asset_usd): """Ensures Account.net_worth() works with explicit `created_at`.""" Record.create(account=account_checking, asset=asset_usd, quantity=1000, type=RecordType.deposit, created_at=parse_datetime('2018-08-30 23:00:00')) net_worth = account_checking.net_worth( base_asset=asset_usd, evaluated_at=parse_date('2018-08-30')) assert net_worth == 1000
def test_records(account_checking, asset_krw): with Transaction.create() as t: record = deposit(account_checking, asset_krw, 1000, parse_date('2016-03-14'), t) # Make sure the record type has been set implictly assert RecordType.deposit == record.type with Transaction.create() as t: record = deposit(account_checking, asset_krw, -2000, parse_date('2016-03-14'), t) # Make sure the record type has been set implictly assert RecordType.withdraw == record.type with Transaction.create() as t: record = balance_adjustment(account_checking, asset_krw, 3000, parse_date('2016-03-14'), t) # Make sure the record type has been set explicitly assert RecordType.balance_adjustment == record.type
def test_yahoo_provider(granularity): provider = Yahoo() symbol = "MSFT" start_time = datetime.combine(parse_date(-5), time(0)) end_time = datetime.utcnow() asset_values = provider.asset_values(symbol, start_time, end_time, granularity) flag = False for asset_value in asset_values: flag = True assert len(asset_value) == 6 assert all([c is not None for c in asset_value]) assert flag
def test_portfolio_balance(account_checking, account_savings, account_sp500, asset_krw, asset_sp500): portfolio = Portfolio() portfolio.base_asset = asset_krw portfolio.add_accounts(account_checking, account_savings, account_sp500) assert portfolio.balance(parse_date('2016-05-20')) == {} Record.create( created_at=parse_date('2016-05-01'), account=account_checking, asset=asset_krw, quantity=1500) Record.create( created_at=parse_date('2016-05-01'), account=account_savings, asset=asset_krw, quantity=3000) Record.create( created_at=parse_date('2016-05-01'), account=account_sp500, asset=asset_sp500, quantity=120) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 4500, asset_sp500: 120} Record.create( created_at=parse_date('2016-05-02'), account=account_savings, asset=asset_krw, quantity=4000) Record.create( created_at=parse_date('2016-05-03'), account=account_savings, asset=asset_krw, quantity=5000) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 13500, asset_sp500: 120} Record.create( created_at=parse_date('2016-05-04'), account=account_savings, asset=asset_krw, quantity=10000, type=RecordType.balance_adjustment) assert portfolio.balance(parse_date('2016-05-20')) \ == {asset_krw: 11500, asset_sp500: 120} db.session.delete(portfolio) db.session.commit()
def test_yahoo_provider(granularity): provider = Yahoo() symbol = 'MSFT' start_time = datetime.combine(parse_date(-5), time(0)) end_time = datetime.utcnow() asset_values = \ provider.asset_values(symbol, start_time, end_time, granularity) flag = False for asset_value in asset_values: flag = True assert len(asset_value) == 6 assert all([c is not None for c in asset_value]) assert flag
def test_balance(account_checking, asset_krw, asset_usd): assert account_checking.balance() == {} deposit(account_checking, asset_krw, 1000, parse_date('2016-05-01')) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 1000} deposit(account_checking, asset_krw, -500, parse_date('2016-05-02')) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500} deposit(account_checking, asset_usd, 25, parse_date('2016-05-03')) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 25} balance_adjustment(account_checking, asset_usd, 40, parse_date('2016-05-04')) assert account_checking.balance(parse_date('2016-05-19')) \ == {asset_krw: 500, asset_usd: 40}
def import_sp500(): app = create_app(__name__) with app.app_context(): account_checking = Account.get(id=1001) account_sp500 = Account.get(id=7001) asset_krw = Asset.query.filter_by(name='KRW').first() asset_sp500 = Asset.query.filter_by(name='KB S&P500').first() with open('sample-data/sp500.csv') as fin: for line in fin: cols = line.split() if len(cols) != 5: continue date = parse_date(cols[0], '%Y.%m.%d') _type = cols[1] quantity_krw, quantity_sp500 = \ [int(extract_numbers(v)) for v in cols[2:4]] print(cols) withdraw = _type == '일반입금' with Transaction.create() as t: if withdraw: Record.create(created_at=date, account=account_checking, asset=asset_krw, quantity=-quantity_krw, transaction=t) Record.create(created_at=date, account=account_sp500, asset=asset_sp500, quantity=quantity_sp500, transaction=t) print( account_sp500.net_worth(make_date('2016-02-25'), target_asset=asset_krw))
def test_insert_stock_record(db, account_stock, account_checking): data = { "date": parse_date("2016-06-30"), "sequence": 1, "category1": "장내매수", "category2": "매수", "code": "005380", "name": "현대차", "unit_price": 136000, "quantity": 10, "subtotal": 1360000, "interest": 0, "fees": 200, "late_fees": 0, "channel": "", "final_amount": 1670200, } asset = Asset.create(type="stock", code="005380.KS", description="현대차") record = insert_stock_record(data, account_stock, account_checking) # TODO: Automate this process db.session.delete(record) db.session.delete(asset) db.session.commit()
def test_insert_stock_record(db, account_stock, account_checking): data = { 'date': parse_date('2016-06-30'), 'sequence': 1, 'category1': '장내매수', 'category2': '매수', 'code': '005380', 'name': '현대차', 'unit_price': 136000, 'quantity': 10, 'subtotal': 1360000, 'interest': 0, 'fees': 200, 'late_fees': 0, 'channel': '', 'final_amount': 1670200, } asset = Asset.create(type='stock', code='005380.KS', description='현대차') record = insert_stock_record(data, account_stock, account_checking) # TODO: Automate this process db.session.delete(record) db.session.delete(asset) db.session.commit()
def request_import_stock_values(code): """Enqueue a request to import stock values.""" start_time = date_to_datetime(parse_date(-3)) end_time = date_to_datetime(parse_date(0)) request_import_stock_values_(code, start_time, end_time)
def test_account_net_worth_1(account_checking, asset_krw): assert 0 == account_checking.net_worth( evaluated_at=parse_date('2016-01-01'), base_asset=asset_krw) assert 0 == account_checking.net_worth( evaluated_at=parse_date('2016-01-02'), base_asset=asset_krw) assert 0 == account_checking.net_worth( evaluated_at=parse_date('2016-01-03'), base_asset=asset_krw) assert 0 == account_checking.net_worth( evaluated_at=parse_date('2016-01-04'), base_asset=asset_krw) with Transaction.create() as t: Record.create( created_at=parse_date('2016-01-01'), transaction=t, account=account_checking, asset=asset_krw, quantity=1000) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-01'), base_asset=asset_krw) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-02'), base_asset=asset_krw) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-03'), base_asset=asset_krw) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-04'), base_asset=asset_krw) with Transaction.create() as t: Record.create( created_at=parse_date('2016-01-02'), transaction=t, account=account_checking, asset=asset_krw, quantity=2000) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-01'), base_asset=asset_krw) assert 3000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-02'), base_asset=asset_krw) assert 3000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-03'), base_asset=asset_krw) assert 3000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-04'), base_asset=asset_krw) with Transaction.create() as t: Record.create( created_at=parse_date('2016-01-03'), transaction=t, account=account_checking, asset=asset_krw, quantity=-1500) assert 1000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-01'), base_asset=asset_krw) assert 3000 == account_checking.net_worth( evaluated_at=parse_date('2016-01-02'), base_asset=asset_krw) assert 1500 == account_checking.net_worth( evaluated_at=parse_date('2016-01-03'), base_asset=asset_krw) assert 1500 == account_checking.net_worth( evaluated_at=parse_date('2016-01-04'), base_asset=asset_krw)
def test_portfolio(account_hf, asset_hf1, account_checking, asset_krw): portfolio = Portfolio() portfolio.base_asset = asset_krw portfolio.add_accounts(account_hf, account_checking) with Transaction.create() as t: Record.create( created_at=parse_date('2015-12-04'), transaction=t, account=account_checking, asset=asset_krw, quantity=500000) Record.create( created_at=parse_date('2015-12-04'), transaction=t, account=account_checking, asset=asset_krw, quantity=-500000) Record.create( created_at=parse_date('2015-12-04'), transaction=t, account=account_hf, asset=asset_hf1, quantity=1) # The net asset value shall not be available at this point with pytest.raises(AssetValueUnavailableException): net_worth = portfolio.net_worth(evaluated_at=parse_date('2015-12-04'), granularity=Granularity.day) # Initial asset value AssetValue.create( evaluated_at=parse_date('2015-12-04'), asset=asset_hf1, base_asset=asset_krw, granularity=Granularity.day, close=500000) net_worth = portfolio.net_worth(evaluated_at=parse_date('2015-12-04'), granularity=Granularity.day) assert 500000 == net_worth # 1st payment interest, tax, returned = 3923, 740, 30930 with Transaction.create() as t: Record.create( created_at=parse_date('2016-01-08'), transaction=t, account=account_checking, asset=asset_krw, quantity=returned) # Remaining principle value after the 1st payment AssetValue.create( evaluated_at=parse_date('2016-01-08'), asset=asset_hf1, base_asset=asset_krw, granularity=Granularity.day, close=472253) net_worth = portfolio.net_worth(evaluated_at=parse_date('2016-01-08'), granularity=Granularity.day) assert 500000 + (interest - tax) == net_worth # 2nd payment with Transaction.create() as t: Record.create( created_at=parse_date('2016-02-05'), transaction=t, account=account_checking, asset=asset_krw, quantity=25016) # Remaining principle value after the 2nd payment AssetValue.create( evaluated_at=parse_date('2016-02-05'), asset=asset_hf1, base_asset=asset_krw, granularity=Granularity.day, close=450195) db.session.delete(portfolio) db.session.commit()
def __set__(self, instance, value): self._values[instance] = parse_date(value, self.date_format)