? and how I built the AI.
Robinhood, if you don?t know it, is a commission-free stock trading platform that Bay Area techies like me love. I can buy and sell shares very conveniently from my phone. I?m fairly new to it, and started trading against my wife a few months ago as a game (we are quite competitive).
This is FOX?s Masked Singer (image from The Wrap). Very little about it is relevant to an article like this, but it?s a fun show with amazing costumes and competition.
Despite thinking I know everything there is to know about hardware and software companies (?intuitively?), I have found that actively trading shares is quite difficult, and have been consistently losing week-on-week to my non-techie wife. First, you have to find the time to be on top of the news about your portfolio companies, their industry segments, and market fundamentals. Second, having friends at those companies would probably help. And third, it all just seems a bit random.
Instead of doing all that, which sounds difficult, I thought I?d do what I know how to do: build an AI to trade for me.
A number of people have asked me in real life why I did this forreals, instead of simulating it. My answer has been ?I work in AI, I should be willing to put my money where my mouth is?. And I think if more people genuinely had skin in the game, we could solve issues like bias sooner, because it forces you to see the bigger picture.
(That said, don?t expect my next article to be entitled ?I let an AI buy my chocolate and wine for a week, and this is what happened?. Some things are just too important.)
The stock market is indeed pretty random; I mostly believe that it?s a random walk (or would be in an ideal world, but markets are sadly not efficient). But my trading strategy to date has been pretty random too, and I feel like an AI could easily beat it on the numbers alone. Here are some of the terrible trading strategies I have followed:
- Buy Sears/K-Mart (SHLDQ). No way will Sears go bankrupt! (It went bankrupt the next day.)
- Buy TTNP. People in Robinhood chat were talking up this penny stock one day, so I thought I?d give it a go too. Results have not been brilliant (my overall return is -40% at time of writing). I still don?t really know what TTNP does.
- Buy Starbucks (SBUX). I drink there every day, why not!
- Buy into the ?Global X MSCI Greece Fund? (GREK). Grek! It shares my unusual name, I have to have it.
- Buy Bank of America (BAC). I bank with them, and they?ve been alright. Seems reasonable.
- Buy Twitter (TWTR). It?s a great platform, or could be if it fundamentally remade its entire product to be a bit more like Weibo. A long-term bet maybe?
- Buy Brinker International (EAT). I just really enjoy eating at Chilis, regardless of the underlying health of the business. Yet another failsafe trading strategy!
In this experiment, I bought and sold shares on the predictions of an AI I made, for one week, to see if I could make a decent profit (and beat my wife for once). I put my Robinhood account totally in the hands of the AI. (They provide an API and robin_stocks helpfully provides a Python interface to it.)
I made a basket out of shares that I either own, have owned, or which randomly popped up in my Robinhood watchlist (this is not exactly data science, folks.) The stock tickers are:
?TSLA?, ?BABA?, ?EAT?, ?TWTR?, ?TTNP?, ?SBUX?, ?BAC?, ?DIS?, ?STM?, ?ACB?, ?GREK?, ?MSFT?, ?AAPL?, ?F?, ?NVDA?, ?FB?, ?NFLX?
I also own shares in Sears (SHLDQ). You can?t buy them on Robinhood any more, but you can sell them. They are excluded from this experiment. It?s just so funny having shares in a bankrupt company, and I want to see what happens at the bitter end.
Disclaimer: This is me documenting a fun experiment. It?s not investment advice, and the AI I made is just for educational purposes. All my positions in any and all stocks are disclosed in this article, and I have no affiliation with any companies mentioned other than sometimes owning their stock.
Note that I am trading about $1000. Losing it all will not kill me, though it would be mildly annoying since that?s my current sum total of retirement funds. I?ll evaluate performance both daily and by comparing the value of whatever I have at the end of the week, with the value of my portfolio as it was at the start, as if I had done nothing all week (which would be realistic).
My AI only makes predictions for the shares in my basket, so that?s all I?ll be trading during the week. It?ll sell the (predicted) worst performing share that I own (no shorting) in the basket, and buy the (predicted) best performing share.
For reference, over the time period of this experiment, the DJIA gained 1.73% and the NASDAQ was up 3.64%. Could I beat the market?
Day 1 ? Thursday 24 January, 2019
The experiment began! My crappy starting portfolio was:
This screenshot is cut off, but on the right are all the shares I began the week owning, from SHLDQ to DIS.
Actually, full disclosure: the experiment began for the third or fourth time today. In the previous six weeks I started off intrepidly several times, only to discover that, in varying ways, I was pre-processing the data wrong and/or feeding it to the AI wrong. Sometimes the error was obvious (such as: it made basically the same predictions day after day, due to me reshaping the data wrong), and sometimes more insidious (when I lost 15% in a week despite the market moving only sideways. After much debugging, turns out I had left out a minus sign in my code?)
Well, I?ve typed this paragraph many times but hopefully this is it. The AI?s predictions for tomorrow:
As you see at the bottom: sell AAPL, buy TSLA
I was rather hoping the AI wouldn?t buy Tesla since it is an expensive and volatile stock, but truly I am beholden to its choices for the next week. Duly, I allowed the AI to make the trades on Thursday night. As it turned out on Friday, the AI was at least partly right: TSLA was up 1.9% for the day (AAPL, which it sold for me, was also up 3.3%, which sucks; as were most other stocks in my basket). Profit today: $11.
Eagle-eyed readers will note that the first screenshot above shows $852 total portfolio value, now this one shows $1017. I had to add $150 of cash so I could buy Tesla; a liquidity problem I mention below. Don?t worry, my performance evaluation at the end will discount any added cash.
Day 2 ? Friday 25 January, 2019
Heading into the weekend, the AI made its trades on Friday night (Robinhood won?t execute them til Monday morning East Coast time). At this point, it was able to buy 4 TWTR shares and sold both of my NVDA shares (the funds from selling don?t become available til the trade takes place, an unfortunate little bit of illiquidity which has meant that throughout this experiment I?ve constantly needed to be adding more cash to my account).
Looks like a roughly positive next day!
Day 3 ? Monday 28 January, 2019
I?d bought those 4 TWTR shares and sold NVDA on this day
Stocks had a bad day today with the Dow down by 0.84%. TWTR was up by 1.66% since my order was executed and NVDA was off by almost 14%; a positive data point for my AI?s trading skills and while losing nearly $50 in a day is objectively a disaster (imagine if the banknote just fell out of your pocket on the street), I do feel like the AI helped me mitigate losses today.
NVDA?s share performance (downwards) is weird to me. I think what most traders don?t get is that they aren?t a gaming hardware company, but rather, they own the deep learning market.
For tomorrow, it looks like the AI will buy TSLA again (1 share), and sell TWTR (the 4 shares I have).
Day 4 ? Tuesday 29 January, 2019
Tech stocks were mostly down today with the NASDAQ off 0.81%, while the broader DJIA was up very slightly. Happily, the AI?s pick TSLA was up 0.36% and its loser TWTR was down 4.5%. Here?s the chart:
If you look closely you can see my portfolio closely matches TSLA?s sparkline for the day, I need to diversify!
Purely directionally (did the stock go up or down), today, the AI?s predictions were correct for 9 out of 16 stocks in my basket.
This is a single data point, don?t get excited. I never bothered to count it again.
Day 5?Wednesday 30 January, 2019
The AI?s sell pick DIS was down about 1.8% while its buy pick NFLX was up 3.6% on the day. Great! New predictions were as follows. Unfortunately, something in my setup borked in the night and I had to execute them manually the next day. I wake up in San Francisco about 2 hours after markets open on the East coast, so it?s possible that I lost some gains.
0.3157522678375244 TSLA0.05695406347513199 BABA-0.8226907849311829 EAT-0.24917984008789062 TWTR-0.21844346821308136 TTNP-0.6226851940155029 SBUX-0.18434487283229828 BAC-0.25224724411964417 DIS0.13227494060993195 STM-0.08197116106748581 ACB0.1578841209411621 GREK0.48212721943855286 MSFT0.5305508971214294 AAPL0.728955090045929 F-0.5398415327072144 NVDA0.04983692988753319 FB-0.6649214029312134 NFLXwill sell NFLX and buy F
My AI was able to buy 25 shares of Ford, since it is quite cheap. Honestly, I don?t know why I put it in the basket of trading stocks. Every Ford I?ve ever owned has had some reliability issue, and I?ve been much happier with Japanese cars, but I guess I do philosophically believe that the US should do more manufacturing.
The End: Day 6, Thursday 31 January, 2019
After five trading days, the experiment ended. If I?d left my portfolio as it was at the start, (accounting for the extra money I had to add during the week), it?d be at $1,202. In fact, it?s at $1,194. Thus, my AI performed only 99.3% as well as ?doing absolutely nothing?.
Here?s a chart of how it did. The yellow line is if I?d done nothing. The blue line is what the AI did.
The y-axis is arbitrary; what this shows is the relative performance. For two days I was strongly better than nothing!
How I built the AI
You can view what I did as a Jupyter notebook on Github here. The high level is:
- Mangle the data (I used training data from Robinhood itself, which gives 5 years of historical data to train on when you use their private API ? the free public API only gives 1 year. Yahoo! Finance and Google Finance both seem to be gone, which is sad).
- Add a few features. What my AI is ultimately predicting is a transformed version of the stock?s gain between today and tomorrow.
- Build a Keras deep recurrent network to be the predictor. I?m back in to Tensorflow since my last article on how it can be deployed at the frontend, plus Keras has the benefit that you don?t need to spend so long reshaping data as PyTorch.
- Train the model on all of the data for the stocks in my basket (one-hot encoding the stock symbol). That makes it a general model, learning general stock market trends across all of the stocks in my basket.
- Freeze some of the layers, pop off the network head, add a new head, and replicate that model for as many stocks as I have in my basket.
- Fine-tune each of those models, with its individual head, to the particular stock.
- Make predictions! I set a cron job to do this every night at midnight West Coast time.
High Level Learnings
- More, and bigger, fully-connected layers didn?t help. It seems a decent RNN layer renders them somewhat superfluous.
- Feature transformations are important. I?m always reluctant to do too much feature engineering, on the principle that a neural network can learn to do that itself. Partly true, but in reality using one-hot encoding for datetime features was very useful, as was taking the log of very large values.
- Features should be as different as possible; there?s little use to having many similar features even if they are not highly correlated. For example, I was doing 2 and 3 day price windows; it was useless. 10 and 50 day windows worked much better.
- Keep batch size the same between training and inference. This is because the Keras LSTM layer is only stateful within a batch. Thus, if you use 128 batch size in training, it?ll learn to predict outputs based on 128 history steps. Don?t then thwart it by giving it fewer steps: it needs to ?warm up? the same amount, even if that intuitively makes you worry about overfitting.
- At some point, I had to acknowledge there was probably data leakage happening ? for example, somewhere I was probably taking the mean over the full range of data instead of just the training set. My modelling here, in a side project, lacks rigor compared to what I do full-time and I had to become OK with that. And also OK about publicly documenting my many blunders!
- Adam is kind of a weird optimizer. Many times in putting this together I reverted to good old SGD where I was certain I knew what was happening (it?ll most always improve? just slower. Unlike Adam which usually learns faster but can be unstable).
- Better logging! I didn?t save anything from day-to-day, except what I wrote down in the draft of this Medium story. I wish I had. It became very difficult to paint a coherent picture after the experiment ended, because I hadn?t fully recorded each day?s actions and prices.
- Security. Even after hardening my server, changing the SSH port, setting it up to use keys and not passwords, and so on? I lost sleep due to my Robinhood password ? which is linked to my bank account ? being on a cloud server.
- RNNs are terrible. Attention is all you need. I?ve been using Transformer architectures at work lately and I?d like to recreate this work without the non-parallelizability and vanishing gradients over long patterns that RNNs suffer from.
But most importantly, you know what: In my view, especially since doing this experiment ? it?s impossible to predict stocks accurately. High frequency trading might yield predictive signals from second to second, but from day to day: fundamentals matter. Moreover, I don?t want to trade day-to-day even, but just stick savings somewhere relatively safe and check on them from month to month.
Of course, that won?t stop me doing this again with more data and more sophisticated methods, but I?m fine with that being a quest for fools? gold.