예제 #1
0
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()
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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()
예제 #5
0
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
예제 #6
0
def test_account_net_worth_3(account_checking, asset_usd):
    """Ensures Account.net_worth() works with implicit `created_at`, which is
    the current datetime.
    """
    deposit(account_checking, asset_usd, 1000)

    net_worth = account_checking.net_worth(base_asset=asset_usd)
    assert net_worth == 1000
예제 #7
0
파일: utils.py 프로젝트: jungmin03/finance
def insert_stock_transfer_record(data: dict, bank_account: object):
    """Inserts a transfer record between a bank account and a stock account.
    """
    from finance.models import Asset, deposit

    # FIXME: Not a good idea to use a hard coded value
    asset_krw = Asset.query.filter(Asset.name == 'KRW').first()

    subtotal = data['subtotal']
    date = data['date']

    if data['name'] == '증거금이체':
        # Transfer from a bank account to a stock account
        return deposit(bank_account, asset_krw, -subtotal, date)
    elif data['name'] == '매매대금정산':
        # Transfer from a stock account to a bank account
        return deposit(bank_account, asset_krw, subtotal, date)
    else:
        raise ValueError("Unrecognized transfer type '{}'".format(
            data['name']))
예제 #8
0
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
예제 #9
0
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,
    }
예제 #10
0
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)
예제 #11
0
파일: utils.py 프로젝트: jungmin03/finance
def insert_stock_trading_record(data: dict, stock_account: object):
    """Inserts a stock trading (i.e., buying or selling stocks) records."""
    from finance.models import Asset, deposit
    if data['category1'].startswith('장내'):
        code_suffix = '.KS'
    elif data['category1'].startswith('코스닥'):
        code_suffix = '.KQ'
    else:
        code_suffix = ''
        raise ValueError(
            "code_suffix could not be determined with the category '{}'"
            ''.format(data['category1']))

    code = data['code'] + code_suffix

    asset = Asset.get_by_symbol(code)
    if asset is None:
        raise ValueError(
            "Asset object could not be retrived with code '{}'".format(code))

    return deposit(stock_account, asset, data['quantity'], data['date'])
예제 #12
0
def insert_stock_trading_record(data: dict, stock_account: object):
    """Inserts a stock trading (i.e., buying or selling stocks) records."""
    from finance.models import Asset, deposit

    if data["category1"].startswith("장내"):
        code_suffix = ".KS"
    elif data["category1"].startswith("코스닥"):
        code_suffix = ".KQ"
    else:
        code_suffix = ""
        raise ValueError(
            "code_suffix could not be determined with the category '{}'"
            "".format(data["category1"]))

    code = data["code"] + code_suffix

    asset = Asset.get_by_symbol(code)
    if asset is None:
        raise ValueError(
            "Asset object could not be retrived with code '{}'".format(code))

    return deposit(stock_account, asset, data["quantity"], data["date"])
예제 #13
0
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)
예제 #14
0
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}
예제 #15
0
def test_record_created_at(account_checking, asset_krw):
    record = deposit(account_checking, asset_krw, 1000)

    # `created_at` must be set as the time at which the record created
    assert record.created_at