27 Nov, 2020

I spoke too soon!

It seems my questionable enthusiasm in my last post was warranted; after a whole week of live testing, I’ve encountered a major problem, one that’s seriously gumming up the works.

I had begun working on a front-end for my program, one that would both output all the day’s buys and sells, as well as more detailed information for individual stocks (as you can see in the image above). While working on it, I had noticed that a couple stocks had drastically different scores from one day to the next. I had attributed that to the stock having been “traded” by the program during those days, which naturally would change the score. However, upon closer inspection, I noticed that not only had the stocks not been traded on those days, but the trades were also different.

Now, before you assume I’m working with some kind of machine learning algorithm, nothing could be further from the truth. I’m very much a beginner-to-intermediate coder and almost exclusively in PHP (and MySQL but that’s not a coding language). As I’ve stated in a previous post, my methodology is very much brute force, with little forethought or planning (even if I do try to plan ahead, I always end up ignoring or ditching the plans). It’s a lot of trial and error, a lot of loops, and Googling things along the way. Fortunately, my program uses a very basic concept of checking if certain pricing conditions are met, coming up with a score based on those conditions, and then determining what action to take based on said score. There are no bizarre quantitative formulas, no machine learning, etc., simply “how many of these conditions are being met?” and “if the score is X, buy, if the score is Y, sell”.

There was one section of code that I thought was fairly clever, that I felt pretty proud of; I had attached point values to each condition, mostly 1s, but a handful of 2s (to the more important ones) and 0.5s (to the least important ones). My idea to build on that was to adjust those point values based on how successful they were. For example, if Condition A led to a successful buy, I’d increase the points from, say, 1.0 to 1.2. If Condition B would repeatedly cause unsuccessful buys, I’d drop the point value from 1.0 to 0.6, and so on.

I had anticipated that this would lead to some variable final scores; however, one of the stocks was yielding wildly different scores every other day. Most stocks would move from 0.52 to 0.56 or similar. This one stock went from 0.71 one day to -0.59 the next, and then back up to 0.74 and eventually down again to -0.13. Further examination of the results I was saving revealed and even bigger problem; I was saving the dates from a stock’s last buy and last sell. All things being equal, they should stay the same from day to day (unless a new trade was made). This stock, however, was yielding different buy and sell dates almost every day; making even less sense, one day it would trade a week before, and the next that trade would no longer happen. One day it would show it traded 12 times, the next day it traded only 11 times, but the next day it traded 16 times.

Needless to say, this makes me lose faith on all the transactional data I had generated over the past week.

That’s not to say the program is a lost cause. It merely requires more troubleshooting. I’m fairly confident two things are the culprits here: 1) the variable point system I described earlier, and having the program start a day later every day. In order to avoid massive processing times, I’m having the program fetch only the last 2 years’ worth of pricing data to analyze; so if I ran the program yesterday, it would analyze all prices from November 26, 2018 to November 26, 2020, and then today it would analyze from November 27, 2018 to November 27, 2020, etc. That moving range has an effect in that it may encounter an actionable date earlier on that would prevent it from taking another action later on. For example, if I start analyzing on November 27, it may not decide to buy stock until maybe December 12. However, if I started on November 26, the program might think that very day is a good idea to buy stock, and if it’s already holding when December 12 comes along, it won’t buy stock because it already has it.

Now this technically could “even out” after a few trades, but this is less likely when the point values are adjusted after every trade. So the first thing I’ve done is eliminate the adjustable point system, and set a static start date; this will be problematic later on as the program will be analyzing more and more data every day, rather than exactly two years’ worth as I originally had. I’m hoping to be able to work out some kind of database-driven caching system that would actually decrease processing time later on, so fingers crossed on that one. But for the time being, I’ll simply let the processing time increase as I’m anticipating to have be in this situation for a short time.

One other possible culprit is an adjustable stop-loss function I have; it starts out at 10%, and then decreases each day based on how much the price moves. It turns out this becomes a pretty good way to also “let it ride” and have the stock price itself out. If the stock continually goes up in value, the stop-loss eventually becomes like a limit order, as eventually the 10% becomes 0% and ultimately a negative number. If I buy a stock for $100, the stop-loss would be triggered at $90. But if the price goes up to $110, my stop-loss might be 0 now, which means “if the price goes below $100 (0% below $100), sell“. Once it goes up to $111, the stop-loss might be -1%, which means “if the stock goes below $101 (-1% “below” $100). The code allows for drops in price and eventually, because the stop-loss value never decreases, it only increases, whether the price goes up or down, the price will cross that limit value and trigger a sell. I’ve run it on dozens of different stocks and only in a small handful of situations was that a false trigger; there have been a few situations where the stock could been held a day or two longer (or sold a day or two sooner), but in most cases it still yields favorable results.

In short, there is some variable data that makes the program “change it’s mind” about decisions it made the day before. I’m going to have to run full-market scans for a few days with just fixed condition values and fixed start dates to see if any irregularities like the ones I’ve mentioned continue to pop up, before I ditch the adjustable stop-loss. I’ve also got to work on that trade caching concept I mentioned above, which will basically “force” the program to record the transactions and re-use them later on, rather than re-simulating every trade every time it runs. Needless to say, I’m disappointed that I’ll once again have to delay live testing, possibly for at least a couple weeks, but if I intend to putting real money on this, whether or not this is accurate or wildly successful, I at least need it to be consistent.

Tags: , , , , ,

One thought on “I spoke too soon!”

Leave a Reply