Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Create assets and forecasts
assets = [
Equity("%s Inc." % ticker, ticker, "NYSE")
for ticker in ["AAA", "BBB", "CCC", "DDD"]
]
forecasts = [
Forecast(assets[i], val, start_dt, forecast_dt)
for i, val in enumerate([1.7, 2.8, 6.32, 36.8])
]
# Create Exchange and SimulatedBroker
prices = [24.68, 52.55, 63.85, 128.223]
exchange = ExchangeMock(assets, prices)
tdcm = TDDirectBrokerCommission()
broker = SimulatedBroker(
start_dt, exchange,
account_id=1234,
initial_funds=cash,
broker_commission=tdcm
)
bpid = "5678"
broker.create_portfolio(portfolio_id="5678")
broker.subscribe_funds_to_portfolio("5678", cash)
# Create portfolio construction model
ewpcm = EqualWeightPCM(
start_dt, broker, bpid,
transaction_cost_model=tdcm
)
# Calculate order equivalence
def test_good_set_initial_funds(self):
"""
Checks _set_initial_funds sets the initial funds
correctly if it is a positive floating point value.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
sb = SimulatedBroker(start_dt, exchange, initial_funds=1e4)
self.assertEqual(sb._set_initial_funds(1e4), 1e4)
"""
Tests the execute_order method for:
* Raises ValueError if no portfolio_id
* Raises ValueError if bid/ask is (np.NaN, np.NaN)
* Checks that bid/ask are correctly set dependent
upon order direction
* Checks that portfolio values are correct after
carrying out a transaction
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
# Raising KeyError if portfolio_id not in keys
exchange = ExchangeMock()
data_handler = DataHandlerMock()
sb = SimulatedBroker(start_dt, exchange, data_handler)
asset = AssetMock("Royal Dutch Shell Class B", "EQ:RDSB")
quantity = 100
order = OrderMock(asset.symbol, quantity)
with pytest.raises(KeyError):
sb.submit_order("1234", order)
# Raises ValueError if bid/ask is (np.NaN, np.NaN)
exchange_exception = ExchangeMockException()
sbnp = SimulatedBroker(start_dt, exchange_exception, data_handler)
sbnp.create_portfolio(portfolio_id=1234, name="My Portfolio #1")
quantity = 100
order = OrderMock(asset.symbol, quantity)
with pytest.raises(ValueError):
sbnp._execute_order(start_dt, "1234", order)
# Checks that bid/ask are correctly set dependent on
def test_get_account_cash_balance(self):
"""
Tests get_account_cash_balance method for:
* If currency is None, return the cash_balances
* If the currency code isn't in the cash_balances
dictionary, then raise BrokerException
* Otherwise, return the appropriate cash balance
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
sb = SimulatedBroker(
start_dt, exchange, initial_funds=1000.0
)
# If currency is None, return the cash balances
sbcb1 = sb.get_account_cash_balance()
tcb1 = dict(
zip(
settings.CURRENCIES,
[0.0] * len(settings.CURRENCIES)
)
)
tcb1["USD"] = 1000.0
self.assertEqual(
sbcb1, tcb1
)
def test_initial_settings_for_default_simulated_broker(self):
"""
Tests that the SimulatedBroker settings are set
correctly for default settings.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
# Test a default SimulatedBroker
sb1 = SimulatedBroker(start_dt, exchange)
self.assertEqual(sb1.start_dt, start_dt)
self.assertEqual(sb1.cur_dt, start_dt)
self.assertEqual(sb1.exchange, exchange)
self.assertEqual(sb1.account_id, None)
self.assertEqual(sb1.base_currency, "USD")
self.assertEqual(sb1.initial_funds, 0.0)
self.assertEqual(
type(sb1.broker_commission),
ZeroBrokerCommission
)
tcb1 = dict(
zip(
settings.CURRENCIES,
[0.0] * len(settings.CURRENCIES)
)
)
def test_withdraw_funds_from_account():
"""
Tests withdraw_funds_from_account method for:
* Raising ValueError with negative amount
* Raising ValueError for lack of cash
* Correctly setting cash_balances for positive amount
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
data_handler = DataHandlerMock()
sb = SimulatedBroker(start_dt, exchange, data_handler, initial_funds=1e6)
# Raising ValueError with negative amount
with pytest.raises(ValueError):
sb.withdraw_funds_from_account(-4306.23)
# Raising ValueError for lack of cash
with pytest.raises(ValueError):
sb.withdraw_funds_from_account(2e6)
# Correctly setting cash_balances for a positive amount
sb.withdraw_funds_from_account(3e5)
assert sb.cash_balances[sb.base_currency] == 7e5
def test_set_cash_balances():
"""
Checks _set_cash_balances for zero and non-zero
initial_funds.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
data_handler = DataHandlerMock()
# Zero initial funds
sb1 = SimulatedBroker(
start_dt, exchange, data_handler, initial_funds=0.0
)
tcb1 = dict(
zip(
settings.SUPPORTED['CURRENCIES'],
[0.0] * len(settings.SUPPORTED['CURRENCIES'])
)
)
assert sb1._set_cash_balances() == tcb1
# Non-zero initial funds
sb2 = SimulatedBroker(
start_dt, exchange, data_handler, initial_funds=12345.0
)
tcb2 = dict(
zip(
sbwp.submit_order("1234", order)
sbwp.update(start_dt)
port = sbwp.portfolios["1234"]
assert port.total_cash == 46530.0
assert port.total_non_cash_equity == 53470.0
assert port.total_equity == 100000.0
assert port.pos_handler.positions[asset.symbol].book_cost == 53470.0
assert port.pos_handler.positions[asset.symbol].unrealised_gain == 0.0
assert port.pos_handler.positions[asset.symbol].market_value == 53470.0
assert port.pos_handler.positions[asset.symbol].unrealised_percentage_gain == 0.0
assert port.pos_handler.positions[asset.symbol].quantity == 1000
# Negative direction
exchange_price = ExchangeMockPrice()
sbwp = SimulatedBroker(start_dt, exchange_price, data_handler_price)
sbwp.create_portfolio(portfolio_id=1234, name="My Portfolio #1")
sbwp.subscribe_funds_to_account(175000.0)
sbwp.subscribe_funds_to_portfolio("1234", 100000.00)
quantity = -1000
order = OrderMock(asset.symbol, quantity)
sbwp.submit_order("1234", order)
sbwp.update(start_dt)
port = sbwp.portfolios["1234"]
assert port.total_cash == 153450.0
assert port.total_non_cash_equity == -53450.0
assert port.total_equity == 100000.0
assert port.pos_handler.positions[asset.symbol].book_cost == -53450.0
assert port.pos_handler.positions[asset.symbol].unrealised_gain == 0.0
assert port.pos_handler.positions[asset.symbol].market_value == -53450.0
assert port.pos_handler.positions[asset.symbol].unrealised_percentage_gain == 0.0
def test_all_cases_of_set_broker_commission():
"""
Tests that _set_broker_commission correctly sets the
appropriate broker commission model depending upon
user choice.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
data_handler = DataHandlerMock()
# Broker commission is None
sb1 = SimulatedBroker(start_dt, exchange, data_handler)
assert sb1.fee_model.__class__.__name__ == "ZeroFeeModel"
# Broker commission is specified as a subclass
# of FeeModel abstract base class
bc2 = ZeroFeeModel
sb2 = SimulatedBroker(
start_dt, exchange, data_handler, fee_model=bc2
)
assert sb2.fee_model.__class__.__name__ == "ZeroFeeModel"
# FeeModel is mis-specified and thus
# raises a TypeError
with pytest.raises(TypeError):
SimulatedBroker(
start_dt, exchange, data_handler, fee_model="bad_fee_model"
)
def test_create_portfolio(self):
"""
Tests create_portfolio method for:
* If portfolio_id already in the dictionary keys,
raise BrokerException
* If it isn't, check that they portfolio and open
orders dictionary was created correctly.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
exchange = ExchangeMock()
sb = SimulatedBroker(start_dt, exchange)
# If portfolio_id isn't in the dictionary, then check it
# was created correctly, along with the orders dictionary
sb.create_portfolio(portfolio_id=1234, name="My Portfolio")
self.assertTrue("1234" in sb.portfolios)
self.assertTrue(isinstance(sb.portfolios["1234"], Portfolio))
self.assertTrue("1234" in sb.open_orders)
self.assertTrue(isinstance(sb.open_orders["1234"], queue.Queue))
# If portfolio is already in the dictionary
# then raise BrokerException
with self.assertRaises(BrokerException):
sb.create_portfolio(
portfolio_id=1234, name="My Portfolio"
)