Time for action – avoiding loops with vectorize

The vectorize function is a yet another trick to reduce the number of loops in your programs. We will let it calculate the profit of a single trading day:

  1. First, load the data:
    o, h, l, c = np.loadtxt('BHP.csv', delimiter=',', usecols=(3,4, 5, 6), unpack=True)
  2. The vectorize function is the NumPy equivalent of the Python map function. Call the vectorize function, giving it as an argument the calc_profit function that we still have to write:
    func = np.vectorize(calc_profit)
  3. We can now apply func as if it is a function. Apply the func result that we got, to the price arrays:
    profits = func(o, h, l, c)
  4. The calc_profit function is pretty simple. First, we try to buy slightly below the open price. If this is outside of the daily range, then, obviously our attempt failed and no profit was made, or we incurred a loss, therefore, we will return 0. Otherwise, we sell at the close price and the profit is just the difference between the buy price and the close price. Actually, it is more interesting to have a look at the relative profit:
    def calc_profit((open, high, low, close):
       #buy just below the open
       buy = open * float(sys.argv[1])
       # daily range
       if low <  buy < high:
          return (close - buy)/buy
       else:
          return 0
    print "Profits", profits
  5. There are two days with zero profits: there was either no net gain, or a loss. Select the days with trades and calculate averages:
    real_trades = profits[profits != 0]
    print "Number of trades", len(real_trades), round(100.0 *len(real_trades)/len(c), 2), "%"
    print "Average profit/loss %", round(np.mean(real_trades) *100, 2)

    The trades summary are shown as follows:

    Number of trades 28 93.33 %
    Average profit/loss % 0.02
    
  6. As optimists, we are interested in winning trades with a gain greater than zero. Select the days with winning trades and calculate averages:
    winning_trades = profits[profits > 0]
    print "Number of winning trades", len(winning_trades),round(100.0 * len(winning_trades)/len(c), 2), "%"
    print "Average profit %", round(np.mean(winning_trades) * 100, 2)

    The winning trades are:

    Number of winning trades 16 53.33 %
    Average profit % 0.72
    
  7. As pessimists, we are interested in losing trades with profit less than zero. Select the days with losing trades and calculate averages:
    losing_trades = profits[profits < 0]
    print "Number of losing trades", len(losing_trades),round(100.0 * len(losing_trades)/len(c), 2), "%"
    print "Average loss %", round(np.mean(losing_trades) * 100, 2)

    The losing trades are:

    Number of losing trades 12 40.0 %
    Average loss % -0.92
    

What just happened?

We vectorized a function, which is just another way to avoid using loops. We simulated a trading day with a function, which returned the relative profit of each day's trade. We printed a summary of the losing and winning trades (see simulation.py):

import numpy as np
import sys

o, h, l, c = np.loadtxt('BHP.csv', delimiter=',', usecols=(3, 4, 5, 6), unpack=True)

def calc_profit(open, high, low, close):
   #buy just below the open
   buy = open * float(sys.argv[1])

   # daily range
   if low <  buy < high:
      return (close - buy)/buy
   else:
      return 0

func = np.vectorize(calc_profit)
profits = func(o, h, l, c)
print "Profits", profits

real_trades = profits[profits != 0]
print "Number of trades", len(real_trades), round(100.0 * len(real_trades)/len(c), 2), "%"
print "Average profit/loss %", round(np.mean(real_trades) * 100, 2)

winning_trades = profits[profits > 0]
print "Number of winning trades", len(winning_trades), round(100.0 * len(winning_trades)/len(c), 2), "%"
print "Average profit %", round(np.mean(winning_trades) * 100, 2)

losing_trades = profits[profits < 0]
print "Number of losing trades", len(losing_trades), round(100.0 * len(losing_trades)/len(c), 2), "%"
print "Average loss %", round(np.mean(losing_trades) * 100, 2)

Have a go hero – analyzing consecutive wins and losses

Although the average profit is positive, it is also important to know whether we had to endure a long streak of consecutive losses. If this is the case, we might be left with little or no capital, and then the average profit would not matter that much.

Find out if there was such a losing streak. If you want, you can also find out if there was a prolonged winning streak.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset