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_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_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_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_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 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 insert_asset_value(asset, date, granularity, open_, high, low, close_, volume, source): # FIXME: This kind of approach may not be safe in multithreading # environments if AssetValue.exists(asset_id=asset.id, evaluated_at=date, granularity=granularity): log.warn('AssetValue for {0} on {1} already exist', asset.code, date) else: asset_value = AssetValue.create(evaluated_at=date, granularity=Granularity.min, asset=asset, open=open_, high=high, low=low, close=close_, volume=int(volume), source=source, commit=False) log.info('Record has been create: {0}', asset_value)
def insert_asset_value(row, asset, target_asset): """ (evaluated_at, granularity, open, high, low, close) """ from finance.models import AssetValue columns = [x.strip() for x in row.split(',')] evaluated_at = make_date(columns[0]) granularity = columns[1] open, high, low, close = map(parse_decimal, columns[2:6]) return AssetValue.create( asset=asset, target_asset=target_asset, evaluated_at=evaluated_at, granularity=granularity, open=open, high=high, low=low, close=close)
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 import_stock_values(fin: io.TextIOWrapper, code: str, base_asset=None): """Import stock values.""" asset = Asset.get_by_symbol(code) reader = csv.reader( fin, delimiter=',', quotechar='"', skipinitialspace=True) for date, open_, high, low, close_, volume, source in reader: try: yield AssetValue.create( evaluated_at=date, granularity=Granularity.day, asset=asset, base_asset=base_asset, open=open_, high=high, low=low, close=close_, volume=volume, source=source) except IntegrityError: log.warn('AssetValue for {0} on {1} already exist', code, date) db.session.rollback()
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 insert_asset_value(row, asset, base_asset): """ (evaluated_at, granularity, open, high, low, close) """ from finance.models import AssetValue columns = [x.strip() for x in row.split(',')] evaluated_at = parse_date(columns[0]) granularity = columns[1] open, high, low, close = map(parse_decimal, columns[2:6]) return AssetValue.create(asset=asset, base_asset=base_asset, evaluated_at=evaluated_at, granularity=granularity, open=open, high=high, low=low, close=close)
def import_stock_values(fin: io.TextIOWrapper, code: str, base_asset=None): """Import stock values.""" asset = Asset.get_by_symbol(code) reader = csv.reader(fin, delimiter=',', quotechar='"', skipinitialspace=True) for date, open_, high, low, close_, volume, source in reader: try: yield AssetValue.create(evaluated_at=date, granularity=Granularity.day, asset=asset, base_asset=base_asset, open=open_, high=high, low=low, close=close_, volume=volume, source=source) except IntegrityError: log.warn('AssetValue for {0} on {1} already exist', code, date) db.session.rollback()
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()