示例#1
0
 def test_funds_under_risk(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=200, symbol='a2')
     f1 = Fund('f1', {'a1': 10, 'a2': 10, 'a3': 10}, 100, 1, 1)
     f2 = Fund('f2', {'a1': 10}, 100, 1, 1)
     network = AssetFundNetwork.AssetFundsNetwork(
         funds={
             'f1': f1,
             'f2': f2
         },
         assets={
             'a1': a1,
             'a2': a2
         },
         mi_calc=MockMarketImpactTestCalculator())
     network.reset_order_books = MagicMock()
     network.simulate_trade = MagicMock()
     network.submit_sell_orders = MagicMock()
     network.get_funds_in_margin_calls = MagicMock(return_value=['f1'])
     actions_mgr = ActionsManager(network.assets, 0.1)
     actual_funds = actions_mgr._ActionsManager__funds_under_risk(network)
     self.assertListEqual(actual_funds, ['f1'])
     network.reset_order_books.assert_called_once()
     network.submit_sell_orders.assert_called_once_with(
         [Sell('a1', 10), Sell('a2', 20)])
     network.simulate_trade.assert_called_once()
     network.get_funds_in_margin_calls.assert_called_once()
示例#2
0
 def test_get_possible_attacks(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=10, symbol='a1')
     a1.set_price(3)
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=4, symbol='a2')
     a2.set_price(4)
     a3 = AssetFundNetwork.Asset(price=7, daily_volume=2, symbol='a3')
     f1 = Fund('f1', {'a1': 10, 'a2': 10, 'a3': 10}, 100, 1, 1)
     f2 = Fund('f2', {'a1': 10}, 100, 1, 1)
     SysConfig.set("STEP_ORDER_SIZE", 0.5)
     network = AssetFundNetwork.AssetFundsNetwork(
         funds={
             'f1': f1,
             'f2': f2
         },
         assets={
             'a1': a1,
             'a2': a2,
             'a3': a3
         },
         mi_calc=MockMarketImpactTestCalculator())
     actual_orders = get_possible_attacks(network, 10)
     expected_orders = []
     expected_orders.append(([Sell('a1', 5)], 5))
     expected_orders.append(([Sell('a2', 2)], 4))
     expected_orders.append(([Sell('a3', 1)], 7))
     expected_orders.append(([Sell('a1', 5), Sell('a2', 2)], 9))
     expected_orders.append(([], 0))
     self.assertEqual(actual_orders, expected_orders)
def single_fund_attack_optimal_attack_generator(network: AssetFundsNetwork,
                                                fund_sym,
                                                mic: MarketImpactCalculator,
                                                order_size, max_num_orders):

    fund = network.funds[fund_sym]
    assets = network.assets
    fund_impacts = {}
    for a in assets.values():
        shares_for_1M = floor(10000000 / a.zero_time_price)
        asset_price_impact = mic.get_market_impact(
            Sell(a.symbol, shares_for_1M), a.daily_volume)
        fund_impacts[
            a.
            symbol] = 0 if a.symbol not in fund.portfolio else fund.portfolio[
                a.symbol] * asset_price_impact
    sorted_impact = sorted(fund_impacts.items(),
                           key=lambda x: x[1],
                           reverse=True)
    cost = 0
    actions = []
    for sym, impact in sorted_impact:
        num_orders = 1
        num_shares = floor(assets[sym].daily_volume * order_size)
        while num_orders <= max_num_orders:
            order = Sell(sym, num_shares)
            actions.append(order)
            cost += assets[sym].zero_time_price * num_shares
            network.submit_sell_orders([order])
            network.clear_order_book()
            if fund.marginal_call(assets):
                return actions, cost
            num_orders += 1
    return actions, cost
示例#4
0
 def test_get_possible_attacks_no_history(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=200, symbol='a2')
     assets = {'a1': a1, 'a2': a2}
     mgr = ActionsManager(assets, 0.1)
     expected_attacks = [([Sell('a1', 10)], 10), ([Sell('a2', 20)], 40),
                         ([], 0)]
     actual_attacks = mgr.get_possible_attacks(budget=40)
     actual_attacks.sort(key=lambda a: a[1])
     expected_attacks.sort(key=lambda a: a[1])
     self.assertListEqual(expected_attacks, actual_attacks)
