Poor Man’s Monte Carlo

This entry is part 19 of 23 in the series Numpy Strategies

Gambling is fun. It’s more fun than doing actual work, since you don’t have to know what you are actually doing. But you know if you throw a dice enough times, then the average result will become less and less random. In theory.

Now if we assume that whatever returns we observe for a stock are like the possible outcome of a dice, a coin or similar then we can do a Monte Carlo experiment. Not a very rigorous one. Since we are looking for support and resistance we can just filter out a portion of the returns using a fixed percentile as threshold. For instance, to determine support we can leave out returns above the 95th percentile. This is arbitrary, so back-testing/grid search will be needed.

The following code does simulations from today until a given end date. It randomly selects returns from a returns distribution as explained in the preceding text. The price that we arrive at after each simulation is averaged and we stop after approximately a few seconds. That is I believe more than enough (the percentile parameter influences the end result stronger IMHO). It should be pretty easy to make the code concurrent if you feel the need. As always user beware. If you use this code and lose money, then it’s your own damn fault! If you win big, I expect a decent percentage.

 def biz_days(): a = datetime.date.today() b = datetime.datetime(int(sys.argv), int(sys.argv), int(sys.argv))   return len(list(rrule.rrule(rrule.DAILY, dtstart=a, until=b - datetime.timedelta(days=1), byweekday=(rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR))))   bdays = biz_days() l_rets = l[1:]/l[:-1] - 1 cutoff = scoreatpercentile(l_rets, 95) l_rets = l_rets[l_rets < cutoff] start = datetime.datetime.now() n = 0 mean = 0 M2 = 0   while True: n = n + 1 indices = random_integers(0, len(l_rets)-1, size=bdays) x = l[-1] * (1 + l_rets[indices]).prod() delta = x - mean mean = mean + delta/n M2 = M2 + delta*(x - mean)   if n % 10 ** 5 == 0: print n now = datetime.datetime.now()   if (now-start).seconds > 2: print "Mean", round(mean, 2), "Std", round(mean - np.sqrt(M2/(n-1)), 2) break