The vectorize()
function is a yet another trick to reduce the number of loops in your programs. Calculate the profit of a single trading day following these steps:
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:func = np.vectorize(calc_profit)
func()
as if it is a function. Apply the func()
function 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, will return 0. Otherwise, we sell at the close price and the profit is simply the difference between the buy price and the close price. Actually, it is, in fact, more interesting to have a look at the relative profit:def calc_profit(open, high, low, close): #buy just below the open buy = open * 0.999 # 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 is 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 statistics are as follows:
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 statistics are as follows:
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 statistics summary of the losing and winning trades (see simulation.py
):
from __future__ import print_function import numpy as np 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 * 0.999 # 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.
Find out if there was such a losing streak. If you want, you can also find out if there was a prolonged winning streak.