Back to Posts
Listen to Thread

Thought I'd share another algorithm I was working on :P (having fun learning python/trying out ideas)

This one uses standard deviation to calculate it's stop loss and take profit, as well as to try and detect upward breaks from ranges (which trigger it's buy positions).

The below test had a winning percentage of 61%, including 1149 "successful" trades (trades closed by the takeprofit) and 722 "failed" trades (trades closed by the stoploss).

This is in line with winning percentages from most other volatile stocks I tried the algorithm on (such as google), although some less volatile stocks (like microsoft) I tried didn't work so well, - managing to somehow hit the take profit at small losses - leaving them at -2% max loss (tests other than the below were tested for 1 year).

There's also a few other possibly useful code snippets inside...

Enjoy! (and feel free to post your own patches in this thread)

Clone Algorithm
315
Loading...
Backtest from to with initial capital ( data)
Cumulative performance:
Algorithm Benchmark
Custom data:
Week
Month
All
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Information Ratio
--
Benchmark Returns
--
Volatility
--
Max Drawdown
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Information Ratio 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

Oops! I forgot to add " and context.plug_pulled == False" to the if statement that opens the trade (which prevents trading past a 30% loss of the starting cash value).

Add that code if you want to enable that feature :P

haha I also made a slight mistake in how I used the standard deviation in opening the position (been a year since I covered standard deviation in my 1st year stats module).

Below is the fix (which interestingly had a 1% higher winning percentage, but 5% lower profit).

Clone Algorithm
315
Loading...
Backtest from to with initial capital ( data)
Cumulative performance:
Algorithm Benchmark
Custom data:
Week
Month
All
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Information Ratio
--
Benchmark Returns
--
Volatility
--
Max Drawdown
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Information Ratio 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

Hi Adam ... My name is Abhi ... I am just starting out in the world of algorithmic trading ... Do you mind if I ask you a couple of basic questions about this algorithm?

Hi Abhi, feel free to ask questions and I'll do my best to answer.

Note that I'm quite new to algorithmic trading as well =)

Thanks... Most of these questions are very basic...I kinda feel like Alice in wonderland. :)

  1. In lines 41-43 of your algorithm, why did you choose the vwrap window to be 5. Likewise why was the standard deviation window chosen to be 9?
  2. price > vwap_5_day + (standard_deviation * 0.6) In this if block, why did you choose standard deviation & why the value of 0.6

Hi Abhi,

I'll try to explain the basic thinking behind the algorithm.

This algorithm was a basic experiment in "surfing" market sentiment. This means I was trying to detect breaks from normal market activity, and then "ride the wave" of changing price.

To try and detect normal market activity for a period, I used the vwap and standard deviation.

The vwap (volume weighted average price) represents the average price of the market over the given time period, weighted by the volume of trades people are making.

The standard deviation is a measure for a period of time of how spread out numbers are around the average (there's a good explanation here - http://www.mathsisfun.com/data/standard-deviation.html).

The basic assumption behind this algorithm is that when price remains within the range around the average given by the standard deviation, it is considered to be normal trading (and so not doing anything particularly interesting). Therefore, it assumes that when the price for the given asset "breaks" out of this normal trading range, that there is a change in normal market activity indicating either an upward or downward movement.

Upon a larger than normal (from the given date range) upward movement, this algorithm makes a buy order in order to ride the upward market sentiment. As prices tend to have a habit of changing by the value of the range they are breaking from, I conservatively set the algorithm to take it's profit upon an upward movement of half the standard deviation (0.5).

The problem with this system is that there can be false triggers, either when the market is still overall ranging but just about manages to break the historical range, or sometimes when a market is about to have a major move to the downside it will move up first (not sure why).

In order to reduce false triggers I set the if statement to only make a buy order after the range had been broken by 1 standard deviation + 0.1 (where it had broken the range, and then some extra). I accidentally in the first iteration above used half a standard deviation + 0.1 for this (0.6), but got away with it as I had set the standard deviation to more days than the average (the more days in the standard deviation, the larger it's likely potential size). The standard deviation had initially been set to more days than the average to make it slightly larger, and so make the algorithm less sensitive.

Knowing that this wasn't a 100% accurate way to detect continuing upward price movement, I also ensured to implement a stoploss to cut my losses when the algorithm was wrong, although being careful to not set it so close that it could be accidentally triggered.

Overall it seems the algorithm in more volatile (and numerically large) stocks seems to get it's assumptions of upward movement right more often than it get's them wrong (and so produces a profit in the backtested data).

Hopefully that explanation helps, and having just realised it's 4:30 am I think I'll call it a night :P

Thanks so much for the explanation .... Things are making sense now .... appreciate it

Adam, the mistake you are making is that you are backtesting on Apple. This is not a good stock to pick, because it's a gross case of hindsight bias. Apple's rise has been so strong that even a random buy/sell strategy would produce large profits.

A more appropriate test would be an index, or a stock that has not had the meteoric success Apple has over the last 5 years.

Ken, another user actually proved your point with a backtest that randomly buys Apple: https://www.quantopian.com/posts/random-long-apple-system-aka-the-dangers-of-foresight-bias

Log in to reply to this thread.
Not a member? Sign up!