Example #1
0
def risk_managed_order(step: int,
                       side: 'TradeSide',
                       trade_type: 'TradeType',
                       pair: 'TradingPair',
                       price: float,
                       size: float,
                       down_percent: float,
                       up_percent: float,
                       portfolio: 'Portfolio',
                       start: int = None,
                       end: int = None):
    instrument = side.instrument(pair)
    order = Order(step=step,
                  side=side,
                  trade_type=trade_type,
                  pair=pair,
                  price=price,
                  start=start,
                  end=end,
                  quantity=(size * instrument),
                  portfolio=portfolio)

    risk_criteria = Stop("down", down_percent) ^ Stop("up", up_percent)
    risk_management = OrderSpec(side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
                                trade_type=TradeType.MARKET,
                                pair=pair,
                                criteria=risk_criteria)

    order += risk_management

    return order
Example #2
0
def risk_managed_order(step: int,
                       side: 'TradeSide',
                       trade_type: 'TradeType',
                       pair: 'TradingPair',
                       price: float,
                       size: float,
                       down_percent: float,
                       up_percent: float,
                       portfolio: 'Portfolio',
                       ttl_in_seconds: int = None,
                       ttl_in_steps: int = None):
    instrument = pair.base if side == TradeSide.BUY else pair.quote
    order = Order(step=step,
                  side=side,
                  trade_type=trade_type,
                  pair=pair,
                  price=price,
                  ttl_in_seconds=ttl_in_seconds,
                  ttl_in_steps=ttl_in_steps,
                  quantity=(size * instrument),
                  portfolio=portfolio)

    risk_criteria = Stop("down", down_percent) ^ Stop("up", up_percent)
    risk_management = OrderSpec(
        side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
        trade_type=TradeType.MARKET,
        pair=pair,
        criteria=risk_criteria)

    order += risk_management

    return order
Example #3
0
def risk_managed_order(step: int,
                       side: 'TradeSide',
                       trade_type: 'TradeType',
                       exchange_pair: 'ExchangePair',
                       price: float,
                       quantity: 'Quantity',
                       down_percent: float,
                       up_percent: float,
                       portfolio: 'Portfolio',
                       start: int = None,
                       end: int = None):
    order = Order(step=step,
                  side=side,
                  trade_type=trade_type,
                  exchange_pair=exchange_pair,
                  price=price,
                  start=start,
                  end=end,
                  quantity=quantity,
                  portfolio=portfolio)

    risk_criteria = Stop("down", down_percent) ^ Stop("up", up_percent)
    risk_management = OrderSpec(
        side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
        trade_type=TradeType.MARKET,
        exchange_pair=exchange_pair,
        criteria=risk_criteria)

    order += risk_management

    return order
Example #4
0
def risk_managed_order(side: 'TradeSide',
                       trade_type: 'TradeType',
                       pair: 'TradingPair',
                       price: float,
                       size: float,
                       down_percent: float,
                       up_percent: float,
                       portfolio: 'Portfolio'):

    order = Order(side=side,
                  trade_type=trade_type,
                  pair=pair,
                  price=price,
                  quantity=(size * pair.base),
                  portfolio=portfolio)

    risk_criteria = Stop("down", down_percent) ^ Stop("up", up_percent)

    risk_management = OrderSpec(side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
                                trade_type=TradeType.MARKET,
                                pair=pair,
                                criteria=risk_criteria)

    order += risk_management

    return order
Example #5
0
def test_is_executable_on(mock_portfolio_class, mock_exchange_class):

    exchange = mock_exchange_class.return_value
    exchange.name = "coinbase"
    portfolio = mock_portfolio_class.return_value

    # Market order
    order = Order(step=0,
                  exchange_name="coinbase",
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  pair=USD/BTC,
                  quantity=5000.00 * USD,
                  portfolio=portfolio,
                  price=7000.00)

    exchange.quote_price = mock.Mock(return_value=6800.00)
    assert order.is_executable_on(exchange)

    exchange.quote_price = mock.Mock(return_value=7200.00)
    assert order.is_executable_on(exchange)

    # Limit order
    order = Order(step=0,
                  exchange_name="coinbase",
                  side=TradeSide.BUY,
                  trade_type=TradeType.LIMIT,
                  pair=USD/BTC,
                  quantity=5000.00 * USD,
                  portfolio=portfolio,
                  price=7000.00)

    exchange.quote_price = mock.Mock(return_value=6800.00)
    assert order.is_executable_on(exchange)

    exchange.quote_price = mock.Mock(return_value=7200.00)
    assert order.is_executable_on(exchange)

    # Stop Order
    order = Order(step=0,
                  exchange_name="coinbase",
                  side=TradeSide.SELL,
                  trade_type=TradeType.LIMIT,
                  pair=USD/BTC,
                  quantity=5000.00 * USD,
                  portfolio=portfolio,
                  price=7000.00,
                  criteria=Stop("down", 0.03))

    exchange.quote_price = mock.Mock(return_value=(1 - 0.031)*order.price)
    assert order.is_executable_on(exchange)

    exchange.quote_price = mock.Mock(return_value=(1 - 0.02) * order.price)
    assert not order.is_executable_on(exchange)
