Ejemplo n.º 1
0
def submit_sell(stock, context, data):
    if get_open_orders(stock):
        return

    # We bought a stock but don't know it's age yet
    if stock not in context.age:
        context.age[stock] = 0

    # Don't sell stuff that's less than 1 day old
    if stock in context.age and context.age[stock] < 1:
        return

    shares = context.portfolio.positions[stock].amount
    current_price = float(data.current([stock], 'price'))
    cost_basis = float(context.portfolio.positions[stock].cost_basis)

    if (context.age[stock] >= context.MyFireSaleAge
            and (current_price < context.MyFireSalePrice
                 or current_price < cost_basis)):
        log.info("%s is in fire sale!" % stock.symbol)
        sell_price = float(make_div_by_05(.95 * current_price, buy=False))

        order(stock, -shares, style=LimitOrder(sell_price))
    else:
        sell_price = float(
            make_div_by_05(cost_basis * context.sell_factor, buy=False))

        order(stock, -shares, style=LimitOrder(sell_price))
Ejemplo n.º 2
0
def my_rebalance(context, data):
    log.info("my_rebalance")
    BuyFactor = .99
    SellFactor = 1.01
    cash = context.portfolio.cash
    log.info(cash)
    cancel_open_buy_orders(context, data)

    # Order sell at profit target in hope that somebody actually buys it
    for stock in context.portfolio.positions:
        if not get_open_orders(stock):
            StockShares = context.portfolio.positions[stock].amount
            CurrPrice = float(data.current([stock], 'price'))
            CostBasis = float(context.portfolio.positions[stock].cost_basis)
            SellPrice = float(make_div_by_05(CostBasis * SellFactor,
                                             buy=False))

            if np.isnan(SellPrice):
                pass  # probably best to wait until nan goes away
            elif (stock in context.age and context.age[stock] == 1):
                pass
            elif (stock in context.age
                  and context.MyFireSaleAge <= context.age[stock]
                  and (context.MyFireSalePrice > CurrPrice
                       or CostBasis > CurrPrice)):
                if (stock in context.age and context.age[stock] < 2):
                    pass
                elif stock not in context.age:
                    context.age[stock] = 1
                else:
                    SellPrice = float(
                        make_div_by_05(.95 * CurrPrice, buy=False))
                    order(stock, -StockShares, style=LimitOrder(SellPrice))
            else:
                if (stock in context.age and context.age[stock] < 2):
                    pass
                elif stock not in context.age:
                    context.age[stock] = 1
                else:

                    order(stock, -StockShares, style=LimitOrder(SellPrice))

    WeightThisBuyOrder = float(1.00 / context.MaxBuyOrdersAtOnce)
    for ThisBuyOrder in range(context.MaxBuyOrdersAtOnce):
        stock = next(context.MyCandidate)
        PH = data.history([stock], 'price', 20, '1d')
        PH_Avg = float(PH.mean())
        CurrPrice = float(data.current([stock], 'price'))
        if np.isnan(CurrPrice):
            pass  # probably best to wait until nan goes away
        else:
            if CurrPrice > float(1.25 * PH_Avg):
                BuyPrice = float(CurrPrice)
            else:
                BuyPrice = float(CurrPrice * BuyFactor)
            BuyPrice = float(make_div_by_05(BuyPrice, buy=True))
            StockShares = int(WeightThisBuyOrder * cash / BuyPrice)
            order(stock, StockShares, style=LimitOrder(BuyPrice))
