Monday, 28 May 2012

Week of 2012 MA 25

SPY rose by 1.9% this week, while my account fell 1.5% to its lowest value ever.  I am once again out of the market, so my loss-floor is same as account-value.

Euro news: The “GrExit” is no longer unspeakable among Europe’s leaders.  Greece has announced that they will be unable to meet payroll after the end of June without another bailout, which they can’t get without an “austerity” government, which (polls say) the Greeks will not vote for.  The end seems nigh.

US news: Many pundits predict that next week will have the traditional ”Memorial Day bounce".  The US market seems decoupled from Europe, going up while Euro markets are falling.  This may continue for a few weeks—or the US market may crash later next week.  Hopefully my robot will catch the crash if it happens.

Thursday’s allocations:
Daily % gain
size
│Max loss│Final
Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
SRTY 1  MA16 │ +2.1 16  +0.9 16  +1.2 16  +0.9 0  │ │ +1.4%
SRTY 2  MA18 │ +1.2 15  -0.9 15  -0.6 15  -0.9 0  │ │ -0.3%
TZA  MA21 │ -0.8 13  -0.6 13  -0.9 13  -0.9 0  │ -0.7 -0.7 │ -0.7%
SRTY 3  MA21 │ -0.0 14  +0.2 14  -0.1 14  -0.2 14  -0.1 0  │ -0.4 -0.4 │ -0.1%
SRTY 4  MA23 │ -0.9 14  -1.0 14  +0.2 14  │ -1.2 -1.2 │ -0.8%
SPY │ +3.4 +5.2 +5.3 +5.4 +5.6 +5.3 │ │
me │ -6.0 -6.7 -6.8 -7.7 -7.5 -7.5 │ │
floor │ -6.0 -7.0 -6.8 -7.9 -7.5 -7.5 │ │

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TZA MA 14 11:00 MA 21 10:01 $20.58 $23.18 MA 21 15:00 MA 21 12:26 $21.94 $21.97 +1.0% -0.7%
SRTY 3 MA 21 12:00 MA 21 15:56 $55.97 $54.11 MA 22 10:00 $53.88 $53.94 -0.5% -0.1%
SRTY 4 MA 23 12:00 $57.40 $57.45 MA 24 10:00 $54.48 -0.7% -0.8%

TZA: What a horror story!  Last Sunday night, I put in a buy-stop order for TZA that would trigger if the market dropped to 0.5% below its 200-day moving average.  Also I resolved to get up early Monday morning and buy TNA if the market zoomed instead.  Well, Monday morning the market just sat there, hugging the 200-MA.  Eventually I got tired of waiting, convinced myself that the market looked like it was going down, and changed the buy-stop to a market order for TZA.  Immediately the market went up!  I bought at the worst price of the day!  Yet another reason why I use a trading robot, so I don’t have to make those real-time trading decisions.  Rule: don’t get up early.  It’s never worth it.
      To recap recent events: when the robot failed to buy SRTY a few weeks back, I put in a limit-order to buy if the model’s price showed up again—which it did, but the trade ended up being a small loss.  Then the robot failed to buy TZA, but I didn’t put in a limit-order even though the price did come back—and the trade would have been a medium-sized winner.  So this 2-item subset of trades shows the same “small losses, big gains” feature that we expect of all trades.  New rule: when the model says “buy” but the robot fails to buy, put in a limit-order to at least try to get the model’s price.

SRTY 3 : Because I was screwing around with the robot’s price-data, trying to make it match up with my manual TZA trade, I caused it to not buy SRTY at noon as it should have.  I ended up buying near the close for a better price — but still the trade ended as a small loser.

SRTY 4 : Normal trade, which happened to be a loser during a week that already had losses.

Custom indicator PEAKFREQ

I can haz nu indicator!

Let PEAKFREQ(n,size) be the number of peaks and troughs detected during the last n hours.  Detection uses Donchian channels: a “peak” is a rise in the upper CHAN(size) followed by a drop, while a “trough” is a fall in the lower CHAN(size) followed by a rise.

This indicator shows how “jittery” the market is.  If there are a lot of peaks and troughs per unit time, then the market is changing direction a lot these days.

The chart at right shows the last 140 hours of price action, with 8-hour channels.  The light blue arrows show when peaks and troughs are detected (which happens nine hours after they occur).  There are eight arrows shown and therefore PEAKFREQ(140,8) = 8 as of Friday’s close.

Here is a histogram showing the PEAKFREQ(140,8) values during the period 2008 through 2011 (excluding January 2008, to give the algorithm a running start).  There were 7,329 trading hours during this period.  About 14% of all hours had PEAKFREQ=13.  Only two(!) of all these hours had PEAKFREQ=6.  Only 0.6% of all hours had values below 8, so Friday’s close was a rather “calm” hour.

