Trading Range

This is one of the thinkScript studies I have been finding useful lately. It plots the trading range of a given day, week, or month. The default is to plot the range of the previous day. It draws lines for the high (red) low (green) and close (gray), the upper and lower third (orange), and the midpoint (yellow). While watching the Forex market I have found these to be common areas of support and resistance. I imagine they'll be just as useful for other markets as well.


# Trading Range
# 
# Author: Devin Christensen
# Updated: November 9, 2009
#
# http://threetrieslater.blogspot.com/search/label/thinkScript

input period = {default DAY, WEEK, MONTH};
input offset = 1;

plot "high";
plot "upper third";
plot "middle";
plot "lower third";
plot "low";
plot "close";

"high"        = high(period = period)[offset];
"low"         = low(period = period)[offset];
"middle"      = ("high" + "low") / 2;
"upper third" = "high" - ("high" - "low") * 0.3333;
"lower third" = "low" + ("high" - "low") * 0.3333;
"close"       = close(period = period)[offset];

"high".setDefaultColor(Color.RED);
"upper third".setDefaultColor(Color.DARK_ORANGE);
"middle".setDefaultColor(Color.YELLOW);
"lower third".setDefaultColor(Color.DARK_ORANGE);
"low".setDefaultColor(Color.GREEN);
"close".setDefaultColor(Color.GRAY);

"high".setStyle(Curve.SHORT_DASH);
"upper third".setStyle(Curve.SHORT_DASH);
"middle".setStyle(Curve.SHORT_DASH);
"low".setStyle(Curve.SHORT_DASH);
"lower third".setStyle(Curve.SHORT_DASH);
"close".setStyle(Curve.SHORT_DASH);

def hidden;

switch (period) {
    case DAY:
        hidden = getAggregationPeriod() >= AggregationPeriod.DAY;
    case WEEK:
        hidden = getAggregationPeriod() >= AggregationPeriod.WEEK;
    case MONTH:
        hidden = getAggregationPeriod() >= AggregationPeriod.MONTH;
}

"high".setHiding(hidden);
"upper third".setHiding(hidden);
"middle".setHiding(hidden);
"low".setHiding(hidden);
"lower third".setHiding(hidden);
"close".setHiding(hidden);

My Pivots

I find the default thinkScript implementations of Pivots a bit cumbersome with the big dotted lines that they use. It's especially apparent when I zoom out and they become the only noticeable thing on the chart. I reimplemented my own version which are not quite so visually demanding.

You can see the difference in the image. The top one is the "PersonsPivots" study which is built into Think or Swim and the lower one is my reimplemented version. Feel free to use and modify it however you like.


# Devin's Pivots
#
# Author: Devin Christensen
# Updated: October 29, 2009
#
# http://threetrieslater.blogspot.com/search/label/thinkScript

declare upper;

input period = {default DAY, WEEK, MONTH};
input auto_hide = No;

def previous_high = high(period = period)[1];
def previous_low = low(period = period)[1];
def previous_close = close(period = period)[1];
def hidden;

switch (period) {
case DAY: hidden = getAggregationPeriod() >= AggregationPeriod.DAY;
case WEEK: hidden = getAggregationPeriod() >= AggregationPeriod.WEEK;
case MONTH: hidden = getAggregationPeriod() >= AggregationPeriod.MONTH;
}

plot R3; plot R2; plot R1; plot PP; plot S1; plot S2; plot S3;

R3.SetDefaultColor(Color.RED);
R2.SetDefaultColor(Color.RED);
R1.SetDefaultColor(Color.RED);
PP.SetDefaultColor(Color.DARK_ORANGE);
S1.SetDefaultColor(Color.GREEN);
S2.SetDefaultColor(Color.GREEN);
S3.SetDefaultColor(Color.GREEN);