Ejemplo n.º 3
0
def my_rebalance(context, data):
    BuyFactor = .99
    SellFactor = 1.01
    cash = context.portfolio.cash

    cancel_open_buy_orders(context, data)
    log.info("My Rebalance.")

    # Order sell at profit target in hope that somebody actually buys it
    open_orders = get_open_orders()
    for stock in context.portfolio.positions:
        print(stock.sid)
        print(get_open_orders(stock.sid))
        if stock in open_orders:
            pass
        else:
            print("no orders")
            StockShares = context.portfolio.positions[stock].amount
            CurrPrice = float(data.current([stock], 'price'))
            CostBasis = float(context.portfolio.positions[stock].cost_basis)
            SellPrice = float(make_div_by_05(CostBasis * SellFactor,
                                             buy=False))

            if np.isnan(SellPrice):
                log.info("My Rebalance: NaN")
                pass  # probably best to wait until nan goes away
            elif (stock in context.age and context.age[stock] == 0):
                log.info("My Rebalance: Age")
                pass
            elif (stock in context.age
                  and context.MyFireSaleAge <= context.age[stock]
                  and (context.MyFireSalePrice > CurrPrice
                       or CostBasis > CurrPrice)):
                log.info("My Rebalance: Losing")
                if (stock in context.age and context.age[stock] < 2):
                    pass
                elif stock not in context.age:
                    context.age[stock] = 1
                else:
                    SellPrice = float(
                        make_div_by_05(.95 * CurrPrice, buy=False))
                    order(stock, -StockShares, style=LimitOrder(SellPrice))
            else:
                if (stock in context.age and context.age[stock] < 1):
                    log.info("My Rebalance: too young")
                    pass
                elif stock not in context.age:
                    log.info("My Rebalance: no age")
                    context.age[stock] = 1
                else:
                    log.info("My Rebalance: Place order")
                    order(stock, -StockShares, style=LimitOrder(SellPrice))
Ejemplo n.º 4
0
def my_rebalance(context, data):
    BuyFactor = .99
    SellFactor = 1.1
    cash = context.portfolio.cash
    cancel_open_buy_orders(context, data)
    
    log.info("My Rebalance: ") 
    WeightThisBuyOrder = float(1.00 / context.MaxBuyOrdersAtOnce)
    
    
    
    
    for ThisBuyOrder in range(context.MaxBuyOrdersAtOnce):
        stock = next(context.MyCandidate)
        PH = data.history([stock], 'price', 20, '1d')
        PH_Avg = float(PH.mean())
        CurrPrice = float(data.current([stock], 'price'))
        if np.isnan(CurrPrice):
            pass  # probably best to wait until nan goes away
        else:
            if CurrPrice > float(1.25 * PH_Avg):
                BuyPrice = float(CurrPrice)
            else:
                BuyPrice = float(CurrPrice * BuyFactor)
            BuyPrice = float(make_div_by_05(BuyPrice, buy=True))
            StockShares = int(WeightThisBuyOrder * cash / BuyPrice)
            order(stock, StockShares,
                  style=LimitOrder(BuyPrice)
                  )
    
    place_sells(context,data)   
def buy(context, data):
    cash_accum = 0
    for security in context.candidates:
        if security not in context.portfolio.positions and data.can_trade(security):
            if len(context.portfolio.positions) < 10:
                price_share = data.current(security, 'close')
                cost = get_cost(context.my_output.get_value(security, 'atr'), context.portfolio.portfolio_value, price_share)
                if cost < (context.portfolio.cash - cash_accum) and is_trade(context, data):
                    order_value(security, cost, style=LimitOrder(limit_price=price_share))
                    context.tmp_tracker[security.symbol] = context.my_output.get_value(security, 'atr')
                    cash_accum = cash_accum + cost
Ejemplo n.º 6
0
def rebalance(context, data):
    """Rebalance the portfolio based on context.stocks"""

    cancel_all_orders(context, data)
    sell_stocks_not_in_portfolio(context, data)

    LOG.info("rebalancing")
    LOG.info(context.stocks)
    totals = calculate_totals(context, data)
    LOG.info("totals calculated: %s" % totals)
    for stock, info in totals.items():
        order(stock, info["total"], style=LimitOrder(info["price"]))