Adding a PEAKFREQ test helps my TNA and TZA models a lot!

MACD-based news trades

The SRTY model is a “news” trade in the sense that its typical hold time is hours-to-days, even though this is a quant model and doesn’t attempt to parse a news feed.

New rule: don’t buy SRTY if PEAKFREQ(140,8) < 8.  Although only 0.6% of hours have such low values, those trades are mostly losers, so skipping them raises the 2008..2011 return from 42.4% to 42.8% and improves the win:loss ratio from 93:104 to 81:88.  Yeah, it’s not much.  Then I retuned the model: only the SMA parameter changed (from 27 to 26), but that further increased returns to 43.2%.

PPO-based swing trades

%return, win:loss
TNATZA
Old model41.0%, 26:2253.9%, 25:20
add PEAKFREQ44.9%, 24:1556.0%, 22:11
retune52.4%, 29:1563.2%, 24:17

New rule: do not buy TNA or TZA if PEAKFREQ(140,8) > 11.  This removes 77% of all hours from consideration for purchase, while improving results noticeably.  Because PEAKFREQ eliminates so many bad hours, I was able to retune for best results on just the hours that remained.  After retuning, 66% of the TNA model’s trades are now winners (was 54%) while TZA now has 59% winning trades (was 56%).

In the new model, there are now no TNA trades at all for the first five months of 2012.

The PPO model is overcomplicated, but I can’t decide what to prune.  The most obvious candidates are the “alternate buy” and “alternate sell” rules, but the alt-buy rule is responsible for 13 %-points of profit during 2008..2011, while the alt-sell rule provides almost 5 %-points of the total 116% profit.  Anyway, here is the model-description, with highlighting for changes:

Bull swing (TNA) Bear swing (TZA)
Buy signal:
  • Time = 10am–3pm, on the hour
  • PEAKFREQ(140,8) ≤ 11
  • This hour’s price > previous hour’s price
  • This hour’s price > stop
  • This hour’s price > SMA(30)
  • This hour’s price > max of preceding 26 hours
  • PPO(8,71,1) < +1.8
  • PPO(8,71,12) > +0.4
  • PPO(8,71,12) has gone below -0.25 since last purchase
  • STDDEV(80) < its EMA(43)
  • Time = 11am–3pm, on the hour
  • PEAKFREQ(140,8) ≤ 11
  • This hour’s price < previous hour’s price
  • This hour’s price < stop
  • This hour’s price < SMA(75)
  • This hour’s price < min of preceding 34 hours
  • PPO(10,60,1) > -2.4
  • PPO(10,60,12) < -0.1
  • PPO(10,60,12) has gone above +0.28 since last purchase
  • STDDEV(29) < its EMA(25)
Alternate buy signal:
  • Time = 10am–3pm, on the hour
  • This hour’s price > SMA(30)
  • This hour’s PPO(8,71,12) minus its value from 35 hours ago > +2.6
  • It has been at least 6 hours since last sale.
  • Time = 11am–3pm, on the hour
  • This hour’s price < SMA(75)
  • This hour’s PPO(10,60,12) minus its value from 22 hours ago < -2.35
  • It has been at least 10 hours since last sale.
Buy-more signal:
  • Time = 10am–4pm, on the hour
  • Either
    • PPO(8,71,12) has risen by at least 0.02 during each of the last two hours
    • PPO(8,71,12) has changed by less than ±0.02 during the last hour and rose by at least 0.02 during each of the preceding two hours
  • PPO(8,71,12) fell by at least 0.02 during the two hours before that.
  • STDDEV(80) < its EMA(43)
  • Have bought 2 or fewer tranches so far
  • If signal received at 10am or 4pm, postpone purchase to 11am
  • Time = 10am–4pm, on the hour
  • Either
    • PPO(10,60,12) has fallen by at least 0.02 during each of the last two hours
    • PPO(10,60,12) has changed by less than ±0.02 during the last hour and fell  by at least 0.02 during each of the preceding two hours
  • PPO(10,60,12) rose by at least 0.02 during the two hours before that.
  • STDDEV(29) < its EMA(25)
  • Have bought 4 or fewer tranches so far
  • If signal received at 4pm, postpone purchase to 10am 10am or
Sell signal:
  • Time = 10am–3pm, on the hour
  • This hour’s price < previous hour’s price
  • This hour’s PPO(8,71,12) < -0.25
  • PPO(8,71,12) has gone above +0.4 since original purchase
  • Time = 11am–3pm, on the hour
  • This hour’s price > previous hour’s price
  • This hour’s PPO(10,60,12) > +0.28
  • PPO(10,60,12) has gone below -0.1 since original purchase