R3.SetStyle(Curve.LONG_DASH);
R2.SetStyle(Curve.LONG_DASH);
R1.SetStyle(Curve.LONG_DASH);
PP.SetStyle(Curve.LONG_DASH);
S1.SetStyle(Curve.LONG_DASH);
S2.SetStyle(Curve.LONG_DASH);
S3.SetStyle(Curve.LONG_DASH);

if hidden
then
{
PP = Double.NaN;
R1 = PP; S1 = PP; R2 = PP; S2 = PP; R3 = PP; S3 = PP;
}
else
{
PP = (previous_high + previous_low + previous_close) / 3;
R1 = (2 * PP) - previous_low;
S1 = (2 * PP) - previous_high;
R2 = PP + (r1 - s1);
S2 = PP - (r1 - s1);
R3 = previous_high + 2 * (PP - previous_low);
S3 = previous_low - 2 * (previous_high - PP);
}

def h = high(period = period);
def l = low(period = period);
def ah = auto_hide == yes;

R3.setHiding(ah and h<(3*R2+R3)/4); R2.setHiding(ah and h<(3*R1+R2)/4); R1.setHiding(ah and (h<(3*PP+R1)/4 or l>(3*R2+R1)/4));
PP.setHiding(ah and (h<(3*S1+PP)/4 or l>(3*R1+PP)/4));
S1.setHiding(ah and (h<(3*S2+S1)/4 or l>(3*PP+S1)/4));
S2.setHiding(ah and l>(3*S1+S2)/4);
S3.setHiding(ah and l>(3*S2+S3)/4);

The Market as a Personal Indicator

If you're in need of taking a cold hard look at yourself and need an honest mirror, start trading. Since I began trading I've been surprised at how much insight I've experienced regarding my own tendencies and behavior, as well as insight into life in general.

The market is a great educator, and it does it by always telling the truth. It never varies or tries to conceal it in anyway. The market does not sugar coat the truth when it is painful to the recipient. It freely hands it out to any who seek it. What we do with it is entirely up to us. When I started trading I came to some humbling realizations about how I react when given the truth. I realized that I have a tendency to deny the truth when it isn't what I want. At times I'd rather suffer than give up on a desire or belief that is in opposition to the truth. Eventually, thankfully, I admit defeat when in those positions and accept the loss and suffering that I have put myself through.

Trading the market is a constant reminder that whatever suffering we endure is self inflicted. It teaches that happiness and peace come from acceptance of, and conformance to, the truth; and that pain, suffering, and loss is a result of having an opinion, belief, or desire -- having a self.

I use the word conformance for a reason. From my experience conformance is a word resented by my generation, and believed to be an activity that should be avoided by all necessary means. My recent experiences have taught me that conformance leads to happiness. It should not be avoided, but embraced. Happy people are happy because they conform to rules and principles of happiness; likewise, successful people are successful because the conform to rules and principles of success, such as: hard work, discipline, and restraint.

Contrary to popular belief, conformance does not negate individuality, it amplifies it; it compliments it; it illuminates it. Every successful trader has different rules, techniques, and practices that they adhere to. These differences are a direct result of applying the rules of success to their unique characteristics -- learning how to submit their singular set of strengths, weaknesses and tendencies to the truth in a productive way.

Every trade is a choice between what you want, believe, think, feel, heard, dreamed or any combination of them, and what is real. You can resist the truth and endure suffering and pain, or you can follow it and be led to prosperity, happiness and peace.

E-Mini S&P 500 Pivots

What follows is a thinkScript implementation of the pivot calculations Peter Reznicek talks about in this screencast. These pivots are the ones used in the live ShadowTrader screen-cast for market forecasting. Those of you using the Think Or Swim trading platform can watch the live show with the following steps:

  1. Click on "Support/Chat" in the top-left corner of the main window.
  2. Select the "Chat Rooms" tab.
  3. Click on "Shadow Trader."
  4. Click the "Watch" button in the bottom right.

The script intelligently hides pivot points that do not come into play in the current day. Setting "auto hide" to "No" will turn this feature off.