Ejemplo n.º 7
0
def enter_sells(context, data):

    # get the current prices and calculate order values and shares
    update_stock_data(context, context.output, data)

    # If order shares is negative (ie a sell) and value is greater than our min adjust threshold
    rules = 'order_shares < 0 and order_value > @MIN_ADJUST_AMT'
    sells = context.output.query(rules).index.tolist()

    for stock in sells:
        order_id = order(stock,
              context.output.get_value(stock, 'order_shares'),
              style=LimitOrder(context.output.get_value(stock, 'latest_price'))
              )
        # store the order id in case we need to retry the order
        context.todays_orders.append(order_id)
Ejemplo n.º 8
0
def enter_buys(context, data):

    # get the current prices and calculate order values and shares
    update_stock_data(context, context.output, data)
    adjust_buy_orders_per_available_cash(context, data)

    # Order shares is positive (ie a buy) and value greater than our min adjust threshold
    rules = 'order_shares > 0 and order_value > @MIN_ADJUST_AMT'
    buys = context.output.query(rules).index.tolist()

    for stock in buys:
        order_id = order(stock,
              context.output.get_value(stock, 'order_shares'),
              style=LimitOrder(context.output.get_value(stock, 'latest_price'))
              )
        # store the order id in case we need to retry the order
        context.todays_orders.append(order_id)
Ejemplo n.º 9
0
    def __convert_order_params_for_blotter(limit_price, stop_price, style):
        """
        Helper method for converting deprecated limit_price and stop_price
        arguments into ExecutionStyle instances.

        This function assumes that either style == None or (limit_price,
        stop_price) == (None, None).
        """
        if style:
            assert (limit_price, stop_price) == (None, None)
            return style
        if limit_price and stop_price:
            return StopLimitOrder(limit_price, stop_price)
        if limit_price:
            return LimitOrder(limit_price)
        if stop_price:
            return StopOrder(stop_price)
        else:
            return MarketOrder()
Ejemplo n.º 10
0
def retry_cancelled_order(context, data):

    '''
    Every once in awhile Robinhood orders get mysteriously cancelled. This checks the order status
    and re-submits any cancelled orders.
    '''
    for order_id in context.todays_orders[:]:
        original_order = get_order(order_id)
        if original_order and original_order.status == 2 :
            # The order was somehow cancelled so retry
            retry_id = order(
                original_order.sid,
                original_order.amount,
                style=LimitOrder(original_order.limit)
                )

            log.info('order for %i shares of %s cancelled - retrying'
                         % (original_order.amount, original_order.sid))

            # Remove the original order (typically can't do but note the [:]) and store the new order
            context.todays_orders.remove(original_order)
            context.todays_orders.append(retry_id)
Ejemplo n.º 11
0
def submit_buy(stock, context, data, weight):
    cash = min(
        investment_limits(context)['remaining_to_invest'],
        context.portfolio.cash)

    price_history = data.history([stock], 'price', 20, '1d')
    average_price = float(price_history.mean())
    current_price = float(data.current([stock], 'price'))

    if np.isnan(current_price):
        pass  # probably best to wait until nan goes away
    else:
        if current_price > float(
                1.25 * average_price):  # if the price is 25% above the 20d avg
            buy_price = float(current_price)
        else:  # Otherwise buy at a discount
            buy_price = float(current_price * context.buy_factor)
        buy_price = float(make_div_by_05(buy_price, buy=True))
        shares_to_buy = int(weight * cash / buy_price)
        max_exposure = int(weight * context.portfolio.portfolio_value /
                           buy_price)

        # Prevent over exposing to a particular stock, never own more than 1/max_buy_orders
        # of our account value
        positions = context.portfolio.positions
        if stock in positions and positions[stock].amount >= max_exposure:
            return

        # This cancels open sales that would prevent these buys from being submitted if running
        # up against the PDT rule
        open_orders = get_open_orders()
        if stock in open_orders:
            for open_order in open_orders[stock]:
                cancel_order(open_order)

        order(stock, shares_to_buy, style=LimitOrder(buy_price))