Alternate sell signal:
  • Time = 10am–3pm, on the hour
  • This hour’s PPO(8,71,12) minus its value from 35 hours ago < -2.7
  • It has been at least 6 hours since last purchase.
  • Time = 11am–3pm, on the hour
  • This hour’s PPO(10,60,12) minus its value from 22 hours ago > +0.6
  • It has been at least 10 hours since last purchase.
Stop update:
  • Time = 10am
  • Calculate new stop = lowest price seen in preceding 22 hours.
  • Raise new stop to  94.5% of the highest price seen in preceding 22 hours, if less than that
  • If I don’t currently own TNA, replace stop with the newly-calculated value.  Otherwise:
    • Discard new stop (and keep the old one) if the new value is lower
    • Sell now if lowest price of last 22 hours occurred during the last hour
    • Otherwise, convert the IWM-based stop to the corresponding TNA price and update the standing stop-order at Schwab
  • Time = 10am
  • Calculate new stop = highest price seen in preceding 22 hours.
  • Lower new stop to 104.6% of the lowest price seen in preceding 22 hours, if greater than that
  • If I don’t currently own TZA, replace stop with the newly-calculated value.  Otherwise:
    • Discard new stop (and keep the old one) if the new value is higher
    • Sell now if highest price of last 22 hours occurred during the last hour
    • Otherwise, convert the IWM-based stop to the corresponding TZA price and update the standing stop-order at Schwab

TRIX-based trend trades

No change.  It turns out that the URTY model only ever triggers when PEAKFREQ has a middling value, so there is nothing to gain from adding an explicit test.

For almost three months now, the robot has woken up every hour and calculated whether to buy URTY.  Every single hour, the answer has been “No.”  This model typically triggers about six times per year, so clearly we are going through a dry spell.

Summary of changes to trading performance

In this version of the chart, the left column for each quarter shows the results using the models as of March 31st (but excluding URTY) and the right column shows results using the latest model as above.  For the 2012 quarters there is a third column showing actual results.

So far, Q1 and Q2 of 2012 look only a little worse than Q4 2010 and Q1 2011.


Friday, 18 May 2012

Week of 2012 MA 18

SPY fell by 4.7% this week, while my account rose 0.9%.  I am out of the market again; many pundits believe that next Monday will bring either a large bounce or a crash.

Friday’s allocations:
Daily % gain
size
│Max loss│Final
Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
TZA#0 MA03 │ +0.7 30  +1.8 30  +1.9 0  │ │ -0.0%
SRTY#0  MA08 │ -0.1 14  +0.4 0  │ │ -0.3%
SRTY#1  MA14 │ +0.0 15  +0.1 15  +0.4 15  +1.4 0  │ -0.9 -0.9 │ -0.2%
SRTY#2  MA16 │ +0.6 16  +1.6 16  +2.1 16  │ -0.4 -0.3 │ +1.4%
SRTY#3  MA18 │ +0.2 16  │ -1.2 -1.2 │ -0.3%
SPY │ +8.1 +6.9 +6.2 +5.8 +4.3 +3.4 │ │
me │ -6.9 -7.1 -7.1 -6.5 -5.5 -6.0 │ │
floor │ -6.9 -7.1 -7.1 -7.5 -7.2 -6.0 │ │

This week, I have changed the “Daily % Gain” table so all figures are percentages of my total account, not of the individual trade.  Basically, all numbers are now ⅟₇ of what they used to be.  This removes the disparity between the daily table above and the robot’s weekly table below, which was already using total-account figures.

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TZA#1 MA 14 11:00 (Skipped) $20.58 (Not yet)
SRTY#1 MA 14 12:00 MA 14 11:00 $51.05 $51.25 MA 09 14:00 $50.57 $50.50 -0.2%
SRTY#2 MA 16 10:00 $50.75 $50.58 MA 18 11:00 $55.75 $55.70 +1.3% +1.4%
SRTY#3 MA 18 12:00 $57.52 $57.50 MA 18 13:00 $56.47 $56.46 -0.3%

TZA#1: Argh!  The robot didn’t buy because it got an IWM real-time quote from Schwab at 11am that was higher than the one for 10am, while stockcharts.com shows a lower price.  Because of the new STDDEV rule, the robot then refused to buy TZA all week, waiting for a bounce that never came.  As I suspected last week, it was a bad idea to sell TZA last Thursday and it might well turn out to have been a bad idea not to overrule the robot and buy TZA this week.

SRTY: This ticker underwent a 1-for-5 reverse split last Friday, so all price-quotes are now five times larger ($50 instead of $10).

SRTY#2: Good timing on the purchase!  The robot shorted the market on Wednesday at what turned out to be nearly the highest price of the day.  Friday’s sale-time wasn’t so hot, though.