Example #6
0
def test_or(mock_order_class, mock_exchange_class):

    # Test Initialization
    criteria = Stop("down", 0.03) | Stop("up", 0.03)
    assert criteria
    assert isinstance(criteria, Criteria)

    order = mock_order_class.return_value
    order.pair = USD / BTC
    order.price = 7000.00

    exchange = mock_exchange_class.return_value

    # Test (stop=True, stop=False) ===> True
    # Greater than 3.00% below order price
    exchange.quote_price.return_value = 0.95 * order.price
    assert criteria(order, exchange)

    # Equal to 3.00% below order price
    exchange.quote_price.return_value = 0.969 * order.price
    assert criteria(order, exchange)

    # Test (stop=False, stop=False) ===> False
    # Less than 3.00% below order price
    exchange.quote_price.return_value = 0.98 * order.price
    assert not criteria(order, exchange)

    # Less than 3.00% above order price
    exchange.quote_price.return_value = 1.02 * order.price
    assert not criteria(order, exchange)

    # Test (stop=False, stop=True) ===> True
    # Equal to 3.00% above order price
    exchange.quote_price.return_value = 1.031 * order.price
    assert criteria(order, exchange)

    # Greater than 3.00% above order price
    exchange.quote_price.return_value = 1.05 * order.price
    assert criteria(order, exchange)
Example #7
0
def test_call_with_direction_up(mock_order_class, mock_exchange_class):

    exchange = mock_exchange_class.return_value

    order = mock_order_class.return_value
    order.pair = USD / BTC
    order.price = 7000.00

    criteria = Stop(direction=StopDirection.UP, percent=0.03)

    # Less than 3.00% above order price
    exchange.quote_price.return_value = 1.02 * order.price
    assert not criteria(order, exchange)

    # Equal to 3.00% above order price
    exchange.quote_price.return_value = 1.031 * order.price
    assert criteria(order, exchange)

    # Greater than 3.00% above order price
    exchange.quote_price.return_value = 1.05 * order.price
    assert criteria(order, exchange)
Example #8
0
def test_call_with_direction_down(mock_order_class, mock_exchange_class):

    exchange = mock_exchange_class.return_value

    order = mock_order_class.return_value
    order.pair = USD / BTC
    order.price = 7000.00

    criteria = Stop(direction=StopDirection.DOWN, percent=0.03)

    # Greater than 3.00% below order price
    exchange.quote_price.return_value = 0.95 * order.price
    assert criteria(order, exchange)

    # Equal to 3.00% below order price
    exchange.quote_price.return_value = 0.969 * order.price
    assert criteria(order, exchange)

    # Less than 3.00% below order price
    exchange.quote_price.return_value = 0.98 * order.price
    assert not criteria(order, exchange)
Example #9
0
def test_is_executable_on(mock_exchange_class):

    exchange = mock_exchange_class.return_value
    exchange.options = ExchangeOptions()
    exchange.id = "fake_exchange_id"
    exchange.name = "coinbase"
    exchange.clock = mock.Mock()
    exchange.clock.step = 0

    # Market order
    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)
    order = Order(step=0,
                  exchange_pair=ExchangePair(exchange, USD / BTC),
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  quantity=5000.00 * USD,
                  portfolio=portfolio,
                  price=Decimal(7000.00))

    exchange.quote_price = mock.Mock(return_value=Decimal(6800.00))
    assert order.is_executable()

    exchange.quote_price = mock.Mock(return_value=Decimal(7200.00))
    assert order.is_executable()

    # Limit order
    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)
    order = Order(step=0,
                  exchange_pair=ExchangePair(exchange, USD / BTC),
                  side=TradeSide.BUY,
                  trade_type=TradeType.LIMIT,
                  quantity=5000.00 * USD,
                  portfolio=portfolio,
                  price=Decimal(7000.00))

    exchange.quote_price = mock.Mock(return_value=Decimal(6800.00))
    assert order.is_executable()

    exchange.quote_price = mock.Mock(return_value=Decimal(7200.00))
    assert order.is_executable()

    # Stop Order
    wallets = [Wallet(exchange, 0 * USD), Wallet(exchange, 2 * BTC)]
    portfolio = Portfolio(USD, wallets)
    order = Order(step=0,
                  exchange_pair=ExchangePair(exchange, USD / BTC),
                  side=TradeSide.SELL,
                  trade_type=TradeType.LIMIT,
                  quantity=1 * BTC,
                  portfolio=portfolio,
                  price=Decimal(7000.00),
                  criteria=Stop("down", 0.03))

    exchange.quote_price = mock.Mock(return_value=Decimal(1 - 0.031) *
                                     order.price)
    assert order.is_executable()

    exchange.quote_price = mock.Mock(return_value=Decimal(1 - 0.02) *
                                     order.price)
    assert not order.is_executable()
