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:
o, h, l, c = np.loadtxt('BHP.csv', delimiter=',', usecols=(3,4, 5, 6), unpack=True)
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)
func
as if it is a function. Apply the func
result that we got, to the price arrays:profits = func(o, h, l, c)
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
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
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
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
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)
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.