SRTY#3: This was stupid.  I have added a new rule: Do not buy SRTY unless at least two hours have passed since the last sale.  This rule increases average profit slightly (from 10.4%/year to 10.5%/year) and improves the win:loss ratio slightly (from 101:118 to 101:116 since 2008) but the main point is that it would have blocked the third trade this week.

Daily stop-update: Friday’s stop price for SRTY#2 should have been $50.40 (for a -0.1% max loss) but the robot chose $49.48 (for -0.3%).  As a result, the max-loss actually went *down* from Thursday’s -0.2%.  I really ought to fix this, by fetching quotes for IWM and SRTY during the same invocation of Opera so their prices will differ by milliseconds instead of seconds.

Friday, 11 May 2012

Week of 2011 MA 11

SPY fell by 0.9% this week, while my account fell 1.2% to its lowest value ever, mainly due to last week’s big TNA loss coming home to roost after the unrealized TZA gain evaporated.  I am out of the market again.

This week, I withdrew some more money to put food on the table.  Because of its tranche limits, the current robot algorithm would never have invested that cash, anyway.  Now that I’ve withdrawn 20% of the money, it has become clear that there were some math problems in the weekly chart above (last week’s closing balance was actually -5.7%, not -6.1% as shown last week), so I have made a few adjustments to fix things up.  Unfortunately, it is too difficult to adjust the historical loss floor values so I just made some rough tweaks to make the chart look reasonably close.

Friday’s allocations:
Daily % gain
size
│Max loss│Final
Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
TNA  AL26 │ -10.8  28 -9.7  0         │ │ -4.7%
SRTY#0  MA02 │ +7.0  16 +5.8  16 +6.4  16 +8.0  0 │ │ +6.5%
TZA  MA03 │ +6.5  16 +5.2  16 +5.6  16 +2.8  31 +1.6  30 +2.1  30 │ -3.8 -0.3 │ -0.1%
SRTY#1  MA08 │ -2.2  14 -0.7  14 -1.9  14 -1.2  14 │ -5.5 -3.7 │ -1.9%
SPY │ +9.2 +9.2 +8.8 +8.2 +8.4 +8.1 │ │
me │ -5.9 -6.1 -6.3 -6.3 -6.9 -6.9 │ │
floor │ -7.5 -7.6 -8.4 -7.8 -6.9 -6.9 │ │

Surfing the oscillations

The TZA trading model did an exceptionally bad job of surfing the recent oscillation.  From May 1st to May 9th the market dropped by 6%, but I lost a third of that before the robot realized that it was time to go short, and lost another third waiting for the robot to realize that it was time to close the position, so I got less than one third of the total available profit on that first tranche.  As has been the norm recently, the second tranche was completely mistimed and its loss mostly cancelled out the gain from the first tranche, so I ended up with nothing after subtracting the 0.3% transaction cost.

On Thursday, IWM’s PPO peaked at +0.32, but my model sells TZA at +0.28.  I will be quite unhappy if the market plummets on Monday.

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TZA MA 03 12:00 $18.58 MA 10 13:00 $19.51 $19.43 +0.1% -0.0%
MA 09 11:00 $20.33 $20.36
SRTY#1 MA 08 10:00 MA 08 11:50 $10.00 MA 09 14:00 $9.82 -0.2% -0.3%

There were yet more problems with the robot this week:
      Tuesday: at 10am, it adjusted the stop for TZA.  It was also supposed to buy SRTY at that hour, but inexplicably didn’t (with no error message), so at 11:30 I put in a limit order to buy for the 10am price, which was triggered at 11:50.  But SRTY got sold the next day for a loss so I guess I should just have skipped it.
      Wednesday: The stop-update for TZA tried to change price on SRTY, got rejected by Schwab because stop-price above latest price.  Bug fixed.  Stops for TZA and SRTY updated manually.

PPO-based swing trading

At the beginning of this week, I altered the TZA trading model to reduce churn by avoiding trades where STDDEV is too high.  Since TNA is just a variant of the same model, I ended up adjusting that one also.  Here are the new rules, with yellow highlighting for changes:

Bull swing (TNA) Bear swing (TZA)
Buy signal:
  • Time = 10am–3pm, on the hour
  • This hour’s price > previous hour’s price
  • This hour’s price > stop
  • This hour’s price > SMA(30)
  • This hour’s price > max of preceding 33 hours
  • PPO(8,71,1) < +1.8
  • PPO(8,71,12) > +0.4
  • PPO(8,71,12) has gone below -0.25 since last purchase
  • STDDEV(80) < its EMA(43)
  • Time = 11am–3pm, on the hour
  • This hour’s price < previous hour’s price
  • This hour’s price < stop
  • This hour’s price < SMA(75)
  • This hour’s price < min of preceding 34 hours
  • PPO(10,60,1) > -2.4
  • PPO(10,60,12) < -0.1
  • PPO(10,60,12) has gone above +0.28 since last purchase
  • STDDEV(29) < its EMA(25)