# Futures Pivots
#
# Author: Devin Christensen
# Updated: September 18, 2009
#
# http://threetrieslater.blogspot.com/search/label/thinkScript

# Settlement prices can be found
# at http://www.cmegroup.com
# The E-MINI S&P 500 settlement prices are
# at http://bit.ly/191yhS

declare upper;

input _high = 1043.75;
input _low = 1033.50;
input settle = 1041.50;
input auto_hide = Yes;

def hidden = getDay() < getLastDay() or getAggregationPeriod() >= AggregationPeriod.DAY;

plot R3;
plot R2;
plot R1;
plot PP;
plot S1;
plot S2;
plot S3;

R3.SetDefaultColor(Color.RED);
R2.SetDefaultColor(Color.RED);
R1.SetDefaultColor(Color.RED);
PP.SetDefaultColor(Color.DARK_ORANGE);
S1.SetDefaultColor(Color.GREEN);
S2.SetDefaultColor(Color.GREEN);
S3.SetDefaultColor(Color.GREEN);

R3.SetStyle(Curve.FIRM);
R2.SetStyle(Curve.LONG_DASH);
R1.SetStyle(Curve.SHORT_DASH);
PP.SetStyle(Curve.SHORT_DASH);
S1.SetStyle(Curve.SHORT_DASH);
S2.SetStyle(Curve.LONG_DASH);
S3.SetStyle(Curve.FIRM);

if hidden
then
{
PP = Double.NaN;
R1 = PP; S1 = PP; R2 = PP; S2 = PP; R3 = PP; S3 = PP;
}
else
{
PP = (_high + _low + settle) / 3;
R1 = (2 * PP) - _low;
S1 = (2 * PP) - _high;
R2 = PP + (r1 - s1);
S2 = PP - (r1 - s1);
R3 = _high + 2 * (PP - _low);
S3 = _low - 2 * (_high - PP);
}

def dh = high(period = "DAY");
def dl = low(period = "DAY");
def ah = auto_hide == Yes;

R3.setHiding(ah and (dh < (3*R2+R3)/4)); R2.setHiding(ah and (dh < (3*R1+R2)/4)); R1.setHiding(ah and (dh < (3*PP+R1)/4 or dl > (3*R2+R1)/4));
PP.setHiding(ah and (dh < (3*S1+PP)/4 or dl > (3*R1+PP)/4));
S1.setHiding(ah and (dh < (3*S2+S1)/4 or dl > (3*PP+S1)/4));
S2.setHiding(ah and (dl > (3*S1+S2)/4));
S3.setHiding(ah and (dl > (3*S2+S3)/4));

Volume Weighted Average Price

The VWAP is a study I've often referred to but is missing on the Think Or Swim trading platform. They do include a VWAP study but it is only calculated for individual bars. I wanted one that aggregated over the entire trading day.

I pulled up the thinkScript Manual and got to work. It took some fiddling but I was able to figure out how to achieve the desired functionality. As you can see from the screen shot (the VWAP is the gray line) the VWAP is a common area of both support and resistance. Divergence from the VWAP also provides an indication of the strength or weakness of the stock during the current trading day.


# Intraday VWAP
#
# Author: Devin Christensen
# Updated: September 18, 2009
#
# http://threetrieslater.blogspot.com/search/label/thinkScript

rec current_period = getDay();
rec period_volume;
rec period_vwap;

if current_period != current_period[1]
then {
period_volume = volume();
period_vwap   = volume() * vwap();
}
else
{
period_volume = period_volume[1] + volume();
;period_vwap   = period_vwap[1] + volume() * vwap();
}

plot vwap = period_vwap / period_volume;

vwap.SetHiding(getAggregationPeriod() >= AggregationPeriod.DAY);
vwap.SetDefaultColor(Color.GRAY);

I also created a moving VWAP while I was at it. I don't actually refer to this one much but have seen it in other charting packages and it was easy to implement.