Ejemplo n.º 12
0
def test_orders():
    backend = alpaca.Backend('key-id', 'secret-key')
    with patch.object(backend, '_api') as _api:
        _api.list_assets.return_value = [
            Asset({
                'id': 'bcfdb21a-760c-44a6-a3af-6264851b5c1b',
                'asset_class': 'us_equity',
                'exchange': 'NYSE',
                'symbol': 'X',
                'status': 'inactive',
                'tradable': True
            }),
            Asset({
                'id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'asset_class': 'us_equity',
                'exchange': 'NASDAQ',
                'symbol': 'AAPL',
                'status': 'active',
                'tradable': True
            }),
            Asset({
                'id': '8688f60a-04c9-4740-8468-c0b994499f41',
                'asset_class': 'us_equity',
                'exchange': 'NYSE',
                'symbol': 'BAC',
                'status': 'active',
                'tradable': True
            }),
        ]

        res = backend._symbols2assets(['AAPL'])
        assert len(res) == 1

        _api.get_account.return_value = Account({
            'account_blocked': False,
            'buying_power': '43.38',
            'cash': '35036.18',
            'cash_withdrawable': '43.38',
            'created_at': '2018-08-27T18:33:56.812574Z',
            'currency': 'USD',
            'id': 'da66e4e6-db7e-4c2e-83ae-2e0cce995cf2',
            'pattern_day_trader': False,
            'portfolio_value': '49723.85',
            'status': 'ACTIVE',
            'trading_blocked': False,
            'transfers_blocked': False
        })
        res = backend.account
        assert res.buying_power < 100

        _api.list_positions.return_value = [
            Position({
                'asset_class': 'us_equity',
                'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'avg_entry_price': '198',
                'change_today': '0',
                'cost_basis': '200',
                'current_price': '200',
                'exchange': 'NASDAQ',
                'lastday_price': '200',
                'market_value': '200',
                'qty': '1',
                'side': 'long',
                'symbol': 'AAPL',
                'unrealized_intraday_pl': '0',
                'unrealized_intraday_plpc': '0',
                'unrealized_pl': '2',
                'unrealized_plpc': '0.01111'
            }),
        ]

        algo = Mock()
        algo._backend = backend
        algo.symbol = lambda x: backend._symbols2assets([x])[0]
        with LiveTraderAPI(algo):
            res = backend.portfolio
            assert res.cash > 30e3
            assert len(res.positions) == 1

            _api.list_orders.return_value = [
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_open',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': None,
                    'filled_at': None,
                    'filled_avg_price': None,
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_failed',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': '2018-08-29T13:31:02.779465Z',
                    'filled_at': None,
                    'filled_avg_price': None,
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
                Order({
                    'asset_class': 'us_equity',
                    'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                    'canceled_at': None,
                    'client_order_id': 'my_id_filled',
                    'created_at': '2018-08-29T13:31:02.779465Z',
                    'expired_at': None,
                    'failed_at': None,
                    'filled_at': '2018-08-29T13:31:02.779465Z',
                    'filled_avg_price': '200',
                    'filled_qty': '0',
                    'id': '6abca255-bc5a-4688-a547-4bfd2c33a979',
                    'limit_price': '1.3',
                    'order_type': 'limit',
                    'qty': '3846',
                    'side': 'buy',
                    'status': 'new',
                    'stop_price': None,
                    'submitted_at': '2018-08-29T13:31:02.779394Z',
                    'symbol': 'AAPL',
                    'time_in_force': 'day',
                    'type': 'limit',
                    'updated_at': '2018-08-30T19:59:00.737786Z'
                }),
            ]
            res = backend.orders
            # make sure order status is set correctly
            assert res['my_id_open']._status == ZP_ORDER_STATUS.OPEN
            assert res['my_id_failed']._status == ZP_ORDER_STATUS.REJECTED
            assert res['my_id_filled']._status == ZP_ORDER_STATUS.FILLED

            _api.submit_order.return_value = Order({
                'asset_class':
                'us_equity',
                'asset_id':
                '93f58d0b-6c53-432d-b8ce-2bad264dbd94',
                'canceled_at':
                None,
                'client_order_id':
                '439dca01703b4674a61a72713a612d24',
                'created_at':
                '2018-08-29T13:31:01.710698Z',
                'expired_at':
                None,
                'failed_at':
                None,
                'filled_at':
                None,
                'filled_avg_price':
                None,
                'filled_qty':
                '0',
                'id':
                '2c366657-fdbd-4554-a14d-b19df2bf430c',
                'limit_price':
                '2.05',
                'order_type':
                'limit',
                'qty':
                '1',
                'side':
                'buy',
                'status':
                'new',
                'stop_price':
                None,
                'submitted_at':
                '2018-08-29T13:31:01.710651Z',
                'symbol':
                'AAPL',
                'time_in_force':
                'day',
                'type':
                'limit',
                'updated_at':
                '2018-08-30T19:59:00.553942Z'
            })

            aapl = algo.symbol('AAPL')
            # this response is not correct logically, but fine for testing
            res = backend.order(aapl, 1, MarketOrder())
            assert res.limit > 1
            # different order types should go through
            backend.order(aapl, 1, LimitOrder(limit_price=100))
            backend.order(aapl, 1, StopOrder(stop_price=200))
            backend.order(aapl, 1,
                          StopLimitOrder(limit_price=100, stop_price=200))

            backend.cancel_order('some-id')

            # order submission fail
            _api.submit_order.side_effect = APIError({'message': 'test'})
            res = backend.order(aapl, -1, MarketOrder())
            assert res is None