Alternate buy signal:
  • Time = 10am–3pm, on the hour
  • This hour’s price > SMA(30)
  • This hour’s PPO(8,71,12) minus its value from 33 hours ago > +2.8
  • It has been at least 5 hours since last sale.
  • Time = 11am–3pm, on the hour
  • This hour’s price < SMA(75)
  • This hour’s PPO(10,60,12) minus its value from 22 hours ago < -4.1
  • It has been at least 13 hours since last sale.
Buy-more signal:
  • Time = 10am–4pm, on the hour
  • Either
    • PPO(8,71,12) has risen by at least 0.02 during each of the last two hours
    • PPO(8,71,12) has changed by less than ±0.02 during the last hour and rose by at least 0.02 during each of the preceding two hours
  • PPO(10,60,12) fell by at least 0.02 during the two hours before that.
  • STDDEV(80) < its EMA(43)
  • Have bought 2 or fewer tranches so far
  • If signal received at 10am or 4pm, postpone purchase to 11am
  • Time = 10am–4pm, on the hour
  • Either
    • PPO(10,60,12) has fallen by at least 0.02 during each of the last two hours
    • PPO(10,60,12) has changed by less than ±0.02 during the last hour and fell  by at least 0.02 during each of the preceding two hours
  • PPO(10,60,12) rose by at least 0.02 during the two hours before that.
  • STDDEV(29) < its EMA(25)
  • Have bought 4 or fewer tranches so far
  • If signal received at 4pm, postpone purchase to 10am 10am or
Sell signal:
  • Time = 10am–3pm, on the hour
  • This hour’s price < previous hour’s price
  • This hour’s PPO(8,71,12) < -0.25
  • PPO(8,71,12) has gone above +0.4 since original purchase
  • Time = 11am–3pm, on the hour
  • This hour’s price > previous hour’s price
  • This hour’s PPO(8,71,12) > +0.28
  • PPO(10,60,12) has gone below -0.1 since original purchase
Alternate sell signal:
  • Time = 10am–3pm, on the hour
  • This hour’s PPO(8,71,12) minus its value from 33 hours ago < -2.7
  • It has been at least 5 hours since last purchase.
  • Time = 11am–3pm, on the hour
  • This hour’s PPO(10,60,12) minus its value from 22 hours ago > +0.6
  • It has been at least 13 hours since last purchase.
Stop update:
  • Time = 10am
  • Calculate new stop = lowest price seen in preceding 22 hours.
  • Raise new stop to 94.5% of the highest price seen in preceding 22 hours, if it is less than that
  • If I don’t currently own TNA, replace stop with the newly-calculated value.  Otherwise:
    • Discard new stop (and keep the old one) if the new value is lower
    • Sell now if lowest price of last 22 hours occurred during the last hour
    • Otherwise, update standing stop-order at Schwab
  • Time = 10am
  • Calculate new stop = highest price seen in preceding 22 hours.
  • Lower new stop to 104.6% of the lowest price seen in preceding 22 hours, if it is greater than that
  • If I don’t currently own TZA, replace stop with the newly-calculated value.  Otherwise:
    • Discard new stop (and keep the old one) if the new value is higher
    • Sell now if highest price of last 22 hours occurred during the last hour
    • Otherwise, update standing stop-order at Schwab

For TZA, this new model improves the win:loss ratio from 36:34 to 25:21, while average profit goes down from 12.5%/yr to 11.8%/yr (but the profit÷risk ratio improves from 59 to 74).  For TNA, win:loss improves from 33:35 to 28:23, average profit from 8.1%/yr to 8.9%/yr, and profit÷risk ratio from 26 to 35.

This week, the new STDDEV requirement prevented the robot from buying another tranche of TZA at 11am on Tuesday, which would just have increased my loss.

Here is a chart showing old and new quarterly results for TNA and TZA.  Note how little change there is, considering that there are now 20% fewer TNA trades and 34% fewer TZA trades!  Also note that Q2 was a bad quarter in three out of the last four years.

Future plans

At the end of Q1, I said that this system hadn’t had two loser quarters in a row at any time in the last four years, so there was no excuse for that to happen now.  Since then I have further improved the system, so it has even less of an excuse to yield the worst performance in four years just after I start betting on it.

What should I do if Q2 ends up as another loser?  We are already halfway through and something is rotten in Denmark.  Perhaps I just don’t know how to use past performance to guarantee future results.  My back-tests say that this system should work, but it just doesn’t.  Maybe the problem is that 2012 is like 2007, which was before the beginning of my back-tests.  Maybe I should just shut the thing down and transfer this money to the mortgage account to reduce my debt.