Example #10
0
def test_complete_complex_order(mock_trade_class, mock_exchange_class):
    exchange = mock_exchange_class.return_value
    exchange.options = ExchangeOptions()
    exchange.id = "fake_exchange_id"
    exchange.name = "coinbase"
    exchange.clock = mock.Mock()
    exchange.clock.step = 0
    exchange.quote_price = mock.Mock(return_value=Decimal(7000.00))

    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)

    side = TradeSide.BUY

    order = Order(step=0,
                  exchange_pair=ExchangePair(exchange, USD / BTC),
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  quantity=5200.00 * USD,
                  portfolio=portfolio,
                  price=Decimal(7000.00))

    risk_criteria = Stop("down", 0.03) ^ Stop("up", 0.02)

    risk_management = OrderSpec(
        side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
        trade_type=TradeType.MARKET,
        exchange_pair=ExchangePair(exchange, USD / BTC),
        criteria=risk_criteria)

    order += risk_management

    order.execute()

    # Execute fake trade
    price = Decimal(7010.00)
    scale = order.price / price
    commission = 3.00 * USD

    base_size = scale * order.size - commission.size

    trade = mock_trade_class.return_value
    trade.size = Decimal(base_size)
    trade.quantity = base_size * USD
    trade.price = price
    trade.commission = commission

    base_wallet = portfolio.get_wallet(exchange.id, USD)
    quote_wallet = portfolio.get_wallet(exchange.id, BTC)

    base_size = trade.size + trade.commission.size
    quote_size = (order.price / trade.price) * (trade.size / trade.price)

    base_wallet.withdraw(quantity=Quantity(USD,
                                           size=base_size,
                                           path_id=order.path_id),
                         reason="test")
    quote_wallet.deposit(quantity=Quantity(BTC,
                                           size=quote_size,
                                           path_id=order.path_id),
                         reason="test")

    # Fill fake trade
    order.fill(trade)

    assert order.path_id in portfolio.get_wallet(exchange.id, USD).locked

    assert order.status == OrderStatus.PARTIALLY_FILLED
    next_order = order.complete()
    assert order.status == OrderStatus.FILLED

    assert next_order
    assert next_order.path_id == order.path_id
    assert next_order.size
    assert next_order.status == OrderStatus.PENDING
    assert next_order.side == TradeSide.SELL
    assert next_order.exchange_pair == ExchangePair(exchange, USD / BTC)
Example #11
0
def test_on_fill_with_complex_order(mock_trade_class, mock_exchange_class):

    exchange = mock_exchange_class.return_value
    exchange.options.max_trade_size = 1e6
    exchange.id = "fake_exchange_id"
    exchange.name = "coinbase"
    exchange.quote_price = lambda pair: Decimal(7000.00)

    broker = Broker()
    broker.exchanges = [exchange]

    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)

    side = TradeSide.BUY

    order = Order(step=0,
                  exchange_pair=ExchangePair(exchange, USD / BTC),
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  quantity=5200.00 * USD,
                  portfolio=portfolio,
                  price=Decimal(7000.00))

    risk_criteria = Stop("down", 0.03) ^ Stop("up", 0.02)

    risk_management = OrderSpec(
        side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
        trade_type=TradeType.MARKET,
        exchange_pair=ExchangePair(exchange, USD / BTC),
        criteria=risk_criteria)

    order += risk_management

    order.attach(broker)
    order.execute()

    broker._executed[order.id] = order

    # Execute fake trade
    price = Decimal(7000.00)
    scale = order.price / price
    commission = 3.00 * USD

    base_size = scale * order.size - commission.size

    trade = mock_trade_class.return_value
    trade.order_id = order.id
    trade.size = base_size
    trade.quantity = base_size * USD
    trade.price = price
    trade.commission = commission

    base_wallet = portfolio.get_wallet(exchange.id, USD)
    quote_wallet = portfolio.get_wallet(exchange.id, BTC)

    base_size = trade.size + trade.commission.size
    quote_size = (order.price / trade.price) * (trade.size / trade.price)

    base_wallet.withdraw(quantity=Quantity(USD,
                                           size=base_size,
                                           path_id=order.path_id),
                         reason="test")
    quote_wallet.deposit(quantity=Quantity(BTC,
                                           size=quote_size,
                                           path_id=order.path_id),
                         reason="test")

    assert trade.order_id in broker.executed.keys()
    assert trade not in broker.trades
    assert broker.unexecuted == []

    order.fill(trade)

    assert order.remaining == 0
    assert trade in broker.trades[order.id]
    assert broker.unexecuted != []