示例#5
0
 def test_get_single_orders(self):
     assets = {'a1': Asset(10, 100, 'a1'), 'a2': Asset(20, 200, 'a2')}
     expected_sell_orders = [Sell('a1', 10), Sell('a2', 20)]
     expected_buy_orders = [Buy('a1', 10), Buy('a2', 20)]
     actions_mgr = ActionsManager(assets, 0.1)
     actual_buy_orders = actions_mgr._ActionsManager__get_single_orders(
         assets, ActionsManager._ActionsManager__gen_buy_order)
     actual_sell_orders = actions_mgr._ActionsManager__get_single_orders(
         assets, ActionsManager._ActionsManager__gen_sell_order)
     self.assertListEqual(expected_sell_orders, actual_sell_orders)
     self.assertListEqual(expected_buy_orders, actual_buy_orders)
示例#6
0
 def test_get_possible_attacks(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=200, symbol='a2')
     a3 = AssetFundNetwork.Asset(price=3, daily_volume=300, symbol='a3')
     assets = {'a1': a1, 'a2': a2, 'a3': a3}
     mgr = ActionsManager(assets, 0.1)
     history = {BUY: {'a1': 2}, SELL: {'a1': 1, 'a2': 2}}
     expected_attacks = [([Sell('a1', 10)], 10), ([Sell('a3', 30)], 90),
                         ([Sell('a1', 10), Sell('a3', 30)], 100), ([], 0)]
     actual_attacks = mgr.get_possible_attacks(100, history)
     actual_attacks.sort(key=lambda a: a[1])
     expected_attacks.sort(key=lambda a: a[1])
     self.assertListEqual(expected_attacks, actual_attacks)
示例#7
0
 def test_gen_liquidation_orders(self):
     SysConfig.set("MINUTE_VOLUME_LIMIT", 0.1)
     assets = {
         'XXX': Asset(2, 3900, 1.5, 'XXX'),
         'YYY': Asset(1, 7900, 1.5, 'yyy'),
         'ZZZ': Asset(1, 7900, 1.5, 'yyy')
     }
     fund = Fund('F1', {'XXX': 10, 'YYY': 11, 'ZZZ': 2}, 5, 2, 0.25)
     expected_orders = [Sell('XXX', 1), Sell('YYY', 2), Sell('ZZZ', 2)]
     expected_portfolio = {'XXX': 9, 'YYY': 9}
     orders = fund.gen_liquidation_orders(assets)
     self.assertEqual(orders, expected_orders)
     self.assertEqual(fund.portfolio, expected_portfolio)
示例#8
0
    def test_get_attacks_in_budget(self):
        a1 = AssetFundNetwork.Asset(price=10, daily_volume=10, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=20, daily_volume=10, symbol='a2')
        f1 = MockFund('f1', a1, 1)
        f2 = MockFund('f2', a2, 1)
        network = AssetFundNetwork.AssetFundsNetwork(
            funds={
                'f1': f1,
                'f2': f2
            },
            assets={
                'a1': a1,
                'a2': a2
            },
            mi_calc=MockMarketImpactTestCalculator())

        expected_portfolio = [
            ([], 0),
            ([Sell("a1", 5)], 50),
            ([Sell("a1", 10)], 100),
            ([Sell("a2", 5)], 100),
            ([Sell("a2", 10)], 200),
            ([Sell("a1", 5), Sell("a2", 5)], 150),
            ([Sell("a1", 10), Sell("a2", 5)], 200),
        ]
        solver = SingleAgentESSolver(network, 0.5, 2)
        actual_portfolio = solver.get_attacks_in_budget(200, True)
        expected_portfolio_str = sorted([(str(x), str(y))
                                         for (x, y) in expected_portfolio])
        actual_portfolio_str = sorted([(str(x), str(y))
                                       for (x, y) in actual_portfolio])
        self.assertEqual(expected_portfolio_str, actual_portfolio_str)