Tim Knight said on Monday that he expects “a few days of a bounce and then Party Time USA”.  Are we done with the bounce?  Or will the pseudo-bankruptcy of JP Morgan Chase lead to the mother of all short-squeezes next week?

Friday, 4 May 2012

Week of 2012 MA 04

SPY fell by 2.7% this week, while my account was un­changed after being down 2.4% at mid-week.  My loss floor rose by 0.4%.

US market news: On Tuesday, the market rose sharply after a surprisingly-good ISM report was released at 10am; then small-cap prices nosedived in the afternoon (I would have been better off in the large-cap SPY).  Wednesday morning’s ADP report was bad, so the market gapped down, then recovered.  On Friday, the NFP report was bad, so the market tanked and did not recover.  Overall, the US market seems bearishly biased right now.  Sy Harding has noticed that the NFP report is The Big One, often moving the market by a large amount over the following one to three days.  So there is reason to hope for continued bearishness next Monday.

Friday’s allocations:
Daily % gain
size
│Max loss│Final
Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
TZA#0  AL23 │ -12.9  13 -10.0 13 -10.3  0       │ │ -9.9%
TNA  AL26 │ +3.6  15 +0.2 15 -1.9  30 -1.1  29 -5.4  29 -10.8  28 │ -9.3 -4.7 │ -4.7%
SRTY  MA02 │ -2.9  15 +1.0  15 +7.0  16 │ -7.3 -3.3 │ +6.5%
TZA#1  MA03 │ +0.5  15 +6.5  16 │ -13.0 -3.8 │
SPY │ +11.9 +11.5 +12.1 +11.8 +11.0 +9.2 │ │
me │ -6.3 -6.8 -7.4 -8.7 -8.0 -6.3 │ │
floor │ -8.3 -7.3 -8.3 -9.4 -11.4 -7.9 │ │

TNA: Seventh loss in a row!  And a double tranche!  And it tanked immediately after I bought the 2nd tranche!  So disheartening.

SRTY: Second trade with this new model is a winner!  And the win was more than twice as large as the first trade’s loss.  Now that’s more like it!

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TNA AL 26 12:00 $58.55 $58.51 MA 02 10:00 MA 02 09:31 $57.33 $57.18 -1.4% -1.5%
MA 01 11:00 $61.40 $61.39
SRTY MA 02 11:00 $9.19 $9.20 MA 04 15:00 $9.81 +0.9% +1.0%
TZA#1 MA 03 12:00 $18.58 (Not yet)

TNA: Stop-out at 9:31, which the model noticed at 10:00.  I’m not sure what number to use for “model TNA sell price”, since the model is actually using IWM prices, so I show the lowest TNA price of the preceding three days.  Actually the robot takes the IWM stop-price and then multiplies by the leverage, which generally produces a lower TNA stop-price than that.  Anyway, the “model acct profit” works out to -1.4% as expected.

SRTY: Got the expected prices, but profit was slightly better than expected due to leverage.

TZA#1: If the market drops on Monday, the robot could buy another tranche as early as 11am.  Otherwise, the max-loss floor could rise above break-even as early as Tuesday.

Daily stop-update: Didn’t work well this week.  On Wednesday, the initial stop for SRTY was miscalculated, so I fixed it manually.  On Thursday, the robot picked a ridiculous 13% max-loss for TZA (should have been 8%).  On Friday the daily stop-update failed so I did it by hand.  The underlying problem is that SRTY is a short-selling model (so the robot does its calculations with negated prices) but unlike TZA it has no stop based on “x% below peak”, just a hard floor based on “low of last x days”, so the algorithm has problems with calling abs() and max() in the proper order.  Hopefully this will be fixed up by Monday.

Friday, 27 April 2012

Week of 2012 AL 27

SPY rose by 2.0% this week, while my account fell by 1.5% to its lowest value ever.  My loss floor dropped by 3.5%.

US market news: Tuesday night, Apple released their earnings, which were very good indeed.  Wednesday morning: the market zoomed!  Thursday night, Amazon released their earnings, which were pretty good.  Friday morning the market dropped, then recovered.  I expect continued upward momentum next week, because Apple is basically driving the entire US market these days and typically the post-earnings euphoria lasts 8‒10 days.

