0

I'm building a trading bot that looks through a df of prices and sells, buys, or passes depending on the price relative to the bounds. Every transaction uses all funds available, so the other constraint is that you must have the stock in the bank to execute a sale and vice versa. Finally I want to add the relevant trade details to a log when trades occur. This is intuitive with iterrows, but is there a more efficient way to do this? Particularly I'm struggling to track the two banks and update them after transactions so future transactions only occur when we have the right denomination (assume df is sorted by date ascending). Here is a snippet of the working but slow iterrows version.

stock_bank = 1000
usd_bank = 0
trade_log = pd.DataFrame()
prices = pd.DataFrame({'buy_price': [9, 11, 12, 13, 12],
                       'sell_price': [10, 10, 11, 12, 12],
                       'lower_bound': [10, 11, 11, 10, 9],
                       'upper_bound': [12, 13, 13, 12, 11]})

for (i, row) in prices.iterrows():
    # Sell stock if own stock and sell price above upper bound
    if row['sell_price'] > row['upper_bound'] and stock_bank != 0:
        usd_bank = stock_bank * (row['sell_price'])
        stock_bank = 0
        # trade_entry = (relevant trade details)
        # trade_log = trades.append(trade_entry)

    # Repeat for Buys
    # Buy stock if have USD and buy price below lower bound
    # etc
DustinB
  • 13
  • 2
  • 3
    Does this answer your question? [Faster alternative to iterrows](https://stackoverflow.com/questions/51149735/faster-alternative-to-iterrows) – Samuel Aug 06 '20 at 22:11

1 Answers1

0

I would suggest using the [numpy.where()][1] function which is usually pretty fast especially if the conditions and manipulations aren't very complex. For your example it would look something like this:

import numpy as np

prices['usd_bank'] = np.where((prices['sell_price'] > row['upper_bound']) 
                               & (stock_bank != 0:)
                              ,stock_bank * (prices['sell_price'])
                              ,0)

After that it's pretty straight forward to just sum the column for a total and check if any value are > 0 to set stock_bank as 0.

  • I don't think it's that simple, I think I explained poorly. The actual data is thousands of rows that we need to cycle through and trade back in forth USD for stock. There may be many trade opportunities but we can only buy stock when we have USD in hand and so forth. We need to keep a running balance of stock holding and USD holding. I hacked something together using shift, and np.where, and np.select, but it is such a mess it is much slower than iterrows! So still looking for something elegant. – DustinB Aug 07 '20 at 01:35