-
Notifications
You must be signed in to change notification settings - Fork 96
/
TOS & Thinkscript Collection.xml
8779 lines (7738 loc) · 493 KB
/
TOS & Thinkscript Collection.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<?asciidoc-toc maxdepth="3"?>
<?asciidoc-numbered?>
<article xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
<info>
<title>TOS & Thinkscript Collection</title>
<date>April 14, 2018</date>
<author>
<personname>
<firstname>Jim</firstname>
<surname>Shinger</surname>
</personname>
<email>[email protected]</email>
</author>
<authorinitials>JS</authorinitials>
<revhistory>
<revision>
<revnumber>0.1</revnumber>
<date>April 14, 2018</date>
<authorinitials>JS</authorinitials>
</revision>
</revhistory>
</info>
<section xml:id="preface">
<title>Preface</title>
<simpara>The "TOS and Thinkscript Snippet Collection" by <link xl:href="http://mytrade.com/StanL">Stanl</link>
has been a great help in my thinkscript development journey. I constantly look
to this work for ideas and techniques.</simpara>
<simpara>It appears that "TOS and Thinkscript Snippet Collection" hasn’t been update in
3 years as of this writing, …​ I am not sure if something happened to StanL or what.</simpara>
<simpara><emphasis role="strong">My Motivations:</emphasis> I found the pdf hard to read at times and I want the great work
StanL did to live on. So I converted the PDF to Asciidoctor html format.
<link xl:href="https://github.com/jshingler/TOS-and-Thinkscript-Snippet-Collection">TOS-and-Thinkscript-Snippet-Collection</link>.</simpara>
<simpara>As converting from PDF is a lot of work, …​ This is a work in
process and I will continue to work on the formatting and clean up.</simpara>
<simpara>Please feel free to fork and send me pull requests or corrections and additions.</simpara>
<simpara>Credits: <link xl:href="http://mytrade.com/StanL">StanL</link> <link xl:href="http://mytrade.com/StanL">http://mytrade.com/StanL</link></simpara>
<simpara>TEST - Jim Shingler</simpara>
<programlisting language="groovy" linenumbering="numbered">file1.eachLine { line ->
//println ">${line}<"
if (line.startsWith("- ") && !line.startsWith("- NEXT")) {
l1 = line.replace("- ","")
l2 = line.toUpperCase().split(/\./)[0].trim()
//println "l2>${l2.split(/\-/).size()} <l2"
if (l2.split(/\-/).size() > 2) {
l3 = l2.split(/\-/)[2]
.replaceAll(" ","_")
.replaceAll("'","")
.replaceAll(",","")
.replaceAll("\\(","")
.replaceAll("\\)","")
.replaceAll("&","AND")
println "- [${l1}](#$l3)"
println "<a name=\"${l3}\"> </a>"
}
} else {
println line
}
}</programlisting>
</section>
<section xml:id="introduction">
<title>Introduction</title>
<section xml:id="snippet">
<title>Snippet</title>
<simpara>A 'snippet' is a small piece(s) of script, oriented towards accomplishing a specific
function identified by the snippet’s title:Sort of a building block. This PDF takes
the liberty to include TOS-platform-features that are not only script snippets but
may be any TOS features worth knowing. Perhaps this document can, more appropriately,
be call an 'Almanac'.</simpara>
<simpara>The emphasis herein is for learning TOS and ThinkScript from the ground up. Numerous examples are used as a learning tool ranging from simple/basic to complex. The PDF format was selected, with extra features, like the hyperlinked Table-of-Contents, to make subjects easily found. This document also proovides a reference for future coding activities.</simpara>
<simpara>Hence being familar with what is available herein, will enhance recall when needed. A good PDF reader with search capability is also recommended.</simpara>
</section>
<section xml:id="legend">
<title>Legend</title>
<simpara>Click the underlined Page ? to go to that page When there, you can return to to the TOC by clicking Return to TOC.</simpara>
<simpara>Titles appearing in the Table Of Contents above are the same and colored blue throughout this document</simpara>
</section>
<section xml:id="revised-07-25-14">
<title>Revised: 07/25/14</title>
</section>
<section xml:id="organization">
<title>Organization:</title>
<simpara>The first letter indicates the category of the subject.</simpara>
<simpara>B- = Basic platform or coding subjects, fundamental principles, fundamental examples and how-to-do’s</simpara>
<simpara>S- = Scan</simpara>
<simpara>C- = Coding of studies, strategies, snippets, et al that accomplish a purpose/result</simpara>
<simpara>T- = A Tip or Trick on how you might use TOS or TS to accomplish a specific useful purpose</simpara>
<simpara>?- = In the subject’s heading, ? means that the data is variable 'inputted' data defined by the user</simpara>
<simpara>C&S- = On occasion, a item may also have multiple codes defining what is included inside. For example, this symbol indicates when scan code is included.</simpara>
</section>
<section xml:id="acknowledgements">
<title>Acknowledgements</title>
<simpara>The people on the ThinkScript Lounge and Yahoo TOS_ThinkScript generously contribute much time and effort helping those learning and using ThinkOrSwim and ThinkScript. Many items herein originated on the those chatroom postings.</simpara>
<simpara>Much credit and thanks are due those people. We are all grateful to them for their selfless contributions.</simpara>
</section>
<section xml:id="usage">
<title>Usage</title>
<simpara>Although a subject may not be of interest to you, the coding techniques involved may be pertinent to what you desire to code, either today or at some time in the future. It is useful to be aware of the techniques so that, when the time comes, you will know where to look to get the how-to-do specifics.</simpara>
<simpara>Hope you find this document useful. Any suggestion for improvement or inclusion are welcome.</simpara>
</section>
<section xml:id="acronyms-used-herein">
<title>Acronyms used herein</title>
<informaltable frame="all" rowsep="1" colsep="1">
<tgroup cols="2">
<colspec colname="col_1" colwidth="50*"/>
<colspec colname="col_2" colwidth="50*"/>
<tbody>
<row>
<entry align="left" valign="top"><simpara>TOS</simpara></entry>
<entry align="left" valign="top"><simpara>ThinkOrSwim</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>TS</simpara></entry>
<entry align="left" valign="top"><simpara>ThinkScript</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>WLC</simpara></entry>
<entry align="left" valign="top"><simpara>An abbreviation for "WatchList Column"</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>TOC</simpara></entry>
<entry align="left" valign="top"><simpara>'Table Of Contents' in this document</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>PDF</simpara></entry>
<entry align="left" valign="top"><simpara>Portable Document Format = the type of file format of this document. Readers of PDF files are readily available. See REFERENCES for a reader source.</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>SD</simpara></entry>
<entry align="left" valign="top"><simpara>Standard Deviation</simpara></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<simpara>Use of '…​' and "…​" Often the single and double quotes are used to identify precise coding, words or statements whose use is not intended to include the quote marks themselves. At times coloring may also be used to do the same.</simpara>
<simpara>'Pre-defined' and 'built-in' are synonymous when referring to studies that are provided by TOS within the program. The coding of these may be copied and reused in your own studies but built-ins cannot be changed.</simpara>
</section>
<section xml:id="suggestion-for-ease-of-use">
<title>Suggestion for Ease-of-Use</title>
<simpara>As this Snippet Collection grows, finding what you want becomes more difficult. It is recommended that you use a good PDF reader that has good navigation and search/find capabilities. There are many readers available but the recommended one is listed in the References at the end of this document.</simpara>
<simpara>If you want to find something, enter what you want into the 'find' tool of the PDF reader and it will navigate you to the possible matches. Try different 'find' entries if you are not successful. Subjects are often named differently. The most expeditious search is looking over the TOC or using 'find' in the TOC as opposed to using 'find' throughout the body of the document.</simpara>
</section>
</section>
<section xml:id="basic-coding-and-platform-principles">
<title>Basic Coding and Platform Principles</title>
<section xml:id="add-info-bubbles-to-a-study-or-a-study-s-inputs">
<title>Add Info Bubbles To a Study or a Study’s Inputs</title>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/2-1.png"/>
</imageobject>
<textobject><phrase>Info Bubble</phrase></textobject>
</mediaobject>
</informalfigure>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/2-2.png"/>
</imageobject>
<textobject><phrase>Info Bubble</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>As shown above the study list and the inputs have info bubbles. You may add these info bubbles to your studies.</simpara>
<simpara>To make an 'Info Bubble' for a study and strategy:</simpara>
<orderedlist numeration="arabic">
<listitem>
<simpara>Above the code lines, place <literal>#hint: ????????</literal> where ???????? is the description you want displayed when the bubble is clicked.</simpara>
</listitem>
<listitem>
<simpara>The tags listed under 'TAGS and their PURPOSE:' may be used to format the ????????.</simpara>
</listitem>
<listitem>
<simpara>An example is --→ <literal>#hint: Plots a <b>trend line</b> between the two input dates.</literal></simpara>
</listitem>
</orderedlist>
<simpara>To make an 'Info Bubble' for 'Edit Studies' input</simpara>
<orderedlist numeration="arabic">
<listitem>
<simpara>Immediately after the semi-colon on the input’s line (preferred location), place <literal>#hint <the input variable name>: (the desired text you want displayed when the bubble is clicked)</literal> .</simpara>
</listitem>
<listitem>
<simpara>The tags listed under 'TAGS and their PURPOSE:' may be used to format the desired text.</simpara>
</listitem>
<listitem>
<simpara>An example is --→ <literal>input Length = 10 #hint Length: The number of bars used to calculate the average.</literal></simpara>
</listitem>
<listitem>
<simpara>Notice that the colon is placed after the input variable name (in this case Length).</simpara>
</listitem>
</orderedlist>
<simpara>Formatting is possible using HTML tags. Some of the common tags you may be interested in are listed below:</simpara>
<simpara><emphasis>TAGS and their PURPOSE:</emphasis></simpara>
<screen><b> ......... </b> Makes the text between the tags bold.
\n Starts a new line
<li>........... </li> Creates indented lists</screen>
<simpara>Example of the following script and its result:</simpara>
<simpara><literal>#hint: <b>Bar Count Between Highs</b>\n Counts the number of bars between each high in the specified length.</literal></simpara>
</section>
<section xml:id="if-expressions-and-statements-explained">
<title>IF EXPRESSIONS AND STATEMENTS EXPLAINED</title>
<simpara>There are three forms of if statements. The <emphasis>'immediate-if'</emphasis> is the shortest and is documented at</simpara>
<itemizedlist>
<listitem>
<simpara><link xl:href="http://demo.thinkorswim.com:7001/manual/metal/thinkscript/reference/Functions/Others/If.html">http://demo.thinkorswim.com:7001/manual/metal/thinkscript/reference/Functions/Others/If.html</link> . The other two are</simpara>
</listitem>
<listitem>
<simpara>the <emphasis>'if-expression'</emphasis> and the <emphasis>'if-statement'</emphasis>, both of which are documented at</simpara>
</listitem>
<listitem>
<simpara><link xl:href="http://demo.thinkorswim.com:7001/manual/metal/thinkscript/reference/Reserved%20Words/if.html">http://demo.thinkorswim.com:7001/manual/metal/thinkscript/reference/Reserved%20Words/if.html</link> . The thinkscript documentation infers that there are more forms of the if-then-else, but the additional examples are merely the base form shown with nested if-then-else statements/expressions.</simpara>
</listitem>
</itemizedlist>
<section xml:id="the-immediate-if-explained">
<title>The 'immediate-if' explained</title>
<simpara>The syntax is: <literal>If(double condition, double true value, double false value);</literal> This is the simplest and easiest to use. An example is: <literal>Plot Maximum1 = If(close > open, close, open);</literal> This reads as “If the close is greater than the open, then plot the close. Otherwise/else, if the close is not greater than the open, then plot the open.” This form is very useful as the right-hand side of the equal sign in a Plot or Def statement. Also this form can be used with <literal>else</literal> to create more complex conditions. This form is a function and returns a type of double that is very useful for the if-then-else statements/expressions when you are processing numbers and nesting.</simpara>
<simpara>The word 'double' is often vague in its meaning in ThinkScript but it means a floating-decimal-point-number of double precision in programming terminology. Any further meaning-clarification is unnecessary here. The impact of 'double' is that constants such as the names of the 23 ThinkScript colors, like LIGHT_RED, BLUE, UPTICK, etc., are not floating point numbers and hence cannot be used in this immediate-if. In this case, the if-expression would be used.</simpara>
</section>
<section xml:id="the-if-expression-explained">
<title>The 'if-expression' explained</title>
<simpara>The syntax is: <literal>if close > open then close else open;</literal> An example is: <literal>plot Maximum2 = if close > open then close else open;</literal> An <emphasis>IF…​.THEN…​.ELSE</emphasis> are all required. A nesting (putting if’s within if’s) example, in the recommended layout for easy reading, is:</simpara>
<screen>plot Maximum2 = if close > open
then close
else if close = open
then (low + high)/2
else open;</screen>
<simpara>Note that the last <literal>'else open'</literal> relates to the <literal>'if close > open'</literal> and applies when the intermediate 'else-if close = open' is not true. This nested-if reads as: If close is greater than the open then plot the close. If the close equals the open then plot the (low + high)/2 . If the close is not greater than the open and the close does not equal the open, then plot the open.</simpara>
<simpara>The if-expression will have only one semi-colon that will terminate the entire expression, regardless of the complexity.</simpara>
</section>
<section xml:id="the-if-statement-explained">
<title>The 'if-statement' explained</title>
<simpara>The syntax and example is:</simpara>
<screen>plot Maximum3;
if close > open [then]{
Maximum3 = close;
} else {
Maximum3 = open;
}</screen>
<simpara>The <literal>'[then]'</literal> above means that it is optional but it is recommended that it always be used for clarity. Notice that each statement is enclosed within a block <emphasis>(the parts enclosed in the { } )</emphasis> and must end with a semi-colon.</simpara>
<simpara>Comparison of all three 'if' syntaxs</simpara>
<screen>plot Maximum1 = If(close > open, close, open); # This is the immediate-if syntax
plot Maximum2 = if close > open then close else open; # This is an if-expression
plot Maximum3; # This and the lines below make up an if-statement
if close > open {
Maximum3 = close;
} else {
Maximum3 = open;
}</screen>
<simpara>Excellent examples of the power of if..then..else can be seen in these documents herein:</simpara>
<simpara>ADD AN INDEX OR FUTURE LOWER CHART and SLOPE OF AN AVERAGE</simpara>
</section>
</section>
<section xml:id="change-the-coloring-of-a-plot-based-on-a-condition">
<title>CHANGE THE COLORING OF A PLOT BASED ON A CONDITION</title>
<literallayout class="monospaced">A very favorite feature is to change the color of a plot based on a condition that you define. The 'HullMovingAvg' illustrates this very well. Here is its code:</literallayout>
<screen>input price = close;
input length = 20;
input displace = 0;
plot HMA = MovingAverage(AverageType.HULL, price, length)[-displace];
HMA.DefineColor("Up", GetColor(1));
HMA.DefineColor("Down", GetColor(0));
HMA.AssignValueColor(if HMA > HMA[1] then HMA.color("Up") else HMA.color("Down"));</screen>
<simpara>In the above HMA>HMA[1] is the condition that says <emphasis>IF</emphasis> the current HMA is greater than the previous value of the HMA, i.e. HMA > HMA[1] , <emphasis>THEN</emphasis> paint the plot with the “Up” color which is defined as color(1) <emphasis>OTHERWISE/ELSE</emphasis> paint the plot with the “Down” color which is defined as color (2). (1) and (2) are color index numbers. Color-assigned-index-numbers are explained in the separate topic.</simpara>
<simpara>The condition is always in a 'if…​. then…​. else' format. If-statements may be nested without limits. The format thenbecomes 'if…​..then…​.. else if…​..then…​..else if…​..then…​…​else'. The closing 'else' is always present and relates to the initialif…​. then when none of the nested if …​then’s produce a result.</simpara>
<simpara>Example:</simpara>
<simpara><literal>if SlowK > SlowD then color.green else if SlowK < SlowD then color.red else color.gray</literal></simpara>
<simpara>The multiple conditions may be used to define a conditional statements. They are joined by <literal>'and'</literal> or its equivalent <literal>'&&'</literal>.</simpara>
<simpara>Example:</simpara>
<simpara><literal>def RangeCondition = ADX > 0 && ADX < 13;# ADX is between 0 and 13</literal></simpara>
<simpara>Conditions may be nested as in this example:</simpara>
<screen>Diamonds.AssignValueColor(
If BullishCondition then color.green else
If RangeCondition then color.white else
If BearishCondition then color.red else
color.black);</screen>
<simpara>Note in the above, since color.green, color.white, color.red and color.black are constants and not double variables, the if-expression must be used and that requires the presence of all <emphasis>IF…​..THEN…​..ELSE</emphasis> parts.</simpara>
<simpara>Here is another example of multiple coloring in a label:</simpara>
<screen>AddLabel(1, Concat("IV Percentile ", AsPercent(perct)), if perct > 0.80
then Color.Green
else if perct < 0.80 and perct > 0.50
then Color.Yellow
else color.Red);</screen>
</section>
<section xml:id="how-thinkscript-calculates">
<title>HOW THINKSCRIPT CALCULATES</title>
<simpara>In scans, conditional orders, and custom quotes there is only one bar, the latest or current bar. All scripts are run in real-time and the script processor only runs one iteration of the script. So within that context, certain functions make no sense, like barNumber(), HighestAll() to name a few, also rec variables. Functions that take a look back value or length, such as average( data, length ), highest( data, length ), etc. work because the internal logic of the function performs the action of looking back. No matter what the timeframe, in those contexts (scans, etc.), your script only runs once and only against the current (latest) bar.</simpara>
<simpara>In studies or strategies, ThinkScript runs your script once <emphasis>for each and every bar</emphasis> on your chart, regardless of the aggregation period.</simpara>
<simpara>You will often hear knowledgeable programmers say with disappointment that 'ThinkScript' does not have arrays. Arrays are a common powerful programming feature for storing/recalling various data and data types. This is a limitation of ThinkScript that we must live with as best we can.</simpara>
</section>
<section xml:id="colors-as-used-in-tos-thinkscript">
<title>COLORS AS USED IN TOS/THINKSCRIPT</title>
<simpara>TOS has defined ten colors corresponding to index numbers on two different background colors as below:</simpara>
<simpara>The colors are used via the function <literal>'GetColor(index number);'</literal> Example: GetColor(1) as used in the HullMovingAvg previous topic. Reference: [See Index Colors]<indexterm><primary><link xl:href="https://tlc.thinkorswim.com/center/charting/thinkscript/reference/Functions/Look---Feel/GetColor.html">https://tlc.thinkorswim.com/center/charting/thinkscript/reference/Functions/Look---Feel/GetColor.html</link></primary></indexterm><link xl:href="https://tlc.thinkorswim.com/center/charting/thinkscript/reference/Functions/Look---Feel/GetColor.html">https://tlc.thinkorswim.com/center/charting/thinkscript/reference/Functions/Look---Feel/GetColor.html</link></simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/6-1.png"/>
</imageobject>
<textobject><phrase>6 1</phrase></textobject>
</mediaobject>
</informalfigure>
<table frame="all" rowsep="1" colsep="1">
<title>Table Colors</title>
<tgroup cols="3">
<colspec colname="col_1" colwidth="33.3333*"/>
<colspec colname="col_2" colwidth="33.3333*"/>
<colspec colname="col_3" colwidth="33.3334*"/>
<thead>
<row>
<entry align="left" valign="top">Index</entry>
<entry align="left" valign="top">RGB Values</entry>
<entry align="left" valign="top">Name of Color</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>0</simpara></entry>
<entry align="left" valign="top"><simpara>255,16,253</simpara></entry>
<entry align="left" valign="top"><simpara>magenta</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>1</simpara></entry>
<entry align="left" valign="top"><simpara>0,255,255</simpara></entry>
<entry align="left" valign="top"><simpara>cyan</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>2</simpara></entry>
<entry align="left" valign="top"><simpara>255,174,174</simpara></entry>
<entry align="left" valign="top"><simpara>pink</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>3</simpara></entry>
<entry align="left" valign="top"><simpara>191,191,191</simpara></entry>
<entry align="left" valign="top"><simpara>white</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>4</simpara></entry>
<entry align="left" valign="top"><simpara>254,199,22</simpara></entry>
<entry align="left" valign="top"><simpara>gold</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>5</simpara></entry>
<entry align="left" valign="top"><simpara>255,3,2</simpara></entry>
<entry align="left" valign="top"><simpara>red</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>6</simpara></entry>
<entry align="left" valign="top"><simpara>0,254,30</simpara></entry>
<entry align="left" valign="top"><simpara>green</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>7</simpara></entry>
<entry align="left" valign="top"><simpara>127,127,127</simpara></entry>
<entry align="left" valign="top"><simpara>dark_gray</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>8</simpara></entry>
<entry align="left" valign="top"><simpara>254,254,31</simpara></entry>
<entry align="left" valign="top"><simpara>yellow</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>9</simpara></entry>
<entry align="left" valign="top"><simpara>255,255,255</simpara></entry>
<entry align="left" valign="top"><simpara>white</simpara></entry>
</row>
</tbody>
</tgroup>
</table>
<simpara>This free tool will help you to get the RGB values for any color you desire to compose.</simpara>
<simpara><link xl:href="http://www.colorschemer.com/online.html">http://www.colorschemer.com/online.html</link></simpara>
<simpara>TOS has also assigned names to 23 colors per the following:</simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/6-2.png"/>
</imageobject>
<textobject><phrase>6 2</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>Reference: [See all color constants](<link xl:href="https://www.thinkorswim.com/tos/thinkScriptHelp.jsp?laf=dark#constants">https://www.thinkorswim.com/tos/thinkScriptHelp.jsp?laf=dark#constants</link>)</simpara>
<simpara>Note that colors 'UPTICK' and 'DOWNTICK' are defined respectively as a red and green tone because they are frequently used in chart coloring. In the above chart the capitalized words are the names used to specify that color i.e. color.CYAN or color.LIGHT_RED.</simpara>
<simpara>Not all colors are defined: for example, PURPLE. You may find any color at</simpara>
<simpara><link xl:href="http://en.wikipedia.org/wiki/List_of_colors:_A%E2%80%93F">http://en.wikipedia.org/wiki/List_of_colors:_A%E2%80%93F</link> or <link xl:href="http://en.wikipedia.org/wiki/X11_color_names">http://en.wikipedia.org/wiki/X11_color_names</link> .</simpara>
<simpara>You can create that color for use in TOS by using the function 'CreateColor(double red, double green, double blue); ' similar to the RGB Code in the chart above. Each RGB component ranges in value from 0 (meaning none or 0%) to 255 (meaning the max 100% value).</simpara>
<simpara>You may also assign a text-name, for later use, to any color you create via</simpara>
<simpara><literal>DefineGlobalColor("Purple" , CreateColor(160,32,240) );</literal></simpara>
</section>
<section xml:id="often-used-coloring-code-statements">
<title>OFTEN USED COLORING CODE STATEMENTS</title>
<note>
<simpara>When writing code you may not have the coloring coding at your finger tips. This provides a ready place to go to to get the code words to paste.</simpara>
</note>
<section xml:id="typical-chart-plot-settings">
<title>Typical chart plot settings</title>
<screen>Data.SetPaintingStrategy(PaintingStrategy.LINE);# See Others Painting Strategies below.
Data.SetLineWeight(1);# 1 thru 5. 1 is the default if 'SetLineWeight' is not defined.
Data.SetDefaultColor(Color.White); #Color.'TOS predefined color constant'</screen>
<simpara>See all predefined color constants: See predefined color constants</simpara>
</section>
<section xml:id="other-painting-stategies">
<title>Other Painting Stategies</title>
<screen>- ARROW_DOWN, ARROW_UP, BOOLEAN_ARROW_DOWN, BOOLEAN_ARROW_UP, BOOLEAN_POINTS,
- DASHES, HISTOGRAM, HORIZONTAL, LINE, LINE_VS_POINTS, LINE_VS_SQUARES, LINE_VS_TRIANGLES,
- POINTS, SQUARED_HISTOGRAM, SQUARES, TRIANGLES, VALUES_ABOVE, VALUES_BELOW</screen>
<simpara>LINE is the default if none is specified.</simpara>
<screen>##### For curves define the line styles ####
Data.SetStyle(Curve.SHORT_DASH);</screen>
<simpara>Other constants:</simpara>
<itemizedlist>
<listitem>
<simpara>FIRM, LONG_DASH, MEDIUM_DASH, SHORT_DASH, POINTS</simpara>
</listitem>
<listitem>
<simpara>SHORT_DASH is the default value of 'SetStyle'</simpara>
</listitem>
</itemizedlist>
<section xml:id="assign-a-name-to-a-color">
<title>Assign a name to a color</title>
<simpara>You may assign a name to a color like:</simpara>
<screen>Plot RSI = 50 * (ChgRatio + 1);
RSI.DefineColor("Normal", GetColor(7));</screen>
<simpara>The name "normal" above is unique to the RSI plot. Another plot cannot use the name 'normal' without redefining it.</simpara>
<simpara>To define and name a color for use in multiple plots do as follows:</simpara>
<screen>DefineGlobalColor("normal", CreateColor(128, 0, 128));
plot signal = high > Highest(high[1]);
signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
signal.SetDefaultColor(GlobalColor("normal"));
plot NinetyPercent = 0.9*close;
NinetyPercent.SetDefaultColor(GlobalColor("normal"));</screen>
</section>
</section>
<section xml:id="color-based-on-a-condition">
<title>Color based on a condition</title>
<screen>plot Diff = close - close[1];
Diff.assignValueColor(if Diff >= 0 then Color.UPTICK else Color.DOWNTICK);</screen>
<simpara>Note that UPTICK and DOWNTICK are TOS predefined color constants</simpara>
</section>
<section xml:id="create-your-own-color">
<title>Create your own color</title>
<screen>plot Price = close;
Price.SetDefaultColor(CreateColor(255, 220, 210));</screen>
<simpara>Or</simpara>
<simpara><literal>DefineGlobalColor("Purple" , CreateColor(160,32,240) );</literal></simpara>
<simpara>After the above global definition, GlobalColor("Purple") can be use wherever a color is needed. For example:</simpara>
<simpara><literal>Price.SetDefaultColor(GlobalColor("Purple"));</literal></simpara>
</section>
<section xml:id="use-predefined-index-colors">
<title>Use predefined index colors</title>
<screen>plot Price = close;
Price.SetDefaultColor(GetColor(1));# 1 is an index color of 0 thru 9</screen>
<simpara>Reference: See all color index numbers</simpara>
</section>
<section xml:id="default-and-global-color-text-names">
<title>Default and global color text names</title>
<screen>plot Data = close;
Data.SetDefaultColor(color.RED);</screen>
<simpara>or</simpara>
<simpara><literal>Data.SetDefaultColor(GlobalColor("normal"));# Provided 'normal' is previously defined.</literal></simpara>
</section>
</section>
<section xml:id="implementing-labels">
<title>IMPLEMENTING LABELS</title>
<simpara>Labels are boxes of info placed at the top-left of a study. They are very useful and well worth the time to master them.</simpara>
<simpara>The label function is <literal>AddLabel(boolean visible, Any text, CustomColor color);</literal> and has three components.</simpara>
<orderedlist numeration="arabic">
<listitem>
<simpara><literal>' boolean visible'</literal> is a true or false statement that defines when the label shows or doesn’t show. If you use a '1' or 'yes' here it will always show the label, Otherwise you define a condition or an input selection-value that evaluates to 'true' or 'false' and reference that condition statement here.</simpara>
</listitem>
<listitem>
<simpara><literal>'Any text'</literal> is what appears inside the label box. There are two way to compose this text using 'concat' or '+' syntax(known as the string concatenation symbol). Concat is a term that means to connect two text phrases together. This includes converting ThinkScript variable-values into text.</simpara>
</listitem>
<listitem>
<simpara><literal>' CustomColor color'</literal> defines the background color of the label box. The text font color is always black.</simpara>
</listitem>
</orderedlist>
<section xml:id="boolean-visible">
<title>boolean visible</title>
<simpara>This can be a <literal>'yes'</literal> or <literal>'no'</literal>, or any condition statement or a reference to: (1) a previously defined condition statement; or (2) an input true/false value. When this evaluates to 'true' then the label will show or, when false, will not show. This is very handy when referring to an input whose value choices are <literal>'yes'</literal> or <literal>'no'</literal>. Programmers use the yes/no input in condition statements to display or not-display certain features such as the labels or plots.</simpara>
</section>
<section xml:id="any-text">
<title>Any text</title>
<simpara>The label’s text can be defined using using <literal>'concat'</literal> or <literal>'+'</literal> which is known as the string concatenation symbol. Using the <literal>'+'</literal> symbol is much easier to master and is recommended. Examples will help explain:</simpara>
<screen>input weeks = 4;
AddLabel(yes, concat(weeks, " Weeks till expiration"), color.YELLOW);</screen>
<simpara>produces the following label:</simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/8-1.png"/>
</imageobject>
<textobject><phrase>8 1</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>Using the '' symbol …. `AddLabel(yes, weeks + " Weeks till expiration", color.YELLOW);` produces the same label as above. You will find that complex texts with numerous segments are much easier to compose using the '' symbol. There is, however, one pitfall to be avoided using the '+' symbol as discussed below:</simpara>
<simpara>The key is when using the + syntax, one must put all calculations-within-a-label inside of parentheses. Also multiple conditions such as HiTrue && LoTrue should be within parenthesis like (HiTrue && LoTrue).To illustrate this, a right and wrong is shown below:</simpara>
<simpara>This works:</simpara>
<screen>input ManADR = 25;
Addlabel(yes,"Exit = Stop Loss @ 10% of ADR = " + (0.10 * ManADR) ,color.PINK);</screen>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/8-2.png"/>
</imageobject>
<textobject><phrase>8 2</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>This is wrong and produces an error:</simpara>
<simpara><literal>Addlabel(yes,"Exit = Stop Loss @ 10% of ADR = " + 0.10 * ManADR ,color.PINK);</literal></simpara>
<simpara>See also LITERAL TEXT IN LABEL FOR THE 11 CHOICES OF INPUT PRICE and C-% CHANGE OF THE FIRST BAR VALUE and C-ADD AN INDEX OR FUTURE LOWER CHART for examples of putting drop-down literals into label text.</simpara>
</section>
<section xml:id="customcolor-color">
<title>CustomColor Color</title>
<itemizedlist>
<listitem>
<simpara>Defines the color of the label box. Conditional coloring can also be had with the addition of if…​.then…​..else statements. There are no limits to the number of conditional statements but they follow the format if…​..then…​.else if…​..then…​..else if…​..then…​..else. Note the closing else that relates to the very first 'if…​..then'.</simpara>
</listitem>
</itemizedlist>
<simpara>You may have a label take on the same color as a plot. The syntax is: <literal>ChartPlotName.TakeValueColor()</literal></simpara>
<simpara><emphasis>Tip for moving labels up</emphasis></simpara>
<simpara>There are times when a label interferes with the top of a plotted chart’s data. To avoid that, you can plot a line at the top of the chart at a value above the plots data. The labels will then have their centerline equal to the value of the line.</simpara>
<simpara>To make the line invisible, paint it the same color as your background.</simpara>
<simpara><emphasis>Tip for debugging</emphasis></simpara>
<simpara>AddLabel is an excellent tool to observe a value for debugging purposes. In addition to that, a neat trick is, while in the code editor, drag the editor window down so that you can see the chart’s label and header values. That way, when you change the code and press apply, you can see the value change while staying in the code editor.</simpara>
<simpara>If you are inclined towards the use of concat, here is a guide on its use as well as an example of conditional coloring.</simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/8-3.png"/>
</imageobject>
<textobject><phrase>Concat</phrase></textobject>
</mediaobject>
</informalfigure>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/8-4.png"/>
</imageobject>
<textobject><phrase>Concat label</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara><emphasis>The equivalent using the '+' syntax is:</emphasis></simpara>
<screen>AddLabel(Display_Labels, "ADX(" + length + ") = " + Round(ADX,1) + " = Strong bullish (rating 3.5)", if "DI+" >"DI-" then
Color.GREEN else if "DI-" > "DI+" then Color.RED else Color.WHITE);</screen>
<simpara>The built-in ZigZagPercent study demonstrates the excellent use of conditional showing of the label itself, the use of the + syntax and conditional coloring. The code is duplicated below:</simpara>
<screen>AddLabel(showLabel and barNumber != 1, (if isConf then "Confirmed " else "Unconfirmed ") + "ZigZag: " + round(chg) +
"%", if !isConf then globalColor("Unconfirmed") else if isUp then globalColor("Up") else globalColor("Down"));</screen>
<simpara>SLOPE OF AN AVERAGE herein shows how to reteieve the literal of 'AverageType' choices in a label.</simpara>
</section>
<section xml:id="a-trap-to-avoid">
<title>A trap to avoid:</title>
<simpara>If your definition of the label text involves long and multiple 'if…​then…​else' statements, to insure that they all print, enclose each 'if…​then else' statement in parentheses e.g. '(if…​then…​else)'. Otherwise, you may not get an error but an 'if…​then…​else' statement may not print. C- THE 'AdvanceDecline' STUDY herein is an excellent example of this.</simpara>
</section>
</section>
<section xml:id="aggregation">
<title>AGGREGATION</title>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/9-1.png"/>
</imageobject>
<textobject><phrase>Length and Aggregation</phrase></textobject>
</mediaobject>
</informalfigure>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/9-2.png"/>
</imageobject>
<textobject><phrase>Dropdown</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>Each bar on a plot represents a period of time known as the primary aggregation: one minute, five minutes, day, etc.</simpara>
<simpara>A chart may also have one or more secondary aggregations. Variables are assumed to be of primary aggregation and those of a secondary aggregation must have their aggregation specified every time they are used.</simpara>
<simpara>A very common way of specifying the secondary aggregation is:</simpara>
<simpara>def Agg = AggregationPeriod.FIFTEEN_MIN;# Use the desired constant to specify the time
plot Data = close(period = agg) / close(period = agg)[3];# The phrase 'period =' is always used when referring to the variable aggregation. In this case 'agg'.</simpara>
<simpara>You may need to learn other ways of specifying aggregation to read other people’s code such as in the built-in DailySMA.</simpara>
<section xml:id="rules">
<title>RULES</title>
<orderedlist numeration="arabic">
<listitem>
<simpara>The secondary aggregation period cannot be less than the primary aggregation period defined by chart settings. This is a hard-fast rule that often comes into play.</simpara>
</listitem>
<listitem>
<simpara>Two different secondary aggregation periods cannot be used within a single variable. You can define each separately and then use the two definitions in a single statement.</simpara>
</listitem>
</orderedlist>
<simpara>It has been observed that using more than one secondary aggregation may affect the proper plotting. Using 'Expansion Area: ? Bars to the right' in chart settings may have an improvement.</simpara>
<simpara>There is a complete tutorial named Aggregation Tutorial,PDF available at <link xl:href="http://mytrade.com/StanL">http://mytrade.com/StanL</link></simpara>
</section>
</section>
<section xml:id="explanation-of-and">
<title>EXPLANATION OF '=' , '==' AND '!'</title>
<simpara><emphasis>The difference between = and ==</emphasis></simpara>
<simpara>A single "=" is the assignment operator. The statement "input Show_ChartPeriod = yes;" reads: assign (or set) the memory location labeled 'Show_ChartPeriod' to yes (boolean TRUE);</simpara>
<simpara>The double "==" is the logical equality operator. The statement "if AggPeriod == AggregationPeriod.DAY then …​ else…​;" reads: if the variable AggPeriod equals (is the same as) AggregationPeriod.DAY then do something else (otherwise) if it’s not, then do some other thing. When evaluating equality in an 'if' statement, two equal signs must be used ('==').</simpara>
<simpara><emphasis>The ! bang exclamation mark</emphasis></simpara>
<simpara>Not related to the above = and == is the "bang" (exclamation mark). As an example, use isnan() which returns <literal>true</literal> if the specified parameter is <emphasis>not a number</emphasis>, returns <literal>false</literal> otherwise. The ! ( exclamation mark called "bang" ) is a logical NOT perator. So if <literal>'isnan(close)'</literal> is true i.e. since/when close is not a number then <literal>'isnan(close)'</literal> reads as true. Using the "bang" and close remains not being a number, then <literal>'!isnan(close)'</literal> reads as " NOT close is not a number" or NOT true = false when close is not a number (⇐0).</simpara>
</section>
<section xml:id="referencing-other-studies">
<title>REFERENCING OTHER STUDIES</title>
<simpara>This subject is about including existing studies in your code 'by reference' in lieu of duplicating its actual code. The syntax for this procedure is: <literal>reference <StudyName>(parameter1=value1,.., parameterN=valueN).<PlotName></literal></simpara>
<simpara>A simple example is: <literal>plot MyMACD = reference MACDHistogram;</literal></simpara>
<simpara>Occasionally a study and a function may have the same name e.g. vwap and moneyflow. In that case:
- Call the vwap function like …​.<literal>plot MyVWAP1 = vwap;</literal>
- Reference the vwap study like …​.<literal>plot MyVWAP1 = reference VWAP;</literal>
- The use of the word 'reference' is optional but, if 'reference' is omitted, the () must always follow the study’s name. Example: <literal>plot MyVWAP1 = VWAP();</literal></simpara>
<simpara>In studies, you may reference built-in studies but not user-defined studies in (currently). However, user-defined studies may be referenced in scans.</simpara>
<simpara>In the following, the 'StochasticSlow' study will be used as an example for explanation.</simpara>
<section xml:id="specifying-plots">
<title>Specifying plots</title>
<simpara>Studies may have a single plot or multiple plots: ' StochasticSlow' has four plots named SlowK, SlowD, OverBought and OverSold. Referencing the SlowD plot would be via <literal>StochasticSlow().SlowD</literal> Just using <literal>StochasticSlow()</literal> would plot the SlowK because SlowK is the first plot in the actual code and is the default. Since no parameters are specified, the default parameters specified in the actual code are automatically used. Using parameters is explained below.</simpara>
</section>
<section xml:id="specifying-parameters">
<title>Specifying parameters</title>
<simpara>If you look at the actual code of StochasticSlow study you’ll see that it has a series of "input" variables. Those are the default parameters and cannot be changed because they are in a pre-defined study which is <emphasis>not editable</emphasis>. There are three ways to specify parameters: (1) Full form; (2) Compact form; and (3) A combo of (1) and (2). Specifying no parameters will use all the default values. The parameter list is in a fixed order of inputs from left to right i.e. each parameter/input has a fixed location in the list.</simpara>
</section>
<section xml:id="full-form">
<title>Full form</title>
<simpara>The full form specifies the input variable name with its intended value. An example is:</simpara>
<simpara><literal>def SlowK = StochasticSlow( KPeriod = 10, DPeriod = 10, priceH = High, smoothingType = "SMA" );</literal></simpara>
<simpara>Any parameter not listed herein takes on its default value. Note that the names like 'KPeriod', 'DPeriod', 'priceH', 'smoothingType' and others are as defined in the actual code’s input list.</simpara>
</section>
<section xml:id="compact-form">
<title>Compact Form</title>
<simpara>The compact form is simplest in that you simply put your values in the place/position of the default parameter you wish to change. You start with the first input value as the left most value in the reference. An example is:</simpara>
<simpara><literal>def SlowK = StochasticSlow( 80, 20, 10, 10, high, low, close, "SMA" ).SlowK;</literal></simpara>
<simpara>Note that you cannot omit any intermediate values or modify their positions. Only the right-most parameters may be dropped off and those will then take on their default values.</simpara>
</section>
<section xml:id="combo-form">
<title>Combo Form</title>
<simpara>This allows you to choose only the variables you want to change. An example is:</simpara>
<simpara><literal>def SlowK = StochasticSlow( 80, 20, 10, 10, smoothingType = "SMA" ).SlowK;</literal></simpara>
<simpara>Here you have omitted the price parameters. Once again, you must preserve the parameter’s position rule.</simpara>
<simpara>There are two ways of referencing constant inputs : <literal>smoothingType = "SMA"</literal> and <literal>smoothingType == smoothingType.SMA</literal> are equivalent.The first is the short syntax ("SMA"), while the second is the full syntax .</simpara>
<simpara>A different but related subject is referencing pre-defined studies using 'Script'. See <link xl:href="http://tda.thinkorswim.com/manual/metal/thinkscript/tutorials/advanced/referencing/other%20study.html">http://tda.thinkorswim.com/manual/metal/thinkscript/tutorials/advanced/referencing/other%20study.html</link></simpara>
<simpara>image::12-1.png[]Click the Scroll]
image::12-2.png[Click to Change Aggregation]</simpara>
</section>
</section>
<section xml:id="b-c-normalization">
<title>B&C-NORMALIZATION</title>
<simpara>If you want to compare two (or more) indicators that have values much different
that are non-receptive to comparison, you can normalize each of the two (or more)
indicators and compare them on a basis you define i.e. 0 to 100%, -1 to +1, -100
to +100, or whatever you want. Below is the code to do normalization and an example.
Note that not all studies can be normalized e.g. 'AccDist' has no parameters and
cannot be normalized.</simpara>
<simpara><emphasis>Code that does normalization</emphasis></simpara>
<screen>#Usage: 'input data = close' is substituted by an indicator and its parameters.
declare lower;
script normalizePlot {
input data = close;
input newRngMin = -1;
input newRngMax = 1;
def HHData = HighestAll( data );
def LLData = LowestAll( data );
plot nr = ((( newRngMax - newRngMin ) * ( data - LLData )) / ( HHData - LLData )) + newRngMin;
}</screen>
<simpara>Examples</simpara>
<screen>input price = close;
input CCI_length = 7;
input Momentum_length = 12;
input RSI_length = 4;
input WR_length = 10;
input newRngMax = 100;#Maximum normalized value
input newRngMin = 0;#Minimum normalized value
input OverBought = 80;#Fixed value upper line for reference
input OverSold = 20;#Fixed lower value line for reference
def newCCI = normalizePlot( CCI( CCI_length).CCI, newRngMin, newRngMax );
def newMomentum = normalizePlot( Momentum( length = Momentum_length ).Momentum, newRngMin, newRngMax );
def newWPR = normalizePlot( WilliamsPercentR( length = WR_length ).WR, newRngMin, newRngMax );
def newRSIWilder = normalizePlot( RSIWilder( length = RSI_length ).RSI, newRngMin, newRngMax );
plot CCI = newCCI;
plot Momentum = newMomentum;
plot WPR = newWPR;
plot RSIWilder = newRSIWilder;
plot Over_Bought = 80;
plot Over_Sold = 20;</screen>
</section>
<section xml:id="counting-and-use-of-compoundvalue">
<title>COUNTING AND USE OF 'COMPOUNDVALUE'</title>
<simpara>Counting is often used. This shows the construct for a 'def count' variable and
also takes this opportunity to define the usage of CompoundValue to initialize
this recursive variable. Previous versions of TS would require this to be written
as 'Rec count =' statement but TS corrently recognizes both 'def' and 'rec' to
define a recursive variable. The below annotated picture explains how counting i
s accomplished. Naturally any valid condition may be substituted for the one shown.</simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/14-1.png"/>
</imageobject>
<textobject><phrase>Count</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>By the way, you can identify a recursive variable definition when the variable itself, in this case 'count', also appears on right side of the equal sign/equation like, in this case, 'count[1]'.</simpara>
<simpara>If you have a reason to re-start the counting from 0 or 1 based on a defined condition, you place the condition after the 'else' like 'else if <condition to restart counting> then 0 ' and close with 'else count[1]'.</simpara>
<simpara>Refer to PastOffset discussed at [Click to read about it.](<link xl:href="https://tlc.thinkorswim.com/center/charting/thinkscript/tutorials/Chapter-13---Past-Offset-and-Prefetch.html">https://tlc.thinkorswim.com/center/charting/thinkscript/tutorials/Chapter-13---Past-Offset-and-Prefetch.html</link>) In short, it says that if you have multiple past references in your code, for example <literal>'Average(close, 11) or close[6]</literal> ,' the longest past reference value will be used for all past reference' regardless of what your code says. You would use 'CompoundValue' to prevent the longest reference being used by initializing the affected calculation with the 'CompoundValue' function.</simpara>
</section>
<section xml:id="linear-regression">
<title>LINEAR REGRESSION</title>
<simpara>There are several built-in Linear Regression studies in ThinkScript. This section is intended to clarify their differences and usage.</simpara>
<simpara>Definition = 'Linear regression' is a mathematical procedure know as the 'least-squares method', used for drawing the best straight line thruogh a group of data points. ThinkScript’s linear regression function is titled <emphasis>'Inertia'</emphasis>. You may view it at</simpara>
<simpara><link xl:href="http://tda.thinkorswim.com/manual/metal/thinkscript/reference/Functions/Statistical/Inertia.html">http://tda.thinkorswim.com/manual/metal/thinkscript/reference/Functions/Statistical/Inertia.html</link></simpara>
<simpara>The key studies are:</simpara>
<orderedlist numeration="arabic">
<listitem>
<simpara>LinearRegCh100</simpara>
</listitem>
<listitem>
<simpara>LinearRegCh50</simpara>
</listitem>
<listitem>
<simpara>LinearRegChVar</simpara>
</listitem>
<listitem>
<simpara>LinearRegCurve</simpara>
</listitem>
<listitem>
<simpara>LinearRegTrendline</simpara>
</listitem>
<listitem>
<simpara>LinearRegrReversal</simpara>
</listitem>
<listitem>
<simpara>LinearRegressionSlope</simpara>
</listitem>
</orderedlist>
<section xml:id="linearregch100">
<title>LinearRegCh100</title>
<simpara>Uses the data of the entire plot. The upper and lower channel lines, parallel to the centerline (the true linear regression)., indicate the furthest that the data has been from the middle line The '100' in the title means that it shows the upper and lower lines at 100% of the data difference from the centerline .</simpara>
</section>
<section xml:id="linearregch50">
<title>LinearRegCh50</title>
<simpara>Is the same as the LinearRegCh100 except that the upper and lower lines ar at 50% of the of the data difference from the centerline in lieu of 100%.</simpara>
</section>
<section xml:id="linearregchvar">
<title>LinearRegChVar</title>
<simpara>This version allows the user to define the 'percentage-distance-from-the-centerline' of the upper and lower lines. Also, this version allows the user to select the number of bars for the linear regression plot in lieu of the previous two studies that use the entire chart (all bars).</simpara>
</section>
<section xml:id="linearregcurve">
<title>LinearRegCurve</title>
<simpara>Plots a single curve in which you have defined the type of price and the number of bars as the basis for the curve.</simpara>
</section>
<section xml:id="linearregtrendline">
<title>LinearRegTrendline</title>
<simpara>Uses the data of the entire chart. Plots a straight linear regression line for whichever of the eleven choices you have selected. The choices include other than price items such as volume and 'imp volatility'.</simpara>
</section>
<section xml:id="linearregrreversal">
<title>LinearRegrReversal</title>
<simpara>This study indicates "+1" when the current value of Linear Regression Curve is equal to or greater than that of the previous bar and "-1" otherwise. If you compare this to the LinearRegCurve be sure to use the same number of bars input for each study.</simpara>
</section>
<section xml:id="linearregressionslope">
<title>LinearRegressionSlope</title>
<simpara>Plots the changing slope of the LinearRegCurve based on the price and length that you select.</simpara>
<simpara>Note that LinearRegCurve, LinearRegTrendline, and LinearRegressionSlope all have the same eleven price input choices.</simpara>
<simpara>Studies #1, #2 and #3 are very popular in searching for stocks that are at buy-low prices. You may find these especially beneficial to learn and comfortably use them.</simpara>
</section>
</section>
<section xml:id="two-ways-to-calculate-change">
<title>TWO WAYS TO CALCULATE % CHANGE</title>
<simpara>There are two ways to calculate a % change. You may see both ways used in coding.</simpara>
<simpara>As an example let 10 be the original value (B4) and 15 the final value (NOW). NOW/B4 is the "RATIO"</simpara>
<simpara><emphasis>First way:</emphasis></simpara>
<simpara>In words, final value divided by the original value; minus one; times 100.
or 15/10 = 1.5; 1.5 - 1 = 0.5; 0.5 X 100 = 50 % increase</simpara>
<simpara>Example:</simpara>
<screen>def length = 10;<co xml:id="CO1-1"/>
def price = close; # The current close. This is the "NOW" value
plot PercentChg = (price / price[length] - 1) * 100; # or (NOW / B4) - 1 is RATIO - 1 and "RATIO - 1" multiplied by 100 equals the PERCENT CHANGE. If the "RATIO' is below or above the value of ONE, then the % change is above or below 100% respectively</screen>
<calloutlist>
<callout arearefs="CO1-1">
<para>[10] means 10 agg-bars ago This is the "B4" value</para>
</callout>
</calloutlist>
<simpara><emphasis>Second way:</emphasis></simpara>
<simpara>In words, the change difference (NOW minus the B4) divided by the original (B4) value times 100.
or 15 -10 = 5 = change difference; 5/10 = 0.5; 0.5 X 100 = 50% increase.</simpara>
<simpara>If the difference (B4 - NOW) is negative the percent is also negative i.e. 'decrease'. Also if the "RATIO" (NOW/B4) is less than zero then the percent change will be negative.</simpara>
<simpara>Example:</simpara>
<screen>def length = 10;# [10] means 10 agg-bars ago
def price = close; # The current close
plot PercentChg = ((price - price[length])/ price[length]) * 100;# ((NOW-B4) / B4) * 100 which is the same as (NOW/B4 B4/B4) * 100 which is the same as (NOW/B4 - 1) * 100. The % change is up or down if the difference is plus or minus respectively.</screen>
<simpara><emphasis>Additional Comments:</emphasis></simpara>
<simpara>The two ways above example, "value1 is what percent larger/smaller than value2." For value1 = 85 and value2 = 38 then: 85 /38 = 2.24; 2.24 X 100 = 224%. In words value1 is 224% of value2. Or, in a different way, it can be said that 2.24 -1 = 1.24 X 100 = 124% which reads that value1 is 124% larger than (or above) value2.</simpara>
<simpara><emphasis>An aside:</emphasis> A calculated value of -0.0331 will be formatted with 'AsPercent' to show the below label in cyan.</simpara>
<screen>input length = 9;
AddLabel(yes, AsPercent((close - close[length]) / close[length]),color.cyan);</screen>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/17-1.png"/>
</imageobject>
<textobject><phrase>label</phrase></textobject>
</mediaobject>
</informalfigure>
</section>
<section xml:id="formatting-with-astext-asdollars-and-others">
<title>FORMATTING WITH 'AsText', 'AsDollars' AND OTHERS</title>
<simpara>The following formatting functions are especially useful in custom columns and labels.</simpara>
<section xml:id="an-asdollars-example">
<title>An 'AsDollars' example</title>
<screen>def x = CompoundValue(1, if IsNan(GetActualEarnings()) then x[1] else GetActualEarnings(), GetActualEarnings());
AddLabel(yes, "'Earnings = " + asDollars((round(x,2))) + "'", color.cyan);</screen>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/18-1.png"/>
</imageobject>
<textobject><phrase>Label</phrase></textobject>
</mediaobject>
</informalfigure>
</section>
<section xml:id="an-astext-plus-decimal-places-example">
<title>An 'AsText' plus 'decimal-places' example</title>
<screen>def x = CompoundValue(1, if IsNan(GetActualEarnings()) then x[1] else GetActualEarnings(), GetActualEarnings());
AddLabel(yes, "'Earnings = " + AsText(x,NumberFormat.TWO_DECIMAL_PLACES) + "'", color.cyan);</screen>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/18-2.png"/>
</imageobject>
<textobject><phrase>Label</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>Comment: 'NumberFormat.TWO_DECIMAL_PLACES', 'NumberFormat.THREE_DECIMAL_PLACES' and 'NumberFormat.DOLLAR' are the three choices that can be used with 'AsText'. Using 'NumberFormat.DOLLAR' produces the same look as using 'AsDollars'. Also the decimal places can be gotten by using the Round() function as shown above in the 'AsDollars' example.</simpara>
</section>
<section xml:id="an-asdollars-example-2">
<title>An AsDollars example</title>
<simpara><literal>AddLabel(yes, "Current True Range is " + AsDollars(TrueRange(high, close, low)),color.cyan);</literal></simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/18-3.png"/>
</imageobject>
<textobject><phrase>Label</phrase></textobject>
</mediaobject>
</informalfigure>
</section>
<section xml:id="an-aspercent-example">
<title>An AsPercent example</title>
<screen>def Range = 1 - ((high - close)/ (high - low));
AddLabel(yes,"Range percent = " + asPercent(round(Range,2)),color.cyan);</screen>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/18-4.png"/>
</imageobject>
<textobject><phrase>Label</phrase></textobject>
</mediaobject>
</informalfigure>
</section>
<section xml:id="an-asprice-example">
<title>An AsPrice example</title>
<simpara><literal>AddLabel(yes, "10 period SMA of Close price using 1/32nds price notation (XXX’YYZ) = "+ AsPrice(Average(close, 10)),color.cyan);</literal></simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/18-5.png"/>
</imageobject>
<textobject><phrase>Label</phrase></textobject>
</mediaobject>
</informalfigure>
</section>
</section>
<section xml:id="literal-text-in-label-for-the-11-choices-of-input-price">
<title>LITERAL TEXT IN LABEL FOR THE 11 CHOICES OF INPUT PRICE</title>
<screen>#Puts any of the 11 price choices into a literal text in a label like ohlc4 = 75
input price = close;#Price automatically avails 11 choices and the label below tells which was selected.
#Puts any of the 11 price-choices into a literal text in a label like ohlc4 = 75
input price = close;#Price automatically avails 11 choices
AddLabel(yes, if price == close then "The price-variable selected is close = " + Round(close,2)
else if price == open then ""The price-variable selected is open = " + Round(open,2)
else if price == high then ""The price-variable selected is high = " + Round(high,2)
else if price == low then ""The price-variable selected is low = " + Round(low,2)
else if price == hl2 then ""The price-variable selected is hl2 = " + Round(hl2,2)
else if price == hlc3 then ""The price-variable selected is hlc3 = " + Round(hlc3,2)
else if price == imp_volatility then ""The price-variable selected is current imp_volatility = " + AsPercent(imp_volatility)
else if price == ohlc4 then ""The price-variable selected is ohlc4 = " + Round(ohlc4,2)
else if price == open_interest then ""The price-variable selected is Open_interest = " + Round(open_interest,0)
else if price == volume then ""The price-variable selected is Volume = " + Round(volume,0)
else if price == VWAP then ""The price-variable selected is VWAP = " + Round(VWAP,0)
else "N/A" + price,color.white);</screen>
<simpara>Comments: The 11 choices of Price are close, high, hl2, hlc3, imp_volatility, low, ohlc4, open, open_interest, volume, vwap.</simpara>
</section>
<section xml:id="what-is-swing-high-swing-low">
<title>WHAT IS SWING-HIGH, SWING-LOW</title>
<simpara>What is a swing high / low? Basically a swing high is the highest high looking a few bars back and a few bars forward. A swing low is the lowest low looking a few bars back and a few bars forward. The more bars you include in the series, the more significant the swing, but the confirmation comes further from the actual swing point. If you wanted to define a swing high as a bar high that is higher than the highs of the two bars just before it AND higher than the highs of the two bars just after it, the thinkscript code would look like this:</simpara>
<simpara><literal>Def swinghigh = if high > high[1] and high > high[2] and high > high[-1] and high > high[-2] then 1 else 0;</literal></simpara>
<simpara>Or if you are interested in the rise of the last 5 bars, you may use something like this:</simpara>
<simpara><literal>plot pivotHigh = if high == (highest(high, 5) and sum(high > high[-1], 5) == 5) then high else Double.NAN;</literal></simpara>
<simpara>The code for a swing low is similar. Note that the confirmation of a swing point does not come until 2 bars after the swing high in this case. If you wanted to extend the swing check to 3 bars before and after, you would add the checks for a high > high[3] and high > high [-3]. The resulting swing will be more significant, but the signal comes 3 bars after the fact.</simpara>
<simpara>To plot the swing high you could code it like this:</simpara>
<screen>Plot swing_hi = if swinghigh then high else double.nan;
swing_hi.setstyle(curve.points);</screen>
<simpara>This would paint a dot on all the swing highs, and nothing everywhere else. The code for swing lows is similar.</simpara>
<simpara>This is the simplified basics of swingHi/SwingLo. Many coders add all kinds of conditions to supplement the simplified code herein. Also the look-back and the look-forward lengths do not need to be the same.</simpara>
</section>
<section xml:id="comparison-to-another-instrument">
<title>COMPARISON TO ANOTHER INSTRUMENT</title>
<simpara>Comparison to another stock, index or any instrument having a symbol.</simpara>
<itemizedlist>
<listitem>
<simpara>Click 'studies' then 'Add Study' then 'Compare With'</simpara>
</listitem>
<listitem>
<simpara>If none of the ready-made comparisons have what you want, then click 'Custom Symbol…​.'</simpara>
</listitem>
<listitem>
<simpara>You will then be presented with the following dialog:</simpara>
</listitem>
</itemizedlist>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/COMPARISON_TO_ANOTHER_INSTRUMENT_1.png"/>
</imageobject>
<textobject><phrase>Insert the symbol</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>If you have forgotten or are unsure of the symbol, you can find it easily as follows:</simpara>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="./images/COMPARISON_TO_ANOTHER_INSTRUMENT_2.png"/>
</imageobject>
<textobject><phrase>find the symbol</phrase></textobject>
</mediaobject>
</informalfigure>
<simpara>The comparison will be overlaid on the upper panel using the left-hand price scale. You can edit the study to change the symbol or the type of plot, i.e. Line, Bar, Candle, or the color. Choose any aggregation but 'day' is most meaningful.</simpara>
</section>
<section xml:id="the-fold-function-explained">
<title>THE FOLD FUNCTION EXPLAINED</title>
<simpara>The Fold syntax is:</simpara>
<simpara><literal>def <result> = fold <index> = <start> to <end> [ with <variable> [ = <init> ] ] [ while <condition> ] do <expression>;</literal></simpara>
<simpara>Each component of the fold function will be explained separately. The function is not easy to use but understanding the purpose of the components will help you to feel comfortable with it.</simpara>
<simpara>General Comment:</simpara>
<itemizedlist>
<listitem>
<simpara>The fold function is used to define the value for a named variable i.e. def <result>. You cannot operate on other variables or do anything within the fold. Studies may be used within a fold.</simpara>
</listitem>
<listitem>
<simpara>Rather than define a variable, the fold may be plotted directly i.e. def <result> = becomes Plot <result> =.</simpara>
</listitem>
<listitem>
<simpara>Remember that the fold calculation is executed at every bar as ThinkScript processes from bar 1 to the last bar.</simpara>
</listitem>
<listitem>
<simpara>As discussed in GetValue below, studies may be used in the Fold function especially in the do <expression>.</simpara>
</listitem>
<listitem>
<simpara>The names assigned <index> and <variable> are persistent variables. Hence, if you have two folds in a study and you assign 'idx' to <index> in the first fold you cannot assign 'idx' to <index> in the second fold. This will create an error.</simpara>
</listitem>
<listitem>
<simpara>Fold will normally work in a scan and custom columns. Complexity may become an issue especially if the servers are loaded up.</simpara>
</listitem>
<listitem>
<simpara>fold</simpara>
</listitem>
<listitem>
<simpara>A fixed word that identifies the following as a 'Fold' function.</simpara>
</listitem>
<listitem>
<simpara><index> = <start> to <end></simpara>
</listitem>
<listitem>
<simpara>This defines how many times the fold calculation loops on each bar. You need to figure out how many times "fold" needs to repeat itself, OR at what value it is going to stop churning away. Let’s say you want a calculation to repeat 5 times. If the <start> is at 0 and the <end> is at 5, then the calculation will repeat 5 times. <start> is inclusive but <end> is exclusive. When the counter gets to 5, fold stops and there is no results related to loop 5. <index> can be any name you want but 'i' or 'index' is commonly used e.g. i = 0 to 50. The value of the index can be used in the do <expression>. When <index> is used in the do statement, the last value of <index> is used and not the current value. The current value would be <index> + 1.</simpara>
</listitem>
<listitem>
<simpara>[ with <variable> [ = <init> ] ]</simpara>
</listitem>
<listitem>
<simpara>First of all, anything within brackets is optional. So when/why would you include this.?The answer lies in that this is an internal variable that fold uses. So when is it needed? If the 'do' section of the fold performs a activity like 'add to', 'multiply by' or similar, it must have a previous number to 'add to' for example. This 'with <variable>' is the value that will be added to when you see code like 'do nice + idx3'. This means that 'nice' is the with <variable> that fold has been keeping tract of internally and '+ idx3' is the current loop’s calculated value that is to be added to nice. 'nice + idx3' then becomes the new value of the internal variable nice and nice is available for the next loop’s calculation. <variable> can be any name you want to assign. In this example, 'nice' was used.</simpara>
</listitem>
<listitem>
<simpara>[ = <init> ] is the initial value of the 'with <variable>' and is optional. If it is omitted, then the default value of 0 is used. <init> is a number. Since it is in brackets, it is optional if there is a with <variable>.</simpara>
</listitem>
<listitem>
<simpara>[ while <condition> ]</simpara>