Thursday’s cash allocation:
Daily % gain
size
│Max loss│Final
Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
TNA#0  AL17 │ -3.7  14 -7.5  14 -5.5  0 │ │ -6.0%
TZA  AL23 │ -1.3  15 -3.4  14 -7.9  14 -10.7  13 -12.9  13 │ -9.8 -9.8 │ -9.9%
SRTY  AL23 │ -1.3  15 -3.4  14 -8.1  14 -10.5  14 -12.8  0 │ -9.9 -9.9 │ -3.1%
TNA#1  AL26 │ +1.0  15 +3.6  15 │ -11.4 -9.3 │
SPY │ +9.9 +9.0 +9.4 +10.9 +11.7 +11.9 │ │
me │ -4.8 -5.2 -5.9 -6.5 -6.7 -6.3 │ │
floor │ -4.8 -7.9 -6.8 -6.8 -8.6 -8.3 │ │

This week I had my fifth and sixth losses in a row!  I am really getting tired of all these losses.  When will the market make up its mind whether it’s going up or down?  Typically, April or May is supposed to be an intermediate top, followed by lower prices for the summer; but this has been true for only four out of the last ten years.

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TZA AL 23 10:00 AL 23 13:00 $20.34 $20.16 AL 25 10:00 AL 26 12:11 $18.60 $18.20 -1.3% -1.5%
SRTY AL 23 12:00 AL 23 13:00 $10.05 $10.04 AL 24 11:00 $9.76 $9.74 -0.4% -0.5%
TNA#1 AL 26 12:00 $58.55 $58.51 (Not yet)

SRTY: First trade using the new model was a loser.

The robot trader did not work well this week:
      Monday: Both TZA and SRTY models triggered Monday morning.  Due to a bug introduced last weekend, the robot didn’t actually buy anything, so I bought manually several hours later (and for better prices, as it happened).  I also set the stop-orders manually—but for the wrong prices!
      Tuesday: Automatic stop-update didn’t work, due to a different bug introduced last weekend.  Since it looked like the stop prices shouldn’t actually change today, I didn’t bother rerunning the code after fixing the bug, so once again I didn’t notice that Monday’s stop prices were wrong.
      Wednesday: TZA was supposed to stop out around 9:40am or so, but that didn't happen because I had used 29 hours instead of 15 for Monday’s stop-setting and then Tuesday's update didn't happen.
      Thursday: The TZA stop was at $18.20.  Price got down to to $18.24 at 10:07am; $18.23 at 10:18 and again at 10:49; $18.22 at 11:29 and again at 11:37; finally hit $18.20 at 12:11pm.  Meanwhile, the robot bought TNA at noon, so for 11 minutes I owned two opposing bets that cancelled each other out.
      Friday: Automatic stop-update was successful, but didn't reduce my risk much.  Monday morning’s update is predicted to be a big step up, to -3.1% max loss for TNA.  In the best case, the stop price could be above break-even by next Thursday.

Saturday, 21 April 2012

Week of 2012 AL 20

SPY rose by 0.6% this week, while my account (and loss floor) fell 0.9% to their lowest values ever.

Daily % gain
size
│Max loss│Final Gain
Sym  Buy │ Fri Mon Tue Wed Thu Fri │ Beg   End │
 
TZA  AL04 │ +1.3  29 +0.9  29 -3.8  0 │ │ -0.8%
TNA  AL17 │ -1.0  15 -3.6  14 -5.3  14 -3.7  14 │ -8.2 -8.4 │ -6.0%
SPY │ +9.3 +9.2 +10.8 +10.4 +9.7 +9.9 │ │
me │ -3.9 -3.9 -4.1 -4.5 -4.8 -4.8 │ │
floor │ -3.9 -3.9 -5.2 -5.2 -4.8 -4.8 │ │

TNA: Thursday’s IWM-stop update was “no change”, but there was some wobble in the IWM⇒TNA price conversion, so the max-loss value went down slightly.  Previously I had a TZA stop go up slightly under similar conditions.  This is just something to put with in the current design.

Stock-trading robot

Ticker
Symbol
Buy dateBuy priceSell dateSell priceAcct Profit
ModelActualMAModelActualMAMA
TNA AL 17 11:00 $57.96 $58.15 AL 19 15:00 $54.75 $54.76 -0.8% -0.9%

TNA: Rats!  Fourth loss in a row.  Paid too much on Tuesday, then got very little extra on Thursday, so actual loss ends up 0.1 %-points larger than model.

New rule: When calculating the daily stop, if the lowest price for the last N hours was during the latest hour, then sell immediately rather than raising the stop.  This improves average profit slightly, but more importantly it avoids a potential glitch: suppose the stock is in free-fall, so the current price is the lowest price.  Seconds later the robot tries to set that price as the stop, but the stock has since fallen further and so Schwab rejects the stop-order because it’s already underwater.

Bugfix: The models were not calculating their gains properly.  Basically, they were adding the transaction cost instead of subtracting it.  This is presumably why the last few trades had mismatches between model-profit and actual-profit.  This bugfix reduced apparent profit for 2008…2011 by several percent—but now it’s more realistic.