Example #12
0
def test_complete_complex_order(mock_trade_class,
                                mock_exchange_class):

    exchange = mock_exchange_class.return_value
    exchange.id = "fake_exchange_id"

    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)

    side = TradeSide.BUY

    order = Order(step=0,
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  pair=USD / BTC,
                  quantity=5200.00 * USD,
                  portfolio=portfolio,
                  price=7000.00)

    risk_criteria = Stop("down", 0.03) ^ Stop("up", 0.02)

    risk_management = OrderSpec(side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
                                trade_type=TradeType.MARKET,
                                pair=USD / BTC,
                                criteria=risk_criteria)

    order += risk_management

    order.execute(exchange)

    # Execute fake trade
    price = 7010.00
    scale = order.price / price
    commission = 3.00 * USD

    base_size = scale * order.size - commission.size

    trade = mock_trade_class.return_value
    trade.size = base_size
    trade.price = price
    trade.commission = commission

    base_wallet = portfolio.get_wallet(exchange.id, USD)
    quote_wallet = portfolio.get_wallet(exchange.id, BTC)

    base_size = trade.size + trade.commission.size
    quote_size = (order.price / trade.price) * (trade.size / trade.price)

    base_wallet -= Quantity(USD, size=base_size, path_id=order.path_id)
    quote_wallet += Quantity(BTC, size=quote_size, path_id=order.path_id)

    # Fill fake trade
    order.fill(exchange, trade)

    assert order.path_id in portfolio.get_wallet(exchange.id, USD).locked

    assert order.status == OrderStatus.PARTIALLY_FILLED
    next_order = order.complete(exchange)
    assert order.status == OrderStatus.FILLED

    assert next_order
    assert next_order.path_id == order.path_id
    assert next_order.size
    assert next_order.status == OrderStatus.PENDING
    assert next_order.side == TradeSide.SELL
    assert next_order.pair == USD/BTC
Example #13
0
def test_on_fill_with_complex_order(mock_trade_class, mock_exchange_class):

    exchange = mock_exchange_class.return_value
    exchange.id = "fake_exchange_id"

    broker = Broker(exchange)

    wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]
    portfolio = Portfolio(USD, wallets)

    side = TradeSide.BUY

    order = Order(step=0,
                  side=TradeSide.BUY,
                  trade_type=TradeType.MARKET,
                  pair=USD / BTC,
                  quantity=5200.00 * USD,
                  portfolio=portfolio,
                  price=7000.00)

    risk_criteria = Stop("down", 0.03) ^ Stop("up", 0.02)

    risk_management = OrderSpec(
        side=TradeSide.SELL if side == TradeSide.BUY else TradeSide.BUY,
        trade_type=TradeType.MARKET,
        pair=USD / BTC,
        criteria=risk_criteria)

    order += risk_management

    order.attach(broker)
    order.execute(exchange)

    broker._executed[order.id] = order

    # Execute fake trade
    price = 7000.00
    scale = order.price / price
    commission = 3.00 * USD

    base_size = scale * order.size - commission.size

    trade = mock_trade_class.return_value
    trade.order_id = order.id
    trade.size = base_size
    trade.price = price
    trade.commission = commission

    base_wallet = portfolio.get_wallet(exchange.id, USD)
    quote_wallet = portfolio.get_wallet(exchange.id, BTC)

    base_size = trade.size + trade.commission.size
    quote_size = (order.price / trade.price) * (trade.size / trade.price)

    base_wallet -= Quantity(USD, size=base_size, path_id=order.path_id)
    quote_wallet += Quantity(BTC, size=quote_size, path_id=order.path_id)

    assert trade.order_id in broker.executed.keys()
    assert trade not in broker.trades
    assert broker.unexecuted == []

    order.fill(exchange, trade)

    assert order.remaining_size == 0
    assert trade in broker.trades[order.id]
    assert broker.unexecuted != []
Example #14
0
def test_str():
    criteria = Stop(direction=StopDirection.UP, percent=0.3)
    assert str(criteria) == "<Stop: direction=up, percent=0.3>"
Example #15
0
def test_init():

    criteria = Stop(direction=StopDirection.UP, percent=0.3)
    assert criteria.direction == StopDirection.UP
    assert criteria.percent == 0.3