# Moving VWAP
#
# Author: Devin Christensen
# Updated: September 18, 2009
#
# http://threetrieslater.blogspot.com/search/label/thinkScript

input length = 10;
rec vwaps = vwap() * volume();
plot MovingVWAP = sum(vwaps, length) / sum(volume, length);

MovingVWAP.setDefaultColor(Color.GRAY);

A Conversation With Myself

I was testing functionality of a software package I'm evaluating for work. What follows is a conversation I had with myself while viewing a page that allowed me to add notes to an account.

Checking out how notes work.
What if I add a bunch of notes?
How many notes are we talking about?
Lets say, 50. 50 notes!
50 is a lot of notes, do you really think you can type 50 notes?
Perhaps. It is a big job, but I think I can manage.
Alright, well good luck. Looks like you only have 43 notes to go.
Oh man! I really thought I had typed more than that already. Maybe I should hire someone to come type in notes, so I can focus on other things.
That's not a bad idea. Do you want me to write the notes? I charge a meager some of $20/hour.
Whoa! That's a lot for writing notes. It's so simple a monkey could do. You really think I'm gonna pay someone $20/hour to write notes? You gotta be mad if you think that! Tell you what. I'll pay you a penny per note, how's that sound?
No way! I could earn more money scratching my nose! I think you're on your own, I've never been so insulted in my life! A penny per note? Do you not realize how creative and inspiring my notes will be? The world will be a better place times a thousand for each note that I write, and all I asked was for a meager sum of $20/hour. I was trying to do you a favor! My notes are priceless!
No, no. You don't understand. We don't want inspiring notes. We just want meaningless drivel so we have data to test. We don't have time to be inspired. We have work to do.
Well I'm sorry, but I refuse to lower myself to such a level. I'd prefer not to spend my time working on meaningless drivel. I'd rather do nothing then spend my talents in such an absurd manner!
I'm not saying you have to. You can write the most inspired and eloquent notes in the history of the universe, but we can only pay you for uninspired drivel, because that's all we need.
Why on earth would I do such a thing? My notes would never be appreciated as they should. What a waste!
Perhaps, or is the bigger waste to withhold your talents because you feel they are too good to be mingled with such "lowly" work? We'll get our meaningless drivel one way or the other, but you'll never recover from neglecting to achieve your potential.

Apologies

Often times I have ideas that come and go throughout the week that I find intriguing or personally helpful. I've been sitting on this one for a while and wanted to write it before it re-submerged itself into the depths of my unorganized mind.

A fairly recent encounter with a personal friend left me feeling the desire to make amends in the form of a verbal apology. When I made the attempt I was met with an assurance that no offense was taken and that no apology was necessary; however, I still felt that I needed forgiveness, and it was politely, but hesitantly, granted. As I pondered over the events I wondered what motivates a person, or rather, what should motivate a person to apologize. I have concluded that forgiveness should not be sought after only when offense is taken, but whenever actions are not in accordance with the character that a person is trying to build within themselves.

To be fair, I have too been on the receiving end of an apology I did not think necessary. I can empathize with the awkward feelings they can invoke. Why is it that we should be hesitant to accept a sincere desire to make amends? I pondered upon this as well. In my encounter my desire to apologize was prompted by a recognition that I treated my friend in a way below that which I felt was deserved. And I think that's exactly why we can be hesitant to accept. Accepting an apology also means accepting that you instilled within someone the desire to be better than they currently are. This can be especially daunting if you question your own self worth.

No. The default response is to assure them that no change is necessary -- that they are fine just the way they are. That's the easy way at least. That way we not only avoid feeling like we caused someone to feel bad about themselves, but we also avoid the much scarier notion -- that someone found something within us that inspires them to be better -- that we might actually be worth it. It takes a brave soul to offer a sincere apology, but it takes an even braver one to forgive -- to bear the responsibility of knowing you've been an inspiration of change for the better, but maybe we should make this the default.