New trading model

I can haz nu model!  The design target for this model was to catch short downswings like the one that happened last week.  Also, this model avoids real-valued parameters, using moving averages and channels instead.  Because the absolute values of the indicators do not matter, I can use good ol’ MACD instead of PPO.

This is a short-selling model, meaning that I want IWM’s price to go down during the trade.  The “buy” and “sell” actions refer to SRTY, which (like TZA) is a 3× leveraged inverse ETF that tracks the Russell 2000 basket of stocks.

This model has no “buy more” signal.  Only a single tranche is ever purchased.

Buy signal:
  • Time = 10am–3pm, on the hour.
  • This hour’s price is below stop.
  • This hour’s price < SMA( 27 ).
  • Previous hour’s price < SMA( 27 ).
  • MACD( 15, 66, 9 ) < 0.0
  • MACD( 4, 16, 4 ) < its high over the previous 12 hours.
  • MACD( 4, 16, 4 ) > its low  over the previous 12 hours.
  • STDDEV( 7 ) > its EMA( 8 ).
  • I don’t currently own URTY, whose “buy” signal is a strong contrary indicator for SRTY.
  • When buying, lower stop to be no more than 2.7% higher than this hour’s price.
Sell signal:
  • Time = 10am–3pm, on the hour.
  • Either:
    • This hour’s price > SMA( 27 ).
    • MACD( 4, 16, 4 ) > its high over the previous 12 hours.
Stop update:
  • Time = 10am.
  • Calculate new stop = highest price seen in preceding 15 hours.
  • Replace stop with the newly-calculated value, unless I currently own SRTY and the new value is higher than the current one.
  • If the highest price of the last 15 hours was during the last hour, this is a “sell” signal.  Otherwise, if I currently own SRTY, convert this IWM stop to the equivalent SRTY price and update the standing sell-stop order at Schwab.

Below is a chart showing how this model would have behaved over the last four weeeks.  There were three losses and one gain, adding up to -0.1%.  Without the STDDEV requirement, the model would have bought on AL 05 instead of AL 09, for a much bigger gain and overall a profitable month.  But STDDEV is very useful: when volatility is low, most swing trades are losers.  Without it, this model would have a win:loss ratio of 114:189; with STDDEV, it’s 100:116 and the 30% profit over four years is increased to 40%.  But not so hot this month.

Summary of models

Hypothetical Historical Returns
Quarter   TNA TZA URTY SRTY  
qtr
—Total—
yr
2008 Q1 3.2% 0.5% 0.0% 1.7% 5.4% 53.3%
Q2 -2.0% -0.9% 1.1% 0.0% -1.8%  
Q3 2.8% -0.2% 5.4% 2.4% 10.4%
Q4 4.9% 15.5% 3.8% 15.1% 39.3%
2009 Q1 8.6% 4.0% 1.2% 10.3% 24.1% 59.8%
Q2 -1.5% -1.6% 21.6% -1.3% 17.2%  
Q3 7.9% 1.7% -2.0% -0.4% 7.2%
Q4 -0.2% 4.3% 4.5% 2.7% 11.3%
2010 Q1 4.0% -0.8% 0.0% -1.1% 2.1% 45.7%
Q2 -1.9% 8.0% 13.2% 4.0% 23.3%  
Q3 -1.3% 5.4% -0.6% 1.9% 5.4%
Q4 0.2% -1.2% 16.7% -0.8% 14.9%
2011 Q1 0.6% 0.9% -0.5% -1.0% 0.0% 55.4%
Q2 4.8% -1.2% -1.0% 0.2% 2.8%  
Q3 3.9% 24.2% 0.8% 6.5% 35.4%
Q4 2.3% -0.7% 3.1% 1.8% 6.5%
2012 Q1 0.4% -1.7% 12.9% -0.9% 10.7%
Total 36.7% 56.2% 80.2% 41.1% 212.8%

The robot is now using four trading models, identified here by the ticker-symbols they are supposed to trade.  These hypothetical historical returns look great on paper!  I would very much like to be making 45%‒60% per year.

In reality, I did not get the 10.7% profit shown here for 2012 Q1.  Instead, I lost 3.7% because the URTY and SRTY models hadn't been invented yet, the TNA model was improved after the fact, and I made a loser RWM trade that wasn’t justified by any model.

Below is a chart showing weekly results for all models simultaneously.  Of the 221 weeks, there are 84 losses, 41 zeroes, and 96 gains.  Any week with a gain of less than 2.7% is just paying back for the weeks with losses.  About 12% of all weeks have larger gains than that and thus are making actual progress.

Note that 2012 Q1 was a bad quarter with no large gains, except for URTY which I couldn’t actually trade because the model didn't exist yet.