Ejemplo n.º 13
0
def place_sells(context, data):
    SellFactor = 1.1
    cash = context.portfolio.cash
    open_orders = get_open_orders()    
    place_sell_orders = 1
    
    # exit if we have open sell orders
    if len(open_orders) != 0:
        for stock, orders in open_orders.items():
            for o in orders:
                if 0 > o.amount:  # it is a sell order
                    place_sell_orders = 0

    if place_sell_orders == 1:
        log.info("Place sells") 
        # Order sell at profit target in hope that somebody actually buys it
        for stock in context.portfolio.positions:                  
            if stock in open_orders:
                pass
            else:
                StockShares = context.portfolio.positions[stock].amount
                CurrPrice = float(data.current([stock], 'price'))
                CostBasis = float(context.portfolio.positions[stock].cost_basis)
                SellPrice = float(
                    make_div_by_05(
                        CostBasis *
                        SellFactor,
                        buy=False))            
                print(stock)      
                print(StockShares)  


                if np.isnan(SellPrice):
                    pass  # probably best to wait until nan goes away
                elif (stock in context.age and context.age[stock] < 1):
                    print("age < 1.0")
                    pass
                elif (
                    stock in context.age
                    and context.MyFireSaleAge <= context.age[stock]
                    and (
                        context.MyFireSalePrice > CurrPrice
                        or CostBasis > CurrPrice
                    )
                ):
                    if (stock in context.age and context.age[stock] < 1):
                        print("age < 1.1")
                        pass
                    elif stock not in context.age:
                        print("age = 1")                                        
                        context.age[stock] = 1
                    else:
                        print("sell loss")
                        SellPrice = float(
                            make_div_by_05(.95 * CurrPrice, buy=False))
                        order(stock, -StockShares,
                              style=LimitOrder(SellPrice)
                              )
                else:
                    if (stock in context.age and context.age[stock] < 1):
                        print("age < 1")
                        pass
                    elif stock not in context.age:
                        print("age = 0")
                        context.age[stock] = 1
                    else:
                        print("sell win")
                        order(stock, -StockShares,
                              style=LimitOrder(SellPrice)
                              )