def import_8percent_data(parsed_data, account_checking, account_8p, asset_krw): from finance.models import Asset, AssetValue, Record, Transaction assert account_checking assert account_8p assert asset_krw asset_8p = Asset.create(name=parsed_data['name']) remaining_value = parsed_data['amount'] started_at = parsed_data['started_at'] with Transaction.create() as t: Record.create( created_at=started_at, transaction=t, account=account_checking, asset=asset_krw, quantity=-remaining_value) Record.create( created_at=started_at, transaction=t, account=account_8p, asset=asset_8p, quantity=1) AssetValue.create( evaluated_at=started_at, asset=asset_8p, target_asset=asset_krw, granularity='1day', close=remaining_value) for record in parsed_data['records']: date, principle, interest, tax, fees = record returned = principle + interest - (tax + fees) remaining_value -= principle with Transaction.create() as t: Record.create( created_at=date, transaction=t, account=account_checking, asset=asset_krw, quantity=returned) AssetValue.create( evaluated_at=date, asset=asset_8p, target_asset=asset_krw, granularity='1day', close=remaining_value)
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_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_transaction(): with Transaction.create() as t: assert t.state == TransactionState.initiated assert t.state == TransactionState.closed t = Transaction.create() assert t.state == TransactionState.initiated t.close(closed_at=datetime.utcnow()) assert t.state == TransactionState.closed
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 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_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) deposit(account_checking, asset_krw, 500000, parse_date("2015-12-04")) with Transaction.create() as t: deposit(account_checking, asset_krw, -500000, parse_date("2015-12-04"), t) deposit(account_hf, asset_hf1, 1, parse_date("2015-12-04"), t) # 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 deposit(account_checking, asset_krw, returned, parse_date("2016-01-08")) # 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 deposit(account_checking, asset_krw, 25016, parse_date("2016-02-05")) # 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 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 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 make_double_record_transaction(created_at, account, asset_from, quantity_from, asset_to, quantity_to): """Creates a double record transaction (e.g., a buy order of stocks)""" with Transaction.create() as t: record1 = deposit(account, asset_from, quantity_from, created_at, t) record2 = deposit(account, asset_to, quantity_to, created_at, t) return (record1, record2)
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_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: deposit(account_checking, asset_krw, 1000, parse_date('2016-01-01'), t) 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: deposit(account_checking, asset_krw, 2000, parse_date('2016-01-02'), t) 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: deposit(account_checking, asset_krw, -1500, parse_date('2016-01-03'), t) 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 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 import_8percent_data(parsed_data, account_checking, account_8p, asset_krw): from finance.models import Asset, AssetValue, Record, Transaction assert account_checking assert account_8p assert asset_krw asset_8p = Asset.create(name=parsed_data['name']) remaining_value = parsed_data['amount'] started_at = parsed_data['started_at'] with Transaction.create() as t: Record.create(created_at=started_at, transaction=t, account=account_checking, asset=asset_krw, quantity=-remaining_value) Record.create(created_at=started_at, transaction=t, account=account_8p, asset=asset_8p, quantity=1) AssetValue.create(evaluated_at=started_at, asset=asset_8p, target_asset=asset_krw, granularity='1day', close=remaining_value) for record in parsed_data['records']: date, principle, interest, tax, fees = record returned = principle + interest - (tax + fees) remaining_value -= principle with Transaction.create() as t: Record.create(created_at=date, transaction=t, account=account_checking, asset=asset_krw, quantity=returned) AssetValue.create(evaluated_at=date, asset=asset_8p, target_asset=asset_krw, granularity='1day', close=remaining_value)
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 make_double_record_transaction( created_at, account, asset_from, quantity_from, asset_to, quantity_to ): """Creates a double record transaction (e.g., a buy order of stocks)""" with Transaction.create() as t: record1 = Record.create( transaction=t, account_id=account.id, asset_id=asset_from.id, created_at=created_at, quantity=quantity_from, ) record2 = Record.create( transaction=t, account_id=account.id, asset_id=asset_to.id, created_at=created_at, quantity=quantity_to, ) return (record1, record2)
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()