示例#9
0
 def dont_test_get_possible_attacks_single_asset_per_attack(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=2, symbol='a1')
     f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
     SysConfig.set("ORDER_SIZES", [0.5, 1])
     network = AssetFundNetwork.AssetFundsNetwork(
         funds={'f1': f1},
         assets={'a1': a1},
         mi_calc=MockMarketImpactTestCalculator())
     actual_sell_orders = get_possible_attacks(network, 10)
     expected_sell_orders = []
     expected_sell_orders.append(([Sell('a1', 2)], 2))
     expected_sell_orders.append(([Sell('a1', 1)], 1))
     expected_sell_orders.append(([], 0))
     self.assertEqual(actual_sell_orders, expected_sell_orders)
    def test_gen_optimal_attacks(self):
        a1 = AssetFundNetwork.Asset(price=10, daily_volume=10, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=20, daily_volume=10, symbol='a2')
        f1 = MockFund('f1', a1, 1)
        f2 = MockFund('f2', a2, 1)
        f2 = MockFund('f3', a2, 1)
        network = AssetFundNetwork.AssetFundsNetwork(
            funds={
                'f1': f1,
                'f2': f2
            },
            assets={
                'a1': a1,
                'a2': a2
            },
            mi_calc=MockMarketImpactTestCalculator())

        expected_portfolio = [
            ([], 0),
            ([Sell("a1", 5)], 50),
            ([Sell("a1", 10)], 100),
            ([Sell("a2", 5)], 100),
            ([Sell("a2", 10)], 200),
            ([Sell("a1", 5), Sell("a2", 5)], 150),
            ([Sell("a1", 10), Sell("a2", 5)], 200),
        ]
    def test_solution2(self):
        a1 = AssetFundNetwork.Asset(price=2, daily_volume=500, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1000, symbol='a2')
        f1 = AssetFundNetwork.Fund('f1', {'a1': 10, 'a2': 10}, 16, 1, 1)
        f2 = AssetFundNetwork.Fund('f2', {'a1': 5, 'a2': 4}, 5, 2, 0.25)
        network = AssetFundNetwork.AssetFundsNetwork(funds = {'f1':f1, 'f2':f2},
                                                     assets={'a1':a1, 'a2':a2},
                                                     mi_calc=MockMarketImpactTestCalculator(),
                                                     intraday_asset_gain_max_range=None,
                                                     limit_trade_step=False
                                                     )

        actions,cost = single_fund_attack_optimal_attack_generator(network, 'f1',
                                                                   MockMarketImpactTestCalculator(),0.25,3)
        self.assertEqual(cost, 500)
        self.assertEqual(actions, [Sell('a1', 125),Sell('a1', 125)])
    def test_simulate_trade_sell_orders_in_buy_command(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
        f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
        f2 = Fund('f2', {'a2': 10}, 100, 1, 1)
        mi_calc = MarketImpactCalculator()
        mi_calc.get_updated_price = MagicMock()
        network = AssetFundNetwork.AssetFundsNetwork(funds={
            'f1': f1,
            'f2': f2
        },
                                                     assets={
                                                         'a1': a1,
                                                         'a2': a2
                                                     },
                                                     mi_calc=mi_calc,
                                                     limit_trade_step=False)
        exception = False
        try:
            network.submit_buy_orders([Buy('a1', 2), Sell('a1', 2)])
        except TypeError:
            exception = True

        mi_calc.get_updated_price.assert_not_called()
        self.assertTrue(exception)
    def test_simulate_trade_sell_more_than_buy(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
        f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
        f2 = Fund('f2', {'a2': 10}, 100, 1, 1)
        mi_calc = MarketImpactCalculator()
        mi_calc.get_updated_price = MagicMock(return_value=0.5)

        network = AssetFundNetwork.AssetFundsNetwork(funds={
            'f1': f1,
            'f2': f2
        },
                                                     assets={
                                                         'a1': a1,
                                                         'a2': a2
                                                     },
                                                     mi_calc=mi_calc,
                                                     limit_trade_step=False)
        network.submit_buy_orders([Buy('a1', 2)])
        network.submit_sell_orders([Sell('a1', 3)])
        log = network.simulate_trade()
        self.assertDictEqual({'a1': '1->0.5'}, log)
        mi_calc.get_updated_price.assert_called_once_with(1, a1, -1)
        self.assertFalse(network.buy_orders)
        self.assertFalse(network.sell_orders)
        self.assertTrue(a1.price == 0.5)
        self.assertTrue(a2.price == 2)
    def test_simulate_trade_buy_equals_sell(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
        f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
        f2 = Fund('f2', {'a2': 10}, 100, 1, 1)
        mi_calc = MarketImpactCalculator()
        mi_calc.get_updated_price = MagicMock()

        network = AssetFundNetwork.AssetFundsNetwork(funds={
            'f1': f1,
            'f2': f2
        },
                                                     assets={
                                                         'a1': a1,
                                                         'a2': a2
                                                     },
                                                     mi_calc=mi_calc,
                                                     limit_trade_step=False)
        network.submit_buy_orders([Buy('a1', 3)])
        network.submit_sell_orders([Sell('a1', 3)])
        log = network.simulate_trade()
        mi_calc.get_updated_price.assert_not_called()
        self.assertFalse(log)
        self.assertFalse(network.buy_orders)
        self.assertFalse(network.sell_orders)
        self.assertTrue(a1.price == 1)
        self.assertTrue(a2.price == 2)
    def test_simulate_trade_mix_trades(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
        f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
        f2 = Fund('f2', {'a2': 10}, 100, 1, 1)
        mi_calc = MarketImpactCalculator()
        mi_calc.get_updated_price = MagicMock(return_value=1.5)

        network = AssetFundNetwork.AssetFundsNetwork(funds={
            'f1': f1,
            'f2': f2
        },
                                                     assets={
                                                         'a1': a1,
                                                         'a2': a2
                                                     },
                                                     mi_calc=mi_calc,
                                                     limit_trade_step=False)

        network.submit_sell_orders([Sell('a2', 2)])
        network.submit_buy_orders([Buy('a1', 2)])

        log = network.simulate_trade()
        calls = [call(2, a2, -1), call(2, a1, 1)]
        mi_calc.get_updated_price.assert_has_calls(calls, any_order=True)
        self.assertDictEqual({'a1': '1->1.5', 'a2': '2->1.5'}, log)
        self.assertFalse(network.buy_orders)
        self.assertFalse(network.sell_orders)
    def build_attack_rec_wrong(self, n, c, network):
        if n == 0 or c == 0:
            s = Solution(network, [], 0)
            self.solutions[n][c] = s
            return s
        asset_sym = self.id_to_sym[n]
        if self.solutions[n][c]:
            return self.solutions[n][c]
        elif self.weights[n] > c:
            s = self.build_attack(n - 1, c, copy.deepcopy(network))
            self.solutions[n][c] = s
            return s
        else:
            prev_solutions = {}
            max_result = self.build_attack(n - 1, c, copy.deepcopy(network))
            prev_solutions[1] = self.build_attack(n - 1, c - self.weights[n],
                                                  copy.deepcopy(network))
            prev_solutions[2] = self.build_attack(n, c - self.weights[n],
                                                  copy.deepcopy(network))
            order = Sell(
                asset_sym, self.min_order_percentage *
                network.assets[asset_sym].daily_volume)
            for i in range(1, 2):
                net2 = prev_solutions[i].network
                net2.submit_sell_orders([order])
                net2.clear_order_book()
                value = net2.count_margin_calls()
                if value > max_result.value:
                    actions = copy.copy(prev_solutions[i].actions)
                    actions.append(order)
                    max_result = Solution(net2, actions, value)

            self.solutions[n][c] = max_result
            return max_result
 def attack(self, n, network, orders_list):
     if n == 0:
         net2 = copy.deepcopy(network)
         net2.submit_sell_orders(orders_list)
         net2.clear_order_book()
         funds = net2.get_funds_in_margin_calls()
         cost = sum([
             o.num_shares * network.assets[o.asset_symbol].zero_time_price
             for o in orders_list
         ])
         value = len(funds)
         for i in range(1, value + 1):
             if i not in self.solutions or cost < self.solutions[i].cost:
                 self.solutions[i] = Solution(network, orders_list, value,
                                              funds, cost)
         return
     asset_sym = self.id_to_sym[n]
     orders_list2 = copy.copy(orders_list)
     self.attack(n - 1, network, orders_list2)
     for i in range(1, self.max_order_num + 1):
         num_shares = int(
             floor(i * self.min_order_percentage *
                   network.assets[asset_sym].daily_volume))
         order = Sell(asset_sym, num_shares)
         orders_list2 = copy.copy(orders_list)
         orders_list2.append(order)
         self.attack(n - 1, network, orders_list2)
     return
示例#18
0
    def test_single_agent(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')

        f1 = AssetFundNetwork.Fund('f1', {'a2': 10}, 100, 1, 1)
        f2 = AssetFundNetwork.Fund('f2', {'a1': 20}, 100, 1, 1)
        mi_calc = MarketImpactCalculator()
        mi_calc.get_updated_price = MagicMock()
        mi_calc.get_updated_price.side_effect = update_price_side_effects
        network = AssetFundNetwork.AssetFundsNetwork(funds={
            'f1': f1,
            'f2': f2
        },
                                                     assets={
                                                         'a1': a1,
                                                         'a2': a2
                                                     },
                                                     mi_calc=mi_calc,
                                                     limit_trade_step=True)

        f1.marginal_call = MagicMock(return_value=False)
        f2.marginal_call = MagicMock()
        f2.marginal_call.side_effect = f1_margin_call_side_effect
        actions_mgr = ActionsManager(network.assets, 0.1, 2)
        result = single_agent(actions_mgr, network, 200)
        print(result.value)
        print(result.actions)
        self.assertEqual(result.value, -1)
        self.assertListEqual(result.actions, [[Sell('a1', 20)], ['MARKET']])
示例#19
0
 def test_get_portfolio_dict(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=100, symbol='a2')
     a3 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a3')
     a4 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a4')
     assets = {'a1': a1, 'a2': a2, 'a3': a3, 'a4': a4}
     actions_mgr = ActionsManager(assets, 0.1)
     attack1 = Attack([Sell('a1', 10)], 10)
     attack2 = Attack([Sell('a1', 10), Sell('a2', 10)], 40)
     attack3 = Attack([Sell('a3', 10)], 10)
     actions_mgr._ActionsManager__get_all_attacks = MagicMock(
         return_value=[attack1, attack2, attack3])
     expected_dict = {10: [attack1, attack3], 40: [attack2]}
     actual_dict = dict(
         actions_mgr._ActionsManager__get_portfolio_dict(assets))
     self.assertDictEqual(expected_dict, actual_dict)
     actions_mgr._ActionsManager__get_all_attacks.assert_called_once_with(
         assets, 4)
示例#20
0
 def test_filter_from_history(self):
     sell_action1 = Attack([Sell('a1', 1), Sell('a2', 1)], 10)
     sell_action2 = Attack([Sell('a1', 1), Sell('a3', 1)], 10)
     buy_action1 = Attack([Buy('a1', 1), Buy('a2', 1)], 10)
     buy_action2 = Attack([Buy('a2', 1)], 10)
     history = {BUY: {'a1': 2}, SELL: {'a1': 1, 'a2': 2}}
     self.assertTrue(
         ActionsManager._ActionsManager__filter_from_history(
             sell_action1, history, SELL))
     self.assertFalse(
         ActionsManager._ActionsManager__filter_from_history(
             sell_action2, history, SELL))
     self.assertTrue(
         ActionsManager._ActionsManager__filter_from_history(
             buy_action1, history, BUY))
     self.assertFalse(
         ActionsManager._ActionsManager__filter_from_history(
             buy_action2, history, BUY))
    def test_2(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
        f1 = MockFund('f1', a1, 1)
        f2 = MockFund('f2', a2, 1)
        network = AssetFundNetwork.AssetFundsNetwork(
            funds={
                'f1': f1,
                'f2': f2
            },
            assets={
                'a1': a1,
                'a2': a2
            },
            mi_calc=MockMarketImpactTestCalculator())

        solver = SingleAgentDynamicProgrammingSolver(network, 3, 1, 1)
        self.assertEqual(solver.results.value, 2)
        self.assertEqual(solver.results.actions[0], Sell('a1', 1))
        self.assertEqual(solver.results.actions[1], Sell('a2', 1))
示例#22
0
 def test_gen_optimal_attacks(self):
     a1 = AssetFundNetwork.Asset(price=10, daily_volume=10, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=20, daily_volume=10, symbol='a2')
     f1_margin_call = lambda assets: assets['a1'].price <= 8
     f2_margin_call = lambda assets: assets['a2'].price <= 19
     f3_margin_call = lambda assets: assets['a2'].price <= 19
     mi_calc = MockMarketImpactTestCalculator({
         'a1': {
             5: 9,
             10: 8
         },
         'a2': {
             5: 19,
             10: 18
         }
     })
     f1 = MockFund('f1', a1, f1_margin_call)
     f2 = MockFund('f2', a2, f2_margin_call)
     f3 = MockFund('f3', a2, f3_margin_call)
     network = AssetFundNetwork.AssetFundsNetwork(funds={
         'f1': f1,
         'f2': f2,
         'f3': f3
     },
                                                  assets={
                                                      'a1': a1,
                                                      'a2': a2
                                                  },
                                                  mi_calc=mi_calc,
                                                  limit_trade_step=False)
     solver = SingleAgentESSolver(network, 0.5, 2)
     actual_solutions = solver.gen_optimal_attacks()
     solution_2 = Solution(network, [Sell('a2', 5)], 2, ['f2', 'f3'], 100)
     solution_3 = Solution(network,
                           [Sell('a1', 10), Sell('a2', 5)], 3,
                           ['f1', 'f2', 'f3'], 200)
     expected_solutions = {1: solution_2, 2: solution_2, 3: solution_3}
     self.assertEqual(expected_solutions, actual_solutions)
示例#23
0
 def gen_liquidation_orders(self, assets: Dict[str, Asset]):
     orders = []
     assets_to_remove = []
     for asset_symbol, num_shares in self.portfolio.items():
         asset = assets[asset_symbol]
         shares_limit = floor(asset.avg_minute_volume * SysConfig.get("MINUTE_VOLUME_LIMIT"))
         shares_to_sell = min(shares_limit, num_shares)
         orders.append(Sell(asset_symbol, shares_to_sell))
         self.portfolio[asset_symbol] -= shares_to_sell
         if self.portfolio[asset_symbol] == 0:
             assets_to_remove.append(asset_symbol)
     for asset_symbol in assets_to_remove:
         self.portfolio.pop(asset_symbol)
     return orders
示例#24
0
    def test_get_portfolios_in_budget_dict(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=200, symbol='a2')
        assets = {'a1': a1, 'a2': a2}
        mgr = ActionsManager(assets, 0.1, attacker_budgets=[5, 10])
        id2portfolios = mgr.get_portfolios()
        actual = mgr.get_portfolios_in_budget_dict()
        expected_attacks_b5 = [Attack([], 0)]
        expected_attacks_b10 = [Attack([], 0), Attack([Sell('a1', 10)], 10)]
        actual_attacks_b5 = [id2portfolios[x] for x in actual[5]]
        actual_attacks_b10 = [id2portfolios[x] for x in actual[10]]

        self.assertListEqual(expected_attacks_b5, actual_attacks_b5)
        self.assertListEqual(expected_attacks_b10, actual_attacks_b10)
 def get_all_attack_portfolios2(self, n, assets, budget, order_set):
     if n == 0:
         return
     order_set.append(
         self.get_all_attack_portfolios(n - 1, assets, budget, order_set))
     asset_sym = self.id_to_sym[n]
     for i in range(1, self.max_order_num + 1):
         asset = assets[asset_sym]
         num_shares = int(
             floor(i * self.min_order_percentage * asset.daily_volume))
         cost = num_shares * asset.zero_time_price
         if cost < budget:
             return
         order = Sell(asset_sym, num_shares)
         prev = self.get_all_attack_portfolios(n - 1, assets, budget - cost,
                                               order_set)
    def test_order_limited_by_parameter(self):
        a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
        a2 = AssetFundNetwork.Asset(price=2, daily_volume=2, symbol='a2')
        f1 = MockFund(symbol='f1', my_asset=a1, margin_ratio=0.9)
        f2 = MockFund(symbol='f2', my_asset=a2, margin_ratio=0.9)
        network = AssetFundNetwork.AssetFundsNetwork(
            funds={
                'f1': f1,
                'f2': f2
            },
            assets={
                'a1': a1,
                'a2': a2
            },
            mi_calc=MockMarketImpactTestCalculator())

        solver = SingleAgentDynamicProgrammingSolver(network, 4, 0.5, 2)
        self.assertEqual(solver.results.value, 1)
        self.assertEqual(solver.results.actions[0], Sell('a2', 2))
示例#27
0
 def test_get_all_attacks(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=100, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=200, symbol='a2')
     a3 = AssetFundNetwork.Asset(price=3, daily_volume=300, symbol='a3')
     assets = {'a1': a1, 'a2': a2, 'a3': a3}
     expected_attacks = [
         Attack([Sell('a1', 10)], 10),
         Attack([Sell('a2', 20)], 40),
         Attack([Sell('a3', 30)], 90),
         Attack([Sell('a1', 10), Buy('a2', 20)], 50),
         Attack([Sell('a1', 10), Buy('a3', 30)], 100),
         Attack([Sell('a2', 20), Buy('a3', 30)], 130),
         Attack(
             [Sell('a1', 10), Sell('a2', 20),
              Buy('a3', 30)], 140),
         Attack([], 0)
     ]
     mgr = ActionsManager(assets, 0.1)
     actual_attacks = mgr._ActionsManager__get_all_attacks(assets, 3)
     actual_attacks.sort(key=lambda a: a.cost)
     expected_attacks.sort(key=lambda a: a.cost)
     self.assertListEqual(actual_attacks, expected_attacks)
    def build_attack(self, n, c, network):
        if n == 0 or c == 0:
            s = Solution(network, [], 0, [], 0)
            self.solutions[n][c] = s
            return s
        asset_sym = self.id_to_sym[n]
        if c in self.solutions[n]:
            return self.solutions[n][c]
        elif self.weights[n] > c:
            s = self.build_attack(n - 1, c, copy.deepcopy(network))
            self.solutions[n][c] = s
            return s
        else:
            max_assets_orders = min(self.max_order_num,
                                    (int)(floor(c / self.weights[n])))
            max_result = self.build_attack(n - 1, c, copy.deepcopy(network))
            for i in range(1, max_assets_orders + 1):
                prev_solution = self.build_attack(n - 1,
                                                  c - i * self.weights[n],
                                                  copy.deepcopy(network))
                num_shares = floor(i * self.min_order_percentage *
                                   network.assets[asset_sym].daily_volume)
                if not num_shares:
                    continue
                order = Sell(asset_sym, num_shares)
                net2 = prev_solution.network
                net2.submit_sell_orders([order])
                net2.clear_order_book()
                funds = net2.get_funds_in_margin_calls()
                value = len(funds)
                cost = prev_solution.cost + order.num_shares * network.assets[
                    order.asset_symbol].zero_time_price
                if value > max_result.value or (value == max_result.value
                                                and cost < max_result.cost):
                    actions = copy.copy(prev_solution.actions)
                    actions.append(order)
                    max_result = Solution(net2, actions, value, funds, cost)

            self.solutions[n][c] = max_result
            return max_result
 def test_reset_books(self):
     a1 = AssetFundNetwork.Asset(price=1, daily_volume=1, symbol='a1')
     a2 = AssetFundNetwork.Asset(price=2, daily_volume=1, symbol='a2')
     f1 = Fund('f1', {'a1': 10}, 100, 1, 1)
     f2 = Fund('f2', {'a2': 10}, 100, 1, 1)
     network = AssetFundNetwork.AssetFundsNetwork(
         funds={
             'f1': f1,
             'f2': f2
         },
         assets={
             'a1': a1,
             'a2': a2
         },
         mi_calc=MockMarketImpactTestCalculator(),
         limit_trade_step=True)
     network.submit_buy_orders([Buy('a1', 2)])
     network.submit_sell_orders([Sell('a1', 2)])
     self.assertTrue(network.sell_orders)
     self.assertTrue(network.buy_orders)
     network.reset_order_books()
     self.assertFalse(network.sell_orders)
     self.assertFalse(network.buy_orders)
    def gen_tree(self, ):
        sell_order = Sell('a1', 50)
        sell = str([sell_order])
        buy = str([Buy('a1', 50)])
        nope = str([])
        buy_actions = [nope, buy]
        root = {
            'tree_size': 8,
            'to_move': CHANCE,
            'actions': ['p1', 'p2'],
            'inf_set': '.',
            'terminal': False
        }
        price_drop_log = "{'a1': '1->0.5'}"
        empty_log = '{}'

        node_1_0 = self.fill_dict(tree_size=6,
                                  to_move=ATTACKER,
                                  actions=[sell],
                                  history_assets_dict={
                                      BUY: {},
                                      SELL: {}
                                  },
                                  players_info=PlayersHiddenInfo(
                                      attacker_attack=[sell_order],
                                      attacker_pid='p2',
                                      defender_budget=50),
                                  actions_history={
                                      BUY: [],
                                      SELL: [],
                                      SIM_TRADE: []
                                  },
                                  inf_set='.p2.A_HISTORY:[]',
                                  terminal=False,
                                  eval=None)

        node_1_0_0 = self.fill_dict(tree_size=5,
                                    to_move=DEFENDER,
                                    actions=buy_actions,
                                    history_assets_dict={
                                        BUY: {},
                                        SELL: {
                                            'a1': 1
                                        }
                                    },
                                    players_info=PlayersHiddenInfo(
                                        attacker_attack=[],
                                        attacker_pid='p2',
                                        defender_budget=50),
                                    actions_history={
                                        BUY: [],
                                        SELL: [sell],
                                        SIM_TRADE: []
                                    },
                                    inf_set='.50.D_HISTORY:[]',
                                    terminal=False,
                                    eval=None)

        node_1_0_0_0 = self.fill_dict(
            tree_size=2,
            to_move=MARKET,
            actions=[empty_log],
            history_assets_dict={
                BUY: {
                    'a1': 1
                },
                SELL: {
                    'a1': 1
                }
            },
            players_info=PlayersHiddenInfo(attacker_attack=[],
                                           attacker_pid='p2',
                                           defender_budget=0),
            actions_history={
                BUY: [buy],
                SELL: [sell],
                SIM_TRADE: []
            },
            inf_set=".MARKET_HISTORY:[].BUY:{'a1': 50}.SELL:{'a1': 50}",
            terminal=False,
            eval=None)

        node_1_0_0_1 = self.fill_dict(
            tree_size=2,
            to_move=MARKET,
            actions=[price_drop_log],
            history_assets_dict={
                BUY: {},
                SELL: {
                    'a1': 1
                }
            },
            players_info=PlayersHiddenInfo(attacker_attack=[],
                                           attacker_pid='p2',
                                           defender_budget=50),
            actions_history={
                BUY: [nope],
                SELL: [sell],
                SIM_TRADE: []
            },
            inf_set=".MARKET_HISTORY:[].BUY:{}.SELL:{'a1': 50}",
            terminal=False,
            eval=None)

        node_1_0_0_0_0 = self.fill_dict(
            tree_size=1,
            terminal=True,
            eval=0,
            to_move=ATTACKER,
            actions=[],
            history_assets_dict={
                BUY: {
                    'a1': 1
                },
                SELL: {
                    'a1': 1
                }
            },
            players_info=PlayersHiddenInfo(attacker_attack=[],
                                           attacker_pid='p2',
                                           defender_budget=0),
            actions_history={
                BUY: [buy, empty_log],
                SELL: [sell, empty_log],
                SIM_TRADE: [empty_log]
            },
            inf_set=".p2.A_HISTORY:['[Sell a1 50]', '{}']")

        node_1_0_0_1_0 = self.fill_dict(
            tree_size=1,
            terminal=True,
            eval=-1,
            to_move=ATTACKER,
            actions=[],
            history_assets_dict={
                BUY: {
                    'a1': 1
                },
                SELL: {
                    'a1': 1
                }
            },
            players_info=PlayersHiddenInfo(attacker_attack=[],
                                           attacker_pid='p2',
                                           defender_budget=50),
            actions_history={
                BUY: [nope, price_drop_log],
                SELL: [sell, price_drop_log],
                SIM_TRADE: [price_drop_log]
            },
            inf_set=".p2.A_HISTORY:['[Sell a1 50]', \"{'a1': '1->0.5'}\"]")

        ###########
        node_1_1 = self.fill_dict(tree_size=1,
                                  terminal=True,
                                  eval=0,
                                  to_move=ATTACKER,
                                  actions=[],
                                  history_assets_dict={
                                      BUY: {},
                                      SELL: {}
                                  },
                                  players_info=PlayersHiddenInfo(
                                      attacker_attack=[],
                                      attacker_pid='p1',
                                      defender_budget=50),
                                  actions_history={
                                      BUY: [],
                                      SELL: [],
                                      SIM_TRADE: []
                                  },
                                  inf_set='.p1.A_HISTORY:[]')

        ##########

        root['children'] = {'p2': node_1_0, 'p1': node_1_1}
        node_1_0['children'] = {sell: node_1_0_0}
        node_1_0_0['children'] = {buy: node_1_0_0_0, nope: node_1_0_0_1}
        node_1_0_0_0['children'] = {empty_log: node_1_0_0_0_0}
        node_1_0_0_1['children'] = {price_drop_log: node_1_0_0_1_0}
        node_1_0_0_0_0['children'] = {}
        node_1_0_0_1_0['children'] = {}
        node_1_1['children'] = {}
        return root