Congratulations!

[Valid Atom 1.0] This is a valid Atom 1.0 feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://feeds.feedburner.com/blogspot/MeceN

  1. <?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4545464012838172159</id><updated>2021-12-04T10:41:55.268+01:00</updated><category term="XPages"/><category term="Notes Designer"/><category term="Notes client"/><category term="Java"/><category term="INDIP"/><category term="FRULE"/><category term="QUINDIP"/><category term="Feedback required"/><category term="Lotus Notes"/><category term="YOUFEB"/><category term="Illustrator"/><category term="Beans"/><category term="Bug"/><category term="CRYFH"/><category term="CSS"/><category term="Eclipse"/><category term="Export"/><category term="Lotus Script"/><category term="Web Design"/><category term="funny"/><title type='text'>inMood: shared experience mainly</title><subtitle type='html'>anything I feel compelled to share: mostly encouraging or discouraging thing I learned</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>89</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-4975485326990005816</id><published>2021-09-15T20:45:00.002+02:00</published><updated>2021-09-15T20:45:16.793+02:00</updated><title type='text'>Neues Steuermodell</title><content type='html'>&lt;h1 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Steuermodell Evolution&lt;/h1&gt;&lt;div&gt;In vermutlich den meisten Ländern der Welt funktioniert es ähnlich. Das Volk zahlt Steuern und die Regierung verwendet das Geld für die entsprechenden Zwecke. Dazu erstellt jede Regierung, wie auch jedes Unternehmen, leider nicht jeder Haushalt, was aber zu empfehlen wäre, ein Budget.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Was ist ein Budget?&lt;/h2&gt;&lt;div&gt;Kurz gesagt versucht man mit einem Budget herauszufinden wie gross die Einnahmen sein werden und auf welche Positionen man die Ausgaben verteilen will. Dabei sollten sich Einnahmen und Ausgaben die Waage halten.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Beispiel&lt;/h3&gt;&lt;div&gt;Eine Familie verdient 5000 Schweizer Franken pro Monat, dies 13x pro Jahr. Davon müssen mindestens folgende (nicht abschliessende Liste) Positionen bezahlt werden:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Steuern&lt;/li&gt;&lt;li&gt;Wohnung (inkl. Strom, Heizung, Wasser)&lt;/li&gt;&lt;li&gt;Essen/Trinken/Kleider und sonstiges Haushaltszeugs (Reinigungsmittel)&lt;/li&gt;&lt;li&gt;Versicherungen&lt;/li&gt;&lt;li&gt;Fortbewegung (Auto/ÖV)&lt;/li&gt;&lt;li&gt;Kommunikation (Handy/Internet)&lt;/li&gt;&lt;li&gt;Freizeit/sonstiges&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Die Familie geht jetzt hin und teilt die 5000 CHF auf auf alle diese Positionen, zB:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Steuern: 20%&lt;/li&gt;&lt;li&gt;Wohnung (inkl. Strom, Heizung, Wasser): 35%&lt;/li&gt;&lt;li&gt;Essen/Trinken/Kleider und sonstiges Haushaltszeugs (Reinigungsmittel): 8%&lt;/li&gt;&lt;li&gt;Gesundheit: 2%&lt;/li&gt;&lt;li&gt;Versicherungen: 10%&lt;/li&gt;&lt;li&gt;Fortbewegung (Auto/ÖV): 10%&lt;/li&gt;&lt;li&gt;Kommunikation (Handy/Internet): 10%&lt;/li&gt;&lt;li&gt;Freizeit/sonstiges: 5%&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Wenn jetzt irgend ein Posten teurer wird. Zum Beispiel Gesundheit wegen einer ungeplanten Zahnarztrechnung, dann muss (sollte zumindest) dieses Geld woanders eingespart werden. Dabei muss man sich überlegen wo man sparen kann. Gewisse Positionen sind fix: Steuern/Wohnung/Versicherungen. Das heisst man muss bei einer anderen Position sparen, vermutlich zu allererst in der Freizeit. Im Extremfall vielleicht weniger Autofahren oder das Internetabo verkleinern.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Im Glücksfall erbt die Familie Geld und kann sich schönere Ferien als geplant leisten.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bei einer Regierung ist es nicht anders. Nur die Positionen sehen anders aus.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Nicht abschliessende Liste:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Verkehr: Aus-Bau/Reparatur von Strassen/Brücken&amp;amp;Tunnels und deren Beschilderung&lt;/li&gt;&lt;li&gt;Sicherheit: Polizei und Militär&lt;/li&gt;&lt;li&gt;Gesundheit: Bereitstellung von Spitälern, Ausbildung von genügend Ärzten und Pflegepersonal&lt;/li&gt;&lt;li&gt;Bildung: Ausbildung/Bezahlung von Lehrpersonal&lt;/li&gt;&lt;li&gt;Forschung&lt;/li&gt;&lt;li&gt;Regierung: der ganze Regierungsapparat inklusive Richtern/Gerichten muss bezahlt werden&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Der Bürger hat absolut keinen, zumindest keinen direkten, Einfluss darauf wofür die Steuern ausgegeben werden. Das kann dazu führen, dass Geld im Sinne der Bevölkerung falsch ausgegeben wird. So könnte anstatt Geld für die Bildung zum Beispiel im Asylwesen ausgegeben werden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Denkanstoss neues Modell&lt;/h2&gt;&lt;div&gt;Warum lassen wir nicht die Bürger entscheiden wofür die Steuern verwendet werden? Damit wäre der Regierung schon mal ein bisschen die Freiheit genommen Gelder falsch zu verwenden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Man könnte, wie gesagt nur ein Denkanstoss, sich folgendes überlegen:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Der Bürger darf über 80% der Steuern die er zahlt entscheiden in welcher Kategorie das Geld ausgegeben werden soll. Über 20% darf die Regierung verfügen. So könnte sie ein Reserve bilden, oder gewisse Posten, zumindest temporär, mit einem Zustupf versehen. Zum Beispiel in der Pandemie wie jetzt könnten diese 20% in die Kategorie Gesundheit und Unterstützung der Wirtschaft fliessen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Man könnte dieses System so gestalten, dass bei der 1. Steuererklärung wo man dieses Splitting angeben darf, die Beträge auf die bisherigen Budget Positionen verteilt sind. Hat die Regierung 50% der Steuern in die Sicherheit investiert, wäre dies der Default beim 1. Splitting. Der Steuerzahler dürfte nicht einfach nach Lust und Laune jedes Jahr alles neu aufteilen, gibt ja Projekte von der Regierung die dauern ein paar Jahre. Das ginge schief wenn erst viel Geld und im nächsten Jahr kein Geld mehr vorhanden wäre. So könnte man z.B. festlegen, dass man einzelne Positionen nur ein paar Prozente ändern dürfte. Wieviele Prozente dies wären müsste man mathematisch berechnen was Sinn macht. Nehmen wir maximal 5% an. So könnte der Steuerzahler also von den 50% für die Sicherheit 5% abziehen oder dazugeben. Zieht er sie ab, könnte er es z.B. der Kategorie Bildung zuteilen. Er dürfte aber nicht auch vom Verkehr 5% abziehen und dies der Bildung zuschanzen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So oder ähnlich würde man ein relativ stabiles Konstrukt schaffen womit die Regierung nicht allzu sehr in ihren Projekten behindert würde, der Bürger jedoch trotzdem einen gewissen Einfluss haben könnte in welche Richtung er das Geld ausgeben will.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jetzt schreien die ersten: geht doch nicht, dann wollen alle bessere Strasse und niemand will in Sicherheit investieren. Und jetzt? Wenn das der Wunsch des Volkes ist, warum nicht? Man müsste die Entwicklung der einzelnen Kategorien gut überwachen um dem Volk entsprechende Informationen zukommen lassen zu können. Man könnte warnen vor Risikopositionen. Zum Beispiel zu wenig Intensivbetten in Spitälern.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Natürlich müsste man die Kategorien intelligent aufteilen. Evtl. müsste man Sicherheit in Polizei und Militär aufteilen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Dadurch würden sich die Leute auch bewusster wofür ihr Geld, ihre Steuern ausgegeben werden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Heute ist es total anonym. Jeder schreit: Wir haben Platz. Jedes 2. Jahr wollen Linke/Grüne tausende von Flüchtlingen aufnehmen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Szenario 1:&amp;nbsp;&lt;/div&gt;&lt;div&gt;Will ich wirklich 1500 CHF jährlich für Asylanten ausgeben? Oder reichen da 150 CHF und dafür soll mehr in Bildung investiert werden?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Szenario 2:&lt;/div&gt;&lt;div&gt;Kann ich auf gut unterhaltene Strassen verzichten, möchte jedoch mehr in Umweltschutz investieren, kein Problem&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Weil es natürlich sein könnte, dass man für gewisse Positionen Geld ausgeben MUSS, auch wenn die Bevölkerung das nicht will, könnte man auch minimum Anteile definieren oder die 80/20 Aufteilung zwischen Regierung und Steuerzahler auf 70/30 oder 60/40 ändern.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vermutlich würden mehr als die Hälfte eh die meisten Positionen auf den Standardwerten belassen und nur an 2-3 Kategorien ein wenig rumschrauben. Durch die maximal erlaubte Korrektur pro Jahr (im Beispiel 5%, könnte aber auch 1% sein) würde die gegenwärtige Regierung auch nicht allzusehr beeinflusst werden.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wo sich Risikopositionen abzeichnen könnte man frühzeitig mit einer Initiative abfange wie vorzugehen ist wenn der Risikofall eintritt.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bitte hinterlasst mir Eure Gedanken, Kommentare, freundlich aber darf auch scharf sein wenn es mit Argumenten unterlegt ist.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/4975485326990005816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/09/neues-steuermodell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4975485326990005816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4975485326990005816'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/09/neues-steuermodell.html' title='Neues Steuermodell'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-3218138741867120932</id><published>2021-01-28T19:14:00.003+01:00</published><updated>2021-01-28T20:04:02.566+01:00</updated><title type='text'>Other stuff</title><content type='html'>          &lt;div id=&quot;myToc&quot;&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt;       &lt;h4&gt;Other blogs about the topic&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html&quot;&gt;Main Blog about creating a trading bot&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading strategy explained&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule applications in macOS Big Sur&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Improving blogger experience&lt;/h1&gt;&lt;div&gt;&lt;div&gt;Almost forgot to mention how I improved blogger experience.&lt;/div&gt;&lt;div&gt;I needed a TOC (Table of contents), such that a reader can quickly jump to the section he&#39;s interested in.&lt;/div&gt;&lt;div&gt;Blogger does NOT offer this out of the gate.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I dug, dug deeper and I found 2 solutions which actually create a TOC. But neither was good enough.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One only fetched only level of &amp;lt;H&amp;gt; tags, the other one fetched all but got lost as soon as there&#39;s more complicated HTML code between the &amp;lt;H&amp;gt; tags.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I used some parts of both and improved upon it: You paste this in the HTML BEFORE everything:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;myToc&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;hr&lt;/span&gt; &lt;span style=&quot;color: grey;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;myContents&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And you paste this AFTER everything&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  countChapters = $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#myContents &amp;gt; h1, #myContents &amp;gt; h2&quot;&lt;/span&gt;).length&lt;/div&gt;&lt;div&gt;  chapters = $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#myContents &amp;gt; h1, #myContents &amp;gt; h2&quot;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;  flagLevel = &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; toc = &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  &lt;span style=&quot;color: #569cd6;&quot;&gt;for&lt;/span&gt; (i = &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;; i &amp;lt; countChapters; i++) {&lt;/div&gt;&lt;div&gt;    chapter = chapters[i]&lt;/div&gt;&lt;div&gt;    chapterTitle = chapters[i].textContent;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;    chapters[i].setAttribute(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;chapter&quot;&lt;/span&gt; + i);&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;H2&#39;&lt;/span&gt; == chapter.tagName) {&lt;/div&gt;&lt;div&gt;      &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (flagLevel) {&lt;/div&gt;&lt;div&gt;        toc += &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;li&amp;gt;&amp;lt;a href=&#39;#chapter&quot;&lt;/span&gt; + i + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&#39;&amp;gt;&quot;&lt;/span&gt; + chapterTitle + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;      } &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        toc += &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&#39;#chapter&quot;&lt;/span&gt; + i + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&#39;&amp;gt;&quot;&lt;/span&gt; + chapterTitle + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      flagLevel = &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    } &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;      &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (flagLevel) {&lt;/div&gt;&lt;div&gt;        toc += &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;/ul&amp;gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        flagLevel = &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;&lt;/div&gt;&lt;div&gt;      }&lt;/div&gt;&lt;div&gt;      toc += &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;li&amp;gt;&amp;lt;a href=&#39;#chapter&quot;&lt;/span&gt; + i + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&#39;&amp;gt;&quot;&lt;/span&gt; + chapterTitle + &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div&gt;  document.getElementById(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;myToc&quot;&lt;/span&gt;).innerHTML = toc;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Then it will parse all H1/H2 tags and create a TOC at the top.&lt;/div&gt;&lt;div&gt;By fine-tuning the flagLevel thing you could even have it parse H3 tags.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Who&#39;s interested: let me know and I enhance the code for you!&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This technique can actually be used on every HTML page&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Install web server&lt;/h1&gt;&lt;div&gt;&lt;div&gt;This is an easy one on macOS, thanks to this&lt;/div&gt;&lt;div&gt;article &lt;a href=&quot;https://getgrav.org/blog/macos-bigsur-apache-multiple-php-versions&quot; target=&quot;_blank&quot;&gt;https://getgrav.org/blog/macos-bigsur-apache-multiple-php-versions&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I had home-brew (brew) already installed. So I just needed to follow a few steps.&lt;/div&gt;&lt;div&gt;Apple delivers a built-in apache version, yet the default configuration is a bit not so straight forward. With the approach from above I had the web server running in a few minutes, pointing to my directories.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Make (bot) results accessible from afar&lt;/h1&gt;&lt;div&gt;&lt;div&gt;Here I needed to think/play a little bit. Years ago there were DynDNS services, for free. Nowadays they charge for their service. What they basically do is provide a hostname which is mapped to your dynamic public IP from your home router.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I tried to build my own &quot;rough&quot; DynDNS solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I started with &lt;a href=&quot;https://www.whatismyip.com&quot;&gt;https://www.whatismyip.com&lt;/a&gt; and &lt;a href=&quot;https://github.com/cheeriojs/cheerio&quot;&gt;https://github.com/cheeriojs/cheerio&lt;/a&gt; a tool which lets you parse HTML on the server (and not on the client side). Here&#39;s a nice tutorial &lt;a href=&quot;https://dev.to/diass_le/tutorial-web-scraping-with-nodejs-and-cheerio-2jbh&quot; target=&quot;_blank&quot;&gt;https://dev.to/diass_le/tutorial-web-scraping-with-nodejs-and-cheerio-2jbh&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On the way I learned that jQuery is a thing of the past and one should use React or Vue now, so I did a 30 minutes primer into Vue. Nice, but couldn&#39;t understand why/where it&#39;s better than jQuery. With Vue you have to &quot;wrap&quot; your tags into &quot;v-&quot; tags in order for it to work. Works well for applications, but it&#39;s a pain if you want to do very small things, like things I did with my &lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html&quot; target=&quot;_blank&quot;&gt;visual tool to analyse charts&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway: I got cheerio to read the contents of whatismyip.com and it took me almost 2 hours to figure, that they would not return my IP, as they realise the request is not from a user, but from a machine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But there&#39;s other tools, like this one: &lt;a href=&quot;http://ip-api.com/json&quot;&gt;http://ip-api.com/json&lt;/a&gt; Very straight forward. Returns my IP and that&#39;s all I need.&lt;/div&gt;&lt;div&gt;Now what to do with my IP? Store it on google drive? Do they have an API? After a few minutes tinkering I figured: I will use iCloud. Create a document there with a link to my &quot;own&quot; web server. And that&#39;s what I did.&lt;/div&gt;&lt;div&gt;Please don&#39;t judge me on this code: it&#39;s a prototype and does what it needs to do:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;module.paths.unshift(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/Users/michael/NodeJS&#39;&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;const&lt;/span&gt; axios = require(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;axios&quot;&lt;/span&gt;).default;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;url = &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;http://ip-api.com/json&#39;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;const&lt;/span&gt; fetchHtml = &lt;span style=&quot;color: #569cd6;&quot;&gt;async&lt;/span&gt; url &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;try&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;const&lt;/span&gt; { data } = &lt;span style=&quot;color: #569cd6;&quot;&gt;await&lt;/span&gt; axios.get(url);&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;return&lt;/span&gt; data;&lt;/div&gt;&lt;div&gt;    } &lt;span style=&quot;color: #569cd6;&quot;&gt;catch&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        console.error(&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #ce9178;&quot;&gt;`ERROR: An error occurred while trying to fetch the URL: &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;url&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;`&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        );&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;async&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; doIt() {&lt;/div&gt;&lt;br /&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; result = &lt;span style=&quot;color: #569cd6;&quot;&gt;await&lt;/span&gt; fetchHtml(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;http://ip-api.com/json&#39;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; path = &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/Users/michael/Library/Mobile Documents/com~apple~CloudDocs/HTML/&#39;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; ip = result.query&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; fs = require(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;fs&#39;&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;    fs.writeFileSync(path + &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;myServer.html&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;`&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;H1&amp;gt;&amp;lt;a href=&quot;http://&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;ip&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;/heartBeats&quot;&amp;gt;myServer&amp;lt;/a&amp;gt;&amp;lt;/H1&amp;gt;`&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;    fs.writeFileSync(path + &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;myTool.html&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;`&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;H1&amp;gt;&amp;lt;a href=&quot;http://&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;ip&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;:3000&quot;&amp;gt;myTool&amp;lt;/a&amp;gt;&amp;lt;/H1&amp;gt;`&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div&gt;doIt()&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Important here is the first line. This is required as cron, which will run the script, does not know where my node modules are installed&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;If fetches the IP address from my router (via this &lt;a href=&quot;http://ip-api.com/json&quot; target=&quot;_blank&quot;&gt;URL&lt;/a&gt;), stores it in a link in a HTML file in a folder in iCloud where I can access it from anywhere in the world.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I only needed to to some port forwarding in my router. Port 80/3000 need to forward to my machine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interestingly, once I set it up, he, the router software, told me: my Mac will from now on have a static address. How nice!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Final piece: I created a a soft link in my web documents folder to the folder where I store my bot heart beats. So now I can call my server like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;http://my.ip.address/heartBeats&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and it will show me the directory listing of my heartBeats so I can check from everywhere if my bots are running.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;                      &lt;/div&gt;&lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt; countChapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;).length chapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;) flagLevel = false var toc = &#39;&#39; for (i = 0; i &lt; countChapters; i++){ chapter = chapters[i] chapterTitle = chapters[i].textContent;   chapters[i].setAttribute(&quot;id&quot;, &quot;chapter&quot;+i); if(&#39;H2&#39; == chapter.tagName){ if(flagLevel){ toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }else{ toc += &quot;&lt;ul&gt;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; } flagLevel = true }else{ if(flagLevel){ toc += &quot;&lt;/ul&gt;&quot; flagLevel = false } toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }   // subchapter = document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].getElementsByTagName(&quot;h2&quot;).length; // alert(&quot;Chapter: &quot; + document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].textContent + &quot; has &quot; + subchapter + &quot; subchapters&quot;) } document.getElementById(&quot;myToc&quot;).innerHTML = toc;  &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/3218138741867120932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/other-stuff.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3218138741867120932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3218138741867120932'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/other-stuff.html' title='Other stuff'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-5760920907094614210</id><published>2021-01-28T19:12:00.009+01:00</published><updated>2021-02-03T11:51:42.501+01:00</updated><title type='text'>Create a tool to visually analyse data</title><content type='html'>          &lt;div id=&quot;myToc&quot;&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Other blogs about the topic&lt;/h4&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html&quot;&gt;Main Blog about creating a trading bot&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading strategy explained&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule applications in macOS Big Sur&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Create a tool to visually analyse data&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Problem&lt;/h2&gt;&lt;p&gt;There are so many prices, the oscillation is gargantic.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-UKvYx5XiXFo/X_EPV1T77CI/AAAAAAAAEio/pfE40E7F25AQfqSfwmYrqVj_nrJZBP9WQCPcBGAYYCw/s646/Oscillation.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;517&quot; data-original-width=&quot;646&quot; height=&quot;461&quot; src=&quot;https://1.bp.blogspot.com/-UKvYx5XiXFo/X_EPV1T77CI/AAAAAAAAEio/pfE40E7F25AQfqSfwmYrqVj_nrJZBP9WQCPcBGAYYCw/w576-h461/Oscillation.png&quot; width=&quot;576&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;I want to be able to detect areas where my bot could have succeeded, such that I can analyse patterns which would let my bot make the right decision for a trade.&lt;/p&gt;&lt;p&gt;So I first need to &quot;detect&quot; such areas, and then I need to find out &quot;where&quot; in my data points those areas are.&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Approach&lt;/h2&gt;&lt;p&gt;First I tried Numbers, an Excel-like spreadsheet application which comes with every Mac. While for a small amount of numbers I created &lt;a href=&quot;https://www.youtube.com/watch?v=rDfIR7OYJIk&amp;amp;feature=youtu.be&quot; target=&quot;_blank&quot;&gt;the perfect solution&lt;/a&gt;, for large amount of numbers to analyse the process slows down, drastically.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So I had to rethink. Why not use the data from the database directly?&lt;/p&gt;&lt;p&gt;That basically meant I need a tool to display the chart from data from the database, and I needed a simple responsive web server.&lt;/p&gt;&lt;p&gt;There&#39;s lots of such tools. I decided to go with &lt;a href=&quot;https://developers.google.com/chart&quot; target=&quot;_blank&quot;&gt;Google tools&lt;/a&gt;, check out the Guides and the References part.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-xuLxt75t5Ks/X_OW4wZndyI/AAAAAAAAEjU/d23i3zCzp7Il9Z1GS-X42XBSYYmdH05UgCPcBGAYYCw/s361/Google%2BCharts.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;91&quot; data-original-width=&quot;361&quot; src=&quot;https://1.bp.blogspot.com/-xuLxt75t5Ks/X_OW4wZndyI/AAAAAAAAEjU/d23i3zCzp7Il9Z1GS-X42XBSYYmdH05UgCPcBGAYYCw/s320/Google%2BCharts.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;I did find the perfect tool, yet it was very poorly documented and thus I had to start low. Remember &quot;De- complexify problems&quot;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;do everything manually, use manual (hard coded data)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; data = &lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt; google.visualization.arrayToDataTable([&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;Opening Move&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;Percentage&#39;&lt;/span&gt;],&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;King&#39;s pawn (e4)&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;44&lt;/span&gt;],&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Queen&#39;s pawn (d4)&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;31&lt;/span&gt;],&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Knight to King 3 (Nf3)&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;12&lt;/span&gt;],&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Queen&#39;s bishop pawn (c4)&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;10&lt;/span&gt;],&lt;/div&gt;&lt;div&gt;    [&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;Other&#39;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;3&lt;/span&gt;]&lt;/div&gt;&lt;div&gt;]);&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;notice the &quot;true&quot; parameter, it says: no column headers&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div style=&quot;line-height: 18px;&quot;&gt;data = &lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt; google.visualization.arrayToDataTable(dataFromDB, &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;)&lt;/div&gt;&lt;/div&gt;&lt;p&gt;now I had data, but no column titles&lt;/p&gt;&lt;p&gt;so I changed my result from db to include column headers&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;rows.unshift({  &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;,  &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;response.json(rows);&lt;/div&gt;&lt;/div&gt;&lt;p&gt;but then I had to change that parameter to false&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;data = &lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt; google.visualization.arrayToDataTable(dataFromDB, &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;)&lt;/div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;now the table was too long and didn&#39;t scroll&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I figured after long looking and testing, there&#39;s options you can pass to the view&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; optionsTable = {&lt;/div&gt;&lt;div&gt;    width: &lt;span style=&quot;color: #b5cea8;&quot;&gt;265&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    chartArea: { &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;width&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;100%&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;height&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;65%&#39;&lt;/span&gt; },&lt;/div&gt;&lt;div&gt;    page: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;enabled&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    pageSize: &lt;span style=&quot;color: #b5cea8;&quot;&gt;40&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    allowHtml: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;p&gt;the &quot;page&quot; parameter does it, the result looks like this&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-ckHhhwADo-E/X_EPcfk58BI/AAAAAAAAEis/7MJHJzIgKlIKIpTuUVjgge_z8okMu1GmgCPcBGAYYCw/s606/tableView.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;606&quot; data-original-width=&quot;213&quot; height=&quot;897&quot; src=&quot;https://1.bp.blogspot.com/-ckHhhwADo-E/X_EPcfk58BI/AAAAAAAAEis/7MJHJzIgKlIKIpTuUVjgge_z8okMu1GmgCPcBGAYYCw/w314-h897/tableView.png&quot; width=&quot;314&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;2 things were missing:&lt;/p&gt;&lt;p&gt;I need to be able to page data, like fetch a 1000, then fetch another thousand&lt;/p&gt;&lt;p&gt;I wanted to &quot;interact&quot; with the chart&lt;/p&gt;&lt;p&gt;So for the &quot;paging&quot; mechanism I built to buttons which would fetch the &quot;next&quot; or the &quot;prev&quot; page of data, page being a defined number of rows&lt;/p&gt;&lt;p&gt;the two buttons&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;button&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;onclick&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;javascript:getPage(&#39;prev&#39;)&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;Load Previous Page&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;button&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;onclick&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;javascript:getPage(&#39;next&#39;)&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;Load Next Page&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;the code being called&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; getPage(direction) {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; scriptUrl = &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/data?direction=&quot;&lt;/span&gt; + direction;&lt;/div&gt;&lt;div&gt;    $.ajax({&lt;/div&gt;&lt;div&gt;        url: scriptUrl,&lt;/div&gt;&lt;div&gt;        type: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;get&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        dataType: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;html&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        async: &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        success: &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (data) {&lt;/div&gt;&lt;div&gt;            myJson = JSON.parse(data)&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;let&lt;/span&gt; myArray = myJson.map(obj &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; Object.values(obj));&lt;/div&gt;&lt;div&gt;            dataFromDB = myArray;&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;    drawSort()&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;p&gt;the code on the server being executed, see the &quot;next&quot; / &quot;prev&quot; actions, how this influences the paging (page++ or page--) from the db, see the limit clause&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #569cd6;&quot;&gt;undefined&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;    sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT price ,id from &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;table&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt; limit &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;page * &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;, 1000`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;    db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;            console.error(err.message);&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;        response.json(rows);&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;br /&gt;&lt;div&gt;} &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;next&quot;&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;    page++&lt;/div&gt;&lt;div&gt;    sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT price, id  from &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;table&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt; limit &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;page * &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;, 1000`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;    db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;            console.error(err.message);&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;        response.json(rows);&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;br /&gt;&lt;div&gt;} &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;prev&quot;&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;    page--&lt;/div&gt;&lt;div&gt;    sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT price, id  from &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;table&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt; limit &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;page * &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;, 1000`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;    db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;            console.error(err.message);&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;        response.json(rows);&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;p&gt;But how about &quot;interaction&quot; with the chart? Turns out, you can select points by default. But I wanted more, guess what, there&#39;s options = {} too you can supply to the chart view. You can supply options to zoom in, to reset, for tick marks on the scale and you can turn on multiple selections.&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; options = {&lt;/div&gt;&lt;div&gt;    width: &lt;span style=&quot;color: #b5cea8;&quot;&gt;1000&lt;/span&gt;, height: &lt;span style=&quot;color: #b5cea8;&quot;&gt;800&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    chartArea: { &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;width&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;80%&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;height&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;80%&#39;&lt;/span&gt; },&lt;/div&gt;&lt;div&gt;    selectionMode: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;multiple&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    explorer: { actions: [&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;dragToZoom&#39;&lt;/span&gt;], maxZoomIn: &lt;span style=&quot;color: #b5cea8;&quot;&gt;.01&lt;/span&gt;, keepInBounds: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt; },&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So far so good, but I wanted to do something with that info. As a first step, I intercepted the clicked points, made sure only 2 can be selected, and I changed the tooltip, which per default was info from the table. Now I wanted the tooltip to show percentage change from the first point clicked.&lt;/p&gt;&lt;p&gt;After a lot of testing I figured it out.&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;google.visualization.events.addListener(chart, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;select&#39;&lt;/span&gt;, selectHandler);&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// make sure we only have 2 points selected&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; selectedPoints = []&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; selectHandler(e) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    selectedPoints = chart.getSelection()&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; selectedItem = chart.getSelection()[selectedPoints.length - &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;];&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (selectedItem) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        &lt;span style=&quot;color: #6a9955;&quot;&gt;// make sure we only have 2 points selected, delete one if we select 3&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt; &amp;lt; selectedPoints.length) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            selectedPoints.pop()&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            selectedPoints.pop()&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            selectedPoints.push(selectedItem)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            chart.setSelection(selectedPoints)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        &lt;span style=&quot;color: #6a9955;&quot;&gt;// if 1 point is selected, update the tool tips of all others with percentage change related to the first selected point &lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt; == selectedPoints.length) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;for&lt;/span&gt; (i = &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;; i &amp;lt; dataFromDB.length - &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;; i++) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                point1 = data.getValue(selectedPoints[&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;].row, selectedPoints[&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;].column)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                point2 = data.getValue(i, &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                change = (point2 / point1 * &lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;) - &lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt; &amp;gt; change) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                    data.setCell(i, &lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;`&amp;lt;p style=&quot;font-size:25px; text-align: right&quot;&amp;gt;price: &amp;lt;b&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;point2&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;font style=&quot;color:red&quot;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;change.toFixed(&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;)&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;%&amp;lt;/font&amp;gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                } &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                    data.setCell(i, &lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;`&amp;lt;p style=&quot;font-size:25px; text-align: right&quot;&amp;gt;price: &amp;lt;b&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;point2&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;change.toFixed(&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;)&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;%&amp;lt;/p&amp;gt;`&lt;/span&gt;)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;                }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;            }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-dYWP_YvWzWs/X_EQDpVaGHI/AAAAAAAAEi8/he-lbUygP4AFyEMZnL6G8USuwLdtEIzSQCPcBGAYYCw/s301/upChange.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;236&quot; data-original-width=&quot;301&quot; src=&quot;https://1.bp.blogspot.com/-dYWP_YvWzWs/X_EQDpVaGHI/AAAAAAAAEi8/he-lbUygP4AFyEMZnL6G8USuwLdtEIzSQCPcBGAYYCw/s0/upChange.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;positive change in price&lt;/div&gt;&lt;p&gt;&lt;br style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot; /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-Pq6YpUfgJqA/X_EQI1AB4sI/AAAAAAAAEjA/9EHZqhyPNPMiVDFgtna3_TN6kgfydQq9gCPcBGAYYCw/s301/DownChange.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;236&quot; data-original-width=&quot;301&quot; src=&quot;https://1.bp.blogspot.com/-Pq6YpUfgJqA/X_EQI1AB4sI/AAAAAAAAEjA/9EHZqhyPNPMiVDFgtna3_TN6kgfydQq9gCPcBGAYYCw/s0/DownChange.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center;&quot;&gt;positive change in price&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;Turns out, that for HTML tooltips I needed to enable in 2 areas the HTML option. I figured this out by accident. You can see this in the code above which shows the options for the chart and here:&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;data.addColumn({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;type&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;string&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;role&#39;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;tooltip&#39;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;p&#39;&lt;/span&gt;: { &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;html&#39;&lt;/span&gt;: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt; } });&lt;/div&gt;&lt;p&gt;And this is the full prototype&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-nQ3OV5bc9kE/X_EPjia8byI/AAAAAAAAEiw/vrE_S5gkXw0_8xDQeIv8aNUc-8eN_-4PgCPcBGAYYCw/s1204/visualToolPrototype.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;718&quot; data-original-width=&quot;1204&quot; height=&quot;397&quot; src=&quot;https://1.bp.blogspot.com/-nQ3OV5bc9kE/X_EPjia8byI/AAAAAAAAEiw/vrE_S5gkXw0_8xDQeIv8aNUc-8eN_-4PgCPcBGAYYCw/w664-h397/visualToolPrototype.png&quot; width=&quot;664&quot; /&gt;&lt;/a&gt;&lt;/div&gt;and here it is in action &lt;a href=&quot;https://youtu.be/DFV3qq-4oIY&quot;&gt;https://youtu.be/DFV3qq-4oIY&lt;/a&gt;&lt;br /&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Intercept key presses&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Problem&lt;/h2&gt;&lt;div&gt;I want to be able to mark data points in my database for which I should need to do some deeper analysis. I want to do this via key press (eg &amp;lt;ctrl&amp;gt;&amp;lt;s&amp;gt;).&lt;/div&gt;&lt;div&gt;I also want to be able to simpler remove already selected points from the line chart. The &quot;normal&quot; way is clicking them again to unselect them. But this is rather daunting cause you need to be accurate.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Approach&lt;/h2&gt;&lt;div&gt;Don&#39;t even bother handling key events yourself. Let jQuery do that for you. It does it nicely, and (hopefully) across all browsers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;$(document).keydown(&lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (event) {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #6a9955;&quot;&gt;// &amp;lt;ctrl&amp;gt;&amp;lt;s&amp;gt; shall mark the point in the db&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (event.ctrlKey &amp;amp;&amp;amp; event.which == &lt;span style=&quot;color: #b5cea8;&quot;&gt;83&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;        savePoint()&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Adjusting my line chart&lt;/h1&gt;&lt;div&gt;So while I am developing my bot I try to improve its &quot;clairvoyance&quot;, such that he may predict a drop or rise better. So I am introducing additional parameters I want to display in my line chart.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-U47lh9Q21Ik/X_gjvQVZUYI/AAAAAAAAEjk/saW5l-FpIiMhLPBcaLqZmLxAHM0HN2HrwCPcBGAYYCw/s860/wrong%2BAxes.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;555&quot; data-original-width=&quot;860&quot; height=&quot;376&quot; src=&quot;https://1.bp.blogspot.com/-U47lh9Q21Ik/X_gjvQVZUYI/AAAAAAAAEjk/saW5l-FpIiMhLPBcaLqZmLxAHM0HN2HrwCPcBGAYYCw/w584-h376/wrong%2BAxes.png&quot; width=&quot;584&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;Doesn&#39;t help a lot if the red line is squeezed to the bottom due to having totally different values than the blue line.&lt;/div&gt;&lt;div&gt;After hours of searching I figured these settings in the display options of the chart help.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;series: {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;: { targetAxisIndex: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt; },&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;: { targetAxisIndex: &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt; }&lt;/div&gt;&lt;div&gt;}, vAxes: {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;: {&lt;/div&gt;&lt;div&gt;        minValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;20&lt;/span&gt;, maxValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;70&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    }, &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;: {&lt;/div&gt;&lt;div&gt;        minValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0.2&lt;/span&gt;, maxValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0.7&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;},&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Result&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-A93coI2FtPw/X_gloi_039I/AAAAAAAAEjw/PxfhPRfGVRMYf5QVdQ72Qxi1M38HQ9IYQCPcBGAYYCw/s860/correct%2BAxes.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;555&quot; data-original-width=&quot;860&quot; height=&quot;370&quot; src=&quot;https://1.bp.blogspot.com/-A93coI2FtPw/X_gloi_039I/AAAAAAAAEjw/PxfhPRfGVRMYf5QVdQ72Qxi1M38HQ9IYQCPcBGAYYCw/w574-h370/correct%2BAxes.png&quot; width=&quot;574&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;series: {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;: { targetAxisIndex: &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt; },&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;: { targetAxisIndex: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt; }&lt;/div&gt;&lt;div&gt;}, vAxes: {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;: {&lt;/div&gt;&lt;div&gt;        minValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;20&lt;/span&gt;, maxValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;70&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    }, &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;: {&lt;/div&gt;&lt;div&gt;        minValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0.2&lt;/span&gt;, maxValue: &lt;span style=&quot;color: #b5cea8;&quot;&gt;0.7&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;},&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-1WamyKIZoCk/X_gmT9cWcKI/AAAAAAAAEj4/dGnPanYTZnY2eQriQySUmGxwdZBj2ahrgCPcBGAYYCw/s860/all%2Bfine.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;555&quot; data-original-width=&quot;860&quot; height=&quot;377&quot; src=&quot;https://1.bp.blogspot.com/-1WamyKIZoCk/X_gmT9cWcKI/AAAAAAAAEj4/dGnPanYTZnY2eQriQySUmGxwdZBj2ahrgCPcBGAYYCw/w586-h377/all%2Bfine.png&quot; width=&quot;586&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;How to zoom-out of a chart&lt;/h1&gt;&lt;div&gt;&lt;div&gt;Zooming in in Google charts is a breeze. You just need to set the appropriate option, see chapter &quot;Create a tool to visually analyse data&quot;.&lt;/div&gt;&lt;div&gt;But if you want to zoom out step by step it&#39;s a bit more complicated. But I found some code from the same guy (&lt;a href=&quot;https://stackoverfow.com/users/5090771/whitehat&quot;&gt;https://stackoverfow.com/users/5090771/whitehat&lt;/a&gt;) from whom I &quot;stole&quot; already the code to &quot;reset&quot; the zoom level in case I need a redraw, which I do if I click a point and I need to change all tooltips.&lt;/div&gt;&lt;div&gt;So the new piece of code is this here:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; container = document.getElementById(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;chart_sort_div&#39;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;google.visualization.events.addListener(chart, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;ready&#39;&lt;/span&gt;, &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; () {&lt;/div&gt;&lt;div&gt;    zoomLast = getCoords();&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #6a9955;&quot;&gt;//zoomCoords.push(zoomLast)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; observer = &lt;span style=&quot;color: #569cd6;&quot;&gt;new&lt;/span&gt; MutationObserver(&lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; () {&lt;/div&gt;&lt;div&gt;        zoomCurrent = getCoords();&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (JSON.stringify(zoomLast) !== JSON.stringify(zoomCurrent)) {&lt;/div&gt;&lt;div&gt;            zoomCoords.push(zoomLast)&lt;/div&gt;&lt;div&gt;            zoomLast = getCoords();&lt;/div&gt;&lt;br /&gt;&lt;div&gt;            console.log(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;zoom event&#39;&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;    observer.observe(container, {&lt;/div&gt;&lt;div&gt;        childList: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        subtree: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;})&lt;/div&gt;&lt;div&gt;chart.draw(viewChart, options);&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Pay attention to the &quot;container&quot; variable!&lt;/div&gt;&lt;div&gt;And this is also needed for the right click not to reset, but to zoom out:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; zoomOut() {&lt;/div&gt;&lt;div&gt;    options.hAxis.viewWindow = {};&lt;/div&gt;&lt;div&gt;    options.vAxis.viewWindow = {};&lt;/div&gt;&lt;div&gt;    coords = zoomCoords.pop()&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (coords) {&lt;/div&gt;&lt;div&gt;        options.hAxis.viewWindow.min = coords.x.min;&lt;/div&gt;&lt;div&gt;        options.hAxis.viewWindow.max = coords.x.max;&lt;/div&gt;&lt;div&gt;        options.vAxis.viewWindow.min = coords.y.min;&lt;/div&gt;&lt;div&gt;        options.vAxis.viewWindow.max = coords.y.max;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    viewChart.setColumns(axesToDisplay)&lt;/div&gt;&lt;br /&gt;&lt;div&gt;    chart.draw(viewChart, options);&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and a global variable&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; zoomCoords = []&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;and that&#39;s it! Again, so simple&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Adding a slider to move between pages of data&lt;/h1&gt;&lt;div&gt;&lt;div&gt;I first had added a prev/next page button. But since then my data has grown and I need to be able to move faster than click 100 times the next button.&lt;/div&gt;&lt;div&gt;How about using a &quot;slider&quot; like this&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-zHUXduvUz8c/X_9VqnZDkNI/AAAAAAAAEkE/9evJHD1Uo7g1qjcayX8DzWSoQmewGLnYACPcBGAYYCw/s556/Screenshot%2B2021-01-13%2Bat%2B21.17.49.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;34&quot; data-original-width=&quot;556&quot; height=&quot;32&quot; src=&quot;https://1.bp.blogspot.com/-zHUXduvUz8c/X_9VqnZDkNI/AAAAAAAAEkE/9evJHD1Uo7g1qjcayX8DzWSoQmewGLnYACPcBGAYYCw/w541-h32/Screenshot%2B2021-01-13%2Bat%2B21.17.49.png&quot; width=&quot;541&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Fortunately jQuery UI has a slider tool as standard. The normal slider doesn&#39;t show the value, so how do you know where you are? Easy! There&#39;s a &quot;slide&quot; event on the slider, use it to read the current &quot;value&quot; and set that value as text of the slider element:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;doctype&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;html&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;lang&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;charset&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;slider demo&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;link&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;rel&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;href&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #d7ba7d;&quot;&gt;#slider&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #9cdcfe;&quot;&gt;margin&lt;/span&gt;: &lt;span style=&quot;color: #b5cea8;&quot;&gt;10px&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;//code.jquery.com/jquery-1.12.4.js&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;//code.jquery.com/ui/1.12.1/jquery-ui.js&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #9cdcfe;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;slider&quot;&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).slider();&lt;/div&gt;&lt;div&gt;        $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).slider(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;option&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;max&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;50&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;        $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).slider(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;option&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;min&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b5cea8;&quot;&gt;10&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;        sliderHandle = &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;.ui-slider-handle&quot;&lt;/span&gt; &lt;span style=&quot;color: #6a9955;&quot;&gt;//insideHTML&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).on(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;slide&quot;&lt;/span&gt;, &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (event, ui) {&lt;/div&gt;&lt;div&gt;            $(sliderHandle).text(ui.value)&lt;/div&gt;&lt;div&gt;        });&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: grey;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now obviously you need to know which tables have how many pages to display. Add something like this to your &lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;server&lt;/a&gt;:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;app.get(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/pages&#39;&lt;/span&gt;, (request, response) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT count(id) as count from &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;table&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;    db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;            console.error(err.message);&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        response.json(rows);&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;})&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Make sure you call the &quot;/pages&quot; on load somewhere on the HTML document&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; scriptUrl = &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/pages&quot;&lt;/span&gt; + name;&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;$.ajax({&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    url: scriptUrl,&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    type: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;get&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    dataType: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;html&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    async: &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    success: &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (data) {&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        console.log(data)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        count = JSON.parse(data)[&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;].count&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;        pages = Math.ceil(count / &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;)&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;    }&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;});&lt;/div&gt;&lt;br style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot; /&gt;&lt;/div&gt;&lt;div&gt;On slide stop you want to retrieve the actual data page of your db:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;$(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).on(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;slidestop&quot;&lt;/span&gt;, &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (event, ui) {&lt;/div&gt;&lt;div&gt;    value = $(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;#slider&quot;&lt;/span&gt;).slider(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;option&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;value&quot;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;    console.log(value)&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; scriptUrl = &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/data?page=&quot;&lt;/span&gt; + value;&lt;/div&gt;&lt;div&gt;    $.ajax({&lt;/div&gt;&lt;div&gt;        url: scriptUrl,&lt;/div&gt;&lt;div&gt;        type: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;get&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        dataType: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;html&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        async: &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;        success: &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (data) {&lt;/div&gt;&lt;div&gt;            myJson = JSON.parse(data)&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;let&lt;/span&gt; myArray = myJson.map(obj &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; Object.values(obj));&lt;/div&gt;&lt;div&gt;            dataFromDB = myArray;&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    });&lt;/div&gt;&lt;div&gt;    drawSort()&lt;/div&gt;&lt;br /&gt;&lt;div&gt;});&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There&#39;s lots of opportunities to customise further&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;       &lt;/div&gt;&lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt; countChapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;).length chapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;) flagLevel = false var toc = &#39;&#39; for (i = 0; i &lt; countChapters; i++){ chapter = chapters[i] chapterTitle = chapters[i].textContent;   chapters[i].setAttribute(&quot;id&quot;, &quot;chapter&quot;+i); if(&#39;H2&#39; == chapter.tagName){ if(flagLevel){ toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }else{ toc += &quot;&lt;ul&gt;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; } flagLevel = true }else{ if(flagLevel){ toc += &quot;&lt;/ul&gt;&quot; flagLevel = false } toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }   // subchapter = document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].getElementsByTagName(&quot;h2&quot;).length; // alert(&quot;Chapter: &quot; + document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].textContent + &quot; has &quot; + subchapter + &quot; subchapters&quot;) } document.getElementById(&quot;myToc&quot;).innerHTML = toc;  &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/5760920907094614210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5760920907094614210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5760920907094614210'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html' title='Create a tool to visually analyse data'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-UKvYx5XiXFo/X_EPV1T77CI/AAAAAAAAEio/pfE40E7F25AQfqSfwmYrqVj_nrJZBP9WQCPcBGAYYCw/s72-w576-h461-c/Oscillation.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-7297508278738498584</id><published>2021-01-28T18:56:00.023+01:00</published><updated>2021-02-02T23:01:31.301+01:00</updated><title type='text'>Schedule programs on macOS</title><content type='html'>          &lt;div id=&quot;myToc&quot;&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt; &lt;div style=&quot;text-align: left;&quot;&gt;&lt;h4&gt;Other blogs about the topic&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html&quot;&gt;Main Blog about creating a trading bot&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading strategy explained&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule applications in macOS Big Sur&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Schedule programs on macOS&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Problem&lt;/h2&gt;&lt;div&gt;&lt;div&gt;While I could use the WebSocket application as a kind of &quot;heartbeat&quot;, there may arise situations where this is not the optimal solution.&lt;/div&gt;&lt;div&gt;For this purpose I run on my machine an application which fetches the latest trades, calculates average price (not average weight price yet) and stores it in a db.&lt;/div&gt;&lt;div&gt;But I need to run that piece of code every minute exactly.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Approach&lt;/h2&gt;&lt;div&gt;&lt;div&gt;Under macOS (Big Sur or any other) there&#39;s two ways to define a scheduled application. Pre Big Sur I used the Launch Agents functionality, which requires a plst file with relevant attributes/data. This file is then kind of &quot;loaded&quot; into the launchctl daemon.&lt;/div&gt;&lt;div&gt;That was the first approach and it failed miserably trying to load the plst file.&lt;/div&gt;&lt;div&gt;So I googled a bit and found this solution: &lt;a href=&quot;https://www.jcchouinard.com/python-automation-with-cron-on-mac/&quot; target=&quot;_blank&quot;&gt;https://www.jcchouinard.com/python-automation-with-cron-on-mac/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;It pretty simple explains how you can use crontab to do the same. And it actually works.&lt;/div&gt;&lt;div&gt;So, remember &quot;De-complexify problems&quot;, I first did a very simple test. A little Python application which would just print the date. I didn&#39;t even know yet where it would print it (in the system console maybe?)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; time&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; datetime &lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; datetime&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;timestamp = time.time()&lt;/div&gt;&lt;div style=&quot;background-color: #1e1e1e; caret-color: rgb(212, 212, 212); color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; white-space: pre;&quot;&gt;print(datetime.fromtimestamp(timestamp)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I added a first scheduled script to crontab:&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;* * * * * /Users/michael/Python/script.py&amp;gt;&amp;gt;&lt;/span&gt;/Users/Michael/Python/output.log&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;So I expected to see a an output.log file but I didn&#39;t.&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Fortunately, this was new to me, cron sent me a mail on the machine.&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;There it said: Operation not permitted.&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Here the article (see link above) helped. I needed to add cron to the Applications which have Full Disk Access.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Now it worked like a charm.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Next step was to try and have cron run my python script which would fetch every minute data from Bitstamp.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;This failed miserably. And it took me hours to figure out what the reason was.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;The error message, as before I received emails with the error, said:&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;ImportError: No module named requests&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;When I ran the same script manually it worked like a charm. So it looked like there was a problem with the installation of the module requests, at least cron didn&#39;t seem to be able to find that module.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;I tried installing in another directory, failed.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;I tried uninstalling, reinstalling, it installed in the same directory, failed.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Then I found help via Google search. You can actually prepend the PYTHONPATH to the cron tab command, like this:&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;* * * * *&amp;nbsp;&lt;/span&gt;PYTHONPATH=/usr/local/lib/python3.9/site-package /Users/michael/Python/script.py&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;Ever since the script runs ever minute and does it&#39;s job: retrieve the trades from the last minute from Bitstamp.&lt;/p&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Make sure output is written immediately to log files&lt;/h1&gt;&lt;div&gt;As I have several cron jobs running, outputting some data, specially to see they are live and running, I had a problem: those jobs would only print to my out Oles after they had received a certain amount of data. This resulted in a not so chronological output. I had to make sure that the output is sent immediately.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;And, alas, there&#39;s a solution: unbuffer!&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Install unbuffer with brew&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;brew install expect&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then issue your calls like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;/usr/local/bin/unbuffer python3 pathToYourScript.py &amp;gt;&amp;gt; pathToYourLog.txt&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The paths should be ABSOLUTE for them to work 100%. and it works, output is immediately written.&lt;/div&gt;&lt;div&gt;Another thing I learned and tested already: One can call simply scripts from crontab. This makes crontab way more easy to read and I can put the heavy lines into a simple shell file.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Simplify scheduled jobs&lt;/h1&gt;&lt;div&gt;As mentioned above I use crontab on macOS cause on Big Sur somehow the launchd doesn&#39;t load my plist files properly. Others report the same issue.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On crontab it&#39;s crowded. One line can be more than 200 characters long, which makes editing (and even worse viewing) a pain. Reason for that long line is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I need to add the proper PYTHONPATH, the unbuffer from the last chapter, the proper path to python3, the proper path to my script and finally the proper path to my out file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And using those shell editors ain&#39;t a lot of fun either.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But with BBEdit on my Mac, my dearest most loved and used companion since I have Macs, editing files is a breeze. So the route is: creating a shell script which does what the cronjob would do, and call from the cronjob the script. Sounds a bit complicated, having a 2 step process now as compared to one step before.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Before&lt;/b&gt;&lt;/div&gt;&lt;div&gt;cronjob =&amp;gt; python script&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Now&lt;/b&gt;&lt;/div&gt;&lt;div&gt;cronjob =&amp;gt; shell script =&amp;gt; python script&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The advantage is a much easier interface to maintain my scheduled jobs, cause editing the shell script is way easier than editing the crontab, and crontab is very simplistic now, with only about 90 characters per job.&lt;/div&gt;&lt;div&gt;I had a problem though now: In case I need to &quot;interrupt&quot; my scheduled jobs, how would I achieve this? Turns out I can send any &quot;signal&quot; to my python script. Before I always used KILL only. But this prevented the script from doing clean up work, such as deleting the lock file. By using another signal, INT in this case, I can intercept and react accordingly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;List of available signals:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;INT seems the same as &amp;lt;ctrl&amp;gt;&amp;lt;c&amp;gt; which I use if I manually invoke those scripts.&lt;/div&gt;&lt;div&gt;Unfortunately this didn&#39;t seem to work, at first at least.&lt;/div&gt;&lt;div&gt;Python code to act upon:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; signal&lt;/div&gt;&lt;div&gt;signal.signal(signal.SIGINT, receiveSignal)&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Use the receiveSignal handler to handle what needs being handled, ie. getting rid of lck files.&lt;/div&gt;&lt;div&gt;Kill won&#39;t let the code react on it, it simply terminates&lt;/div&gt;&lt;div&gt;If you run a python script by cron, will spawn always 2 processes.&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/questions/24989154/cronjob-command-starts-2-processes-for-1-python-script&quot;&gt;https://stackoverflow.com/questions/24989154/cronjob-command-starts-2-processes-for-1-python-script&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I didn&#39;t know about that. Well I knew I always had 2 processes, but didn&#39;t know why. Killing one killed the other usually as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now knowing one is the script and the other one is python runtime (can we call it like that?) I just need to send the signal to the proper process.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I&#39;m doing this with a nice little shell script which ps|grep and finds the process id to kill the appropriate process.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;#!/bin/zsh&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 13px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;process=$(ps -ax|grep -v grep|grep &quot;Cellar.*temp_socket.py&quot;)&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;pid=${process:0:5}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;kill -s int $pid&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;echo &quot;temp_socket.py terminated&quot;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;End result:&lt;/div&gt;&lt;div&gt;scripts which send their output immediately to the out file and shell scripts which let me easily terminate those processes without to much of manual work.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Delete lock files upon machine boot/reboot&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Giving launchd / launchctl another try&lt;/h2&gt;&lt;div&gt;So while I was mostly settled with my setup there was one problem:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I do not know which signal my processes (my bots) receive when I reboot my machine.&lt;/div&gt;&lt;div&gt;Which is why I can&#39;t properly close my bots and let them do the clean up (mainly moving log files and deleting the lock files).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After some thinking I got the idea: I only have to make sure that upon login those lock files are deleted. But crontab / cronjobs wasn&#39;t done for this purpose.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Maybe give launchd / launchctl another try?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;-rwxr--r--@&amp;nbsp; 1 root &amp;nbsp; &amp;nbsp; wheel &amp;nbsp; 599 Feb&amp;nbsp; 2 19:25 &lt;/span&gt;&lt;span style=&quot;color: #38b9c7; font-variant-ligatures: no-common-ligatures;&quot;&gt;deleteLockFiles.plist&lt;/span&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;*&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;span style=&quot;font-family: -webkit-standard; font-size: medium;&quot;&gt;So you need to put a PLIST (not plst, my first attempt was always with plst which did never work) file into the ~/Library/LaunchAgents directory.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;span style=&quot;font-family: -webkit-standard; font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;span style=&quot;font-family: -webkit-standard; font-size: medium;&quot;&gt;Content of PLIST file:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;plist version=&quot;1.0&quot;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;string&amp;gt;com.yourName.deleteLckFiles&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;array&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;string&amp;gt;/path/to/your/script/deleteLckFiles.sh&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/array&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;KeepAlive&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;false/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;StandardErrorPath&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;string&amp;gt;/path/to/your/script/launchd_error.txt&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;StandardOutPath&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;string&amp;gt;/path/to/your/script/launchd_log.txt&amp;lt;/string&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;key&amp;gt;RunAtLoad&amp;lt;/key&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;true/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;lt;/plist&amp;gt;&lt;span style=&quot;font-family: -webkit-standard; font-size: medium;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;load the plist file:&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;sudo launchctl load deleteLckFiles.plist&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: -webkit-standard; font-size: medium;&quot;&gt;unload the plist file:&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;sudo launchctl load deleteLckFiles.plist&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the shell script itself can look like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;#!/bin/zsh&lt;/div&gt;&lt;div&gt;cd /usually/your/home/directory&lt;/div&gt;&lt;div&gt;ls -d *.lck&lt;/div&gt;&lt;div&gt;rm *.lck&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And that&#39;s it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As always: start slow and easy (remember: Decomplexify problems):&lt;/div&gt;&lt;div&gt;As those background jobs (crontab/launchd/launchctl) do have different &quot;default&quot; paths, this is always a bit a gamble to know where your output files end up and if crontab and launchd can access your scripts&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So first:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;create a simply script just echoing &quot;Hello world&quot;, have the script and the output file in your home directory, just to make sure.&lt;/li&gt;&lt;li&gt;then you may move the script to the directory where it finally will be called, if this does not work, you may need to give in the Security System Preference Panel Full Disk Access to the shell&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-YJ3hb9A2sYs/YBnLLCkhBrI/AAAAAAAAEkw/euPsPRQPGWUuClTcNnxUHqdnT5NAze3NwCLcBGAsYHQ/s663/Screenshot%2B2021-02-02%2Bat%2B22.58.43.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;581&quot; data-original-width=&quot;663&quot; height=&quot;433&quot; src=&quot;https://1.bp.blogspot.com/-YJ3hb9A2sYs/YBnLLCkhBrI/AAAAAAAAEkw/euPsPRQPGWUuClTcNnxUHqdnT5NAze3NwCLcBGAsYHQ/w494-h433/Screenshot%2B2021-02-02%2Bat%2B22.58.43.png&quot; width=&quot;494&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;and increase the complexity&lt;/li&gt;&lt;li&gt;I gave up trying to run my bots via launchd, couldn&#39;t figure out how to define the paths so the python scripts work properly, but my shell scripts run just about fine via launchd / launchctl&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;  &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt; countChapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;).length chapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;) flagLevel = false var toc = &#39;&#39; for (i = 0; i &lt; countChapters; i++){ chapter = chapters[i] chapterTitle = chapters[i].textContent;   chapters[i].setAttribute(&quot;id&quot;, &quot;chapter&quot;+i); if(&#39;H2&#39; == chapter.tagName){ if(flagLevel){ toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }else{ toc += &quot;&lt;ul&gt;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; } flagLevel = true }else{ if(flagLevel){ toc += &quot;&lt;/ul&gt;&quot; flagLevel = false } toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }   // subchapter = document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].getElementsByTagName(&quot;h2&quot;).length; // alert(&quot;Chapter: &quot; + document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].textContent + &quot; has &quot; + subchapter + &quot; subchapters&quot;) } document.getElementById(&quot;myToc&quot;).innerHTML = toc;  &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/7297508278738498584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7297508278738498584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7297508278738498584'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html' title='Schedule programs on macOS'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-YJ3hb9A2sYs/YBnLLCkhBrI/AAAAAAAAEkw/euPsPRQPGWUuClTcNnxUHqdnT5NAze3NwCLcBGAsYHQ/s72-w494-h433-c/Screenshot%2B2021-02-02%2Bat%2B22.58.43.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-1845705104554139269</id><published>2021-01-28T18:56:00.019+01:00</published><updated>2021-02-02T10:39:05.662+01:00</updated><title type='text'>Coding</title><content type='html'>          &lt;div id=&quot;myToc&quot;&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt;       &lt;h4&gt;Other blogs about the topic&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html&quot;&gt;Main Blog about creating a trading bot&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading strategy explained&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule applications in macOS Big Sur&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Creating a responsive web server&lt;/h1&gt;&lt;div&gt;For the visual tool to analyse my charts I needed something to deliver the data to the tool.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;While I was a few months back playing around with ideas and technologies, I came across NodeJS. Which is the easiest way for you to create a Webserver based on JavaScript language.&lt;/div&gt;&lt;div&gt;Don&#39;t believe me? Checkout the document Introduction into programming from the ZIP file you find in the description of this video: &lt;a href=&quot;https://youtu.be/l3undRJAuAU&quot;&gt;https://youtu.be/l3undRJAuAU&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There you find information to get started with NodeJS.&lt;/div&gt;&lt;div&gt;Let me tell you: it is so easy, it makes me totally happy to be able to return data for asynchronous calls to my webpage within a few minutes.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; path = require(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;path&#39;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; express = require(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;express&#39;&lt;/span&gt;);&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; app = express();&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; session = require(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;express-session&#39;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;app.use(session({&lt;/div&gt;&lt;div&gt;    secret: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;chosen language&#39;&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    saveUninitialized: &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;    resave: &lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;,&lt;/div&gt;&lt;div&gt;}))&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; server = app.listen(&lt;span style=&quot;color: #b5cea8;&quot;&gt;3000&lt;/span&gt;, &lt;span style=&quot;color: #569cd6;&quot;&gt;function&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;    app.use(express.static(__dirname + &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/&#39;&lt;/span&gt;));&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;        console.log(err.message)&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    console.log(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Server listening at port 3000&quot;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Obviously it does not do much besides listening to incoming requests on port 3000.&lt;/div&gt;&lt;div&gt;You add a little bit of code like:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;app.get(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/&#39;&lt;/span&gt;, (request, response) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    response.sendFile(path.join(__dirname, &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;index.html&#39;&lt;/span&gt;));&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;div&gt;app.get(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/manual&#39;&lt;/span&gt;, (request, response) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    response.send(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Hello world, no HTML code, pure text&quot;&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;div&gt;app.get(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/test&#39;&lt;/span&gt;, (request, response) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;let&lt;/span&gt; path = url.parse(request.url).pathname;&lt;/div&gt;&lt;div&gt;    console.log(path)&lt;/div&gt;&lt;div&gt;    json = { Name: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;Michael&#39;&lt;/span&gt;, LastName: &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;Zischeck&#39;&lt;/span&gt; }&lt;/div&gt;&lt;div&gt;    response.json(json)&lt;/div&gt;&lt;div&gt;})&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Then you can call your web server like:&amp;nbsp;&lt;/div&gt;&lt;div&gt;http://localhost:3000/manual&lt;/div&gt;&lt;div&gt;http://localhost:3000/test&lt;/div&gt;&lt;div&gt;http://localhost:3000/ (this will serve you the index.html from the same directory as from where you run the server&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;Isn&#39;t that simple?&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How about returning data from a database, sqlite3 in this example:&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;app.get(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;/data&#39;&lt;/span&gt;, (request, response) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;let&lt;/span&gt; path = url.parse(request.url).pathname;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; parts = url.parse(request.url, &lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;);&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;var&lt;/span&gt; query = parts.query;&lt;/div&gt;&lt;div&gt;    action = query.page&lt;/div&gt;&lt;div&gt;    console.log(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;action:&quot;&lt;/span&gt; + action)&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #569cd6;&quot;&gt;undefined&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;        sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;SELECT id, price from tableName limit 0, 1000&#39;&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;        db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;                console.error(err.message);&lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;            rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;            response.json(rows);&lt;/div&gt;&lt;div&gt;        });&lt;/div&gt;&lt;div&gt;    } &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;next&quot;&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;        page++&lt;/div&gt;&lt;div&gt;        sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT id, price from tableName limit &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;page * &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;, 1000`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;        db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;                console.error(err.message);&lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;            rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;            response.json(rows);&lt;/div&gt;&lt;div&gt;        });&lt;/div&gt;&lt;div&gt;    } &lt;span style=&quot;color: #569cd6;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (action == &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;prev&quot;&lt;/span&gt;) {&lt;/div&gt;&lt;div&gt;        page--&lt;/div&gt;&lt;div&gt;        sql = &lt;span style=&quot;color: #ce9178;&quot;&gt;`SELECT id, price from tableName limit &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;${&lt;/span&gt;page * &lt;span style=&quot;color: #b5cea8;&quot;&gt;500&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;, 1000`&lt;/span&gt;;&lt;/div&gt;&lt;div&gt;        db.all(sql, (err, rows) &lt;span style=&quot;color: #569cd6;&quot;&gt;=&amp;gt;&lt;/span&gt; {&lt;/div&gt;&lt;div&gt;            &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; (err) {&lt;/div&gt;&lt;div&gt;                console.error(err.message);&lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;            rows.unshift({ &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;id&quot;&lt;/span&gt;, &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt;: &lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;price&quot;&lt;/span&gt; })&lt;/div&gt;&lt;div&gt;            response.json(rows);&lt;/div&gt;&lt;div&gt;        });&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;That&#39;s it! Complete code for my visual chart analysis tool! How easy is this?&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Going back to Python&lt;/h1&gt;&lt;div&gt;&lt;div&gt;While I was almost done with my trading bot in NodeJS, I basically converted the most important parts of my Orst attempt in Python, it happened that when I run simulations, like tens of thousands of rows to process, NodeJS went nuts.&lt;/div&gt;&lt;div&gt;I really tried, and I really would have wanted to stay with NodeJS, but I won&#39;t! To much asynchronous.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In Python I have everything under control.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I will leave in NodeJS is my other project. A tool to analyse XRPL accounts.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The good news though is this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I ported from Python to NodeJS, I simplified a lot. Made the whole logic more straightforward, and guess what: I found a simple, very stupid but very powerful bug in my logic!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So even if this sideway to NodeJS and back to Python was just about to figure out this stupid bug, then it was worth it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Actually it was not even a bug, it was more a strange thing in my logic.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It boils down to this:&lt;/div&gt;&lt;div&gt;With my trading bot I want to prove that even in bearish markets I can profit. So basically I apply the Stop Loss strategy explained &lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In short:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;If prices drop, I sell, and I rebuy at lower price, if possible.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Sometimes, the price does not drop further after I sold, but keeps rising. Then I have to rebuy in at a higher price, and at a loss obviously.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That&#39;s all part of the &quot;strategy&quot;, the idea being I can buy more often low, than I have to buy high. And that I can buy relatively lower than I have to buy higher.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But there&#39;s times, hopefully a lot of times, where the prices just keep rising. What then? Well I have to adjust my triggers as to when I want to sell. Those triggers keep rising.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my old code I would &quot;UP THE ANTE&quot; every time a new high was reached. With the stupid effect, that, obviously, after the high the price starts dropping any my bot does its duly work: it sells (unfortunately at a way to high price).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I figured now that I should better only &quot;UP THE ANTE&quot; a little bit, like a 1/10 of the previous high price and the new high price.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Like old price (for my calculations) was 1$, new price is 1.20$. Now I will only increase the price for my calculations to 1.02$ and not to 1.20.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With the effect, that I &quot;grow&quot; into rising prices without ever risking selling too early again.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So today I finished my bot, it will start in 15 minutes to run, for a whole day long. Then we&#39;ll see what happens.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Bot simulation&lt;/h1&gt;&lt;div&gt;For my bot simulations I wanted to calculate as many possibilities as possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have 3 triggers: sell low, rebuy lower, or rebuy higher (in case the price does not drop to the rebuy lower level). I wanted to see the outcome for all possibilities, in order for me to chose the right levels for the 3 triggers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me give you an example to understand this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Price of the asset is 10&lt;/div&gt;&lt;div&gt;It drops, sell trigger defines when to sell.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Is sell trigger at 10% then I would sell at 9.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If rebuy low trigger is another 10% lower, I would rebuy at 8 (for simplicity).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If however I am unlucky and the price starts rising after I sold in expectance the price would drop lower, then I surely don&#39;t wanna miss out on the price increase either. So I have to, sour it is, bit the lemon, and rebuy at a higher level, say 10% too.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That means I sold at 9 and I will buy again if it drops to 8 (which is good) or rises to 11 (which is bad).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The same game I could make with 1%.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Meaning I sell at 9.9, rebuy at either 9.8 or 10.1.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You get the idea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now all those percentages, when the price changes by how much I sell, rebuy low or rebuy high:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;there&#39;s MANY possibilities.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I want to make sure my bot uses one which proposes good enough profits.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have now, started afresh 17th January, around 120k data points from Bitstamp, and around 400k data points from Binance.&lt;/div&gt;&lt;div&gt;So one simulation (eg. sell: -1%, low: -2%, high: 3%) will need to be calculated with 120k prices. Assumption, of course, is, that price development is always similar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what did I do?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I created my bot from the beginning, to be able to make simulation runs. I can feed as many simulations at once as I want. I have 3 levels, sell/low/high, I want to adjust.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My initial code looked like this for running this deep analysis was:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;s = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;0.3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;down = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;0.1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;up = &lt;span style=&quot;color: #b5cea8;&quot;&gt;0.1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;count = &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; s &amp;gt;= -&lt;span style=&quot;color: #b5cea8;&quot;&gt;4&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;    l = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; l &amp;gt;= -&lt;span style=&quot;color: #b5cea8;&quot;&gt;5&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;        h = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; h &amp;lt;= &lt;span style=&quot;color: #b5cea8;&quot;&gt;5&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;            count += &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;            h += up&lt;/div&gt;&lt;br /&gt;&lt;div&gt;        print(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;s:{}\tl:{}\th:{}&quot;&lt;/span&gt;.format(s, l, h))&lt;/div&gt;&lt;div&gt;        l += down&lt;/div&gt;&lt;div&gt;    s += down&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and the result something like this&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;h:5.099999999999998&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.1&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.2&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.3000000000000003&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.4000000000000004&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.5000000000000004&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.6000000000000005&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.7000000000000006&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.8000000000000007&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-2.900000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.000000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.100000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.200000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.300000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.4000000000000012&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.5000000000000013&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.6000000000000014&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.7000000000000015&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.8000000000000016&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-3.9000000000000017&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-4.000000000000002&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-4.100000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-4.200000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-0.3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;l:-4.300000000000001&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:5.099999999999998&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;my revised code is now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;s = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;down = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;up = &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;count = &lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; s &amp;gt;= -&lt;span style=&quot;color: #b5cea8;&quot;&gt;40&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;    l = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; l &amp;gt;= -&lt;span style=&quot;color: #b5cea8;&quot;&gt;50&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;        h = -&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;while&lt;/span&gt; h &amp;lt;= &lt;span style=&quot;color: #b5cea8;&quot;&gt;50&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;            count += &lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;            h += up&lt;/div&gt;&lt;br /&gt;&lt;div&gt;        print(&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;s:{}\tl:{}\th:{}&quot;&lt;/span&gt;.format(s, l, h))&lt;/div&gt;&lt;div&gt;        l += down&lt;/div&gt;&lt;div&gt;    s += down&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and my revised result:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-21&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-22&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-23&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-24&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-25&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-26&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-27&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-28&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-29&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-30&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-31&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-32&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-33&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-34&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-35&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-36&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-37&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-38&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-39&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-40&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-41&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-42&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;s:-3&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;l:-43&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;h:51&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So now I have values I can just divide by 10 and they are as accurate as accurate can be with floating points.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Now this piece just made sure that the loops would create all the possibilities I wanted to calculate.&lt;/div&gt;&lt;div&gt;Obviously my bot logic and the log part (file or db) is missing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;That&#39;s what I mean by decomplify your problems. Make one thing understood clearly, then add the next complexity level.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Profiling code&lt;/h1&gt;&lt;div&gt;As it turns out for &amp;gt;100k price points my simulation run 2 hours. While, for 7 million decisions to take, quite acceptable, I wanted to improve on that.&lt;div&gt;&lt;br /&gt;&lt;div&gt;Comes in cProfile&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Add this to your code:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; cProfile&lt;/div&gt;&lt;div&gt;cProfile.run(&lt;span style=&quot;color: #ce9178;&quot;&gt;&#39;main()&#39;&lt;/span&gt;)&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and it will give you a result like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;613716 function calls in 0.530 seconds&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 13px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; Ordered by: standard name&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px; min-height: 13px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; ncalls&amp;nbsp; tottime&amp;nbsp; percall&amp;nbsp; cumtime&amp;nbsp; percall filename:lineno(function)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.529&amp;nbsp; &amp;nbsp; 0.529 &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 classBitstampClient.py:18(__init__)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9999&amp;nbsp; &amp;nbsp; 0.260&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.523&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:114(logic)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; 127159&amp;nbsp; &amp;nbsp; 0.037&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.037&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:163(readyToSell)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; 391749&amp;nbsp; &amp;nbsp; 0.185&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.185&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:176(readyToBuy)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 7318&amp;nbsp; &amp;nbsp; 0.011&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.012&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:273(simulateOrder)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9999&amp;nbsp; &amp;nbsp; 0.003&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.003&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:303(getBalances)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9999&amp;nbsp; &amp;nbsp; 0.018&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.024&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:347(updateStats)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 classLogic.py:88(initLogic)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; 10027&amp;nbsp; &amp;nbsp; 0.002&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.002&amp;nbsp; &amp;nbsp; 0.000 classLogicPlayGround.py:102(logInfo)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 classLogicPlayGround.py:105(__del__)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9999&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000 classLogicPlayGround.py:108(updateHeartBeat)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 classLogicPlayGround.py:16(__init__)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 7370&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000 classLogicPlayGround.py:99(logSimulation)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.006&amp;nbsp; &amp;nbsp; 0.006&amp;nbsp; &amp;nbsp; 0.529&amp;nbsp; &amp;nbsp; 0.529 fetchAllAtOnce.py:40(main)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.530&amp;nbsp; &amp;nbsp; 0.530 {built-in method builtins.exec}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9999&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.001&amp;nbsp; &amp;nbsp; 0.000 {built-in method builtins.len}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 3&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {built-in method builtins.print}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {built-in method now}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; 10051&amp;nbsp; &amp;nbsp; 0.002&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.002&amp;nbsp; &amp;nbsp; 0.000 {method &#39;append&#39; of &#39;list&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {method &#39;commit&#39; of &#39;sqlite3.Connection&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {method &#39;disable&#39; of &#39;_lsprof.Profiler&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; 53&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {method &#39;format&#39; of &#39;str&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; 9979&amp;nbsp; &amp;nbsp; 0.003&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.003&amp;nbsp; &amp;nbsp; 0.000 {method &#39;pop&#39; of &#39;list&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000&amp;nbsp; &amp;nbsp; 0.000 {method &#39;strftime&#39; of &#39;datetime.date&#39; objects}&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Run this over a decent amount of data points, not all, Ogure out where you can improve your data, improve it, test again, see the difference and stick with the change or revert back.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I could improve with 2 little changes almost 25% performance, which is 30 minutes on a 2 hour run.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But over time, seeing which ranges totally never make sense, I can fine-tune, eliminating some trigger bands for sell/low/high and thus increase simulation time even further.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Sending messages to running code&lt;/h1&gt;&lt;div&gt;Up till now I didn&#39;t know it&#39;s possible to send a &quot;message&quot; to an already running piece of code. Okay I knew about event handlers, but not that &quot;sending signals&quot; (or messages) is possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I figured my bot is doing normally quite well, but in times of very high volatility, or very steep price increases, he gets lost and I want to stop trading during these moments.&lt;/div&gt;&lt;div&gt;So far I&#39;d have to kill the process, change the script which runs the process every hour, to not run the process. And if I wanted to start trading again I would undo those changes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now with signals it&#39;s quite easy.&lt;/div&gt;&lt;div&gt;I send a signal, I use USR1/USR2 (for stop/start trading) and intercept and change a flag in my logic.&lt;/div&gt;&lt;div&gt;I have a flag: executingTrades. I simply switch this flag and my bot stops or restarts trading.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How to send a signal?&lt;/div&gt;&lt;div&gt;Use the kill command in a shell script:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;#!/bin/zsh&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;# find the pid from the particular bot I want to stop trading&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;pid=`pgrep -f &quot;[C]ellar.*websocket_temp.py&quot;`&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;# send signal usr1&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;kill -s usr1 $pid&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;echo &quot;websocket_temp.py trading stopped&quot;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;span face=&quot;-webkit-standard&quot; style=&quot;font-size: medium;&quot;&gt;In the python code for the websocket you simply add these lines before going into .run_forever&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;span face=&quot;-webkit-standard&quot; style=&quot;font-size: medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font-family: Menlo; font-size: 11px; font-stretch: normal; line-height: normal; margin: 0px;&quot;&gt;&lt;span style=&quot;font-variant-ligatures: no-common-ligatures;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;        signal.signal(signal.SIGINT, receiveSignal)&lt;/div&gt;&lt;div&gt;        signal.signal(signal.SIGUSR1, receiveSignal)&lt;/div&gt;&lt;div&gt;        signal.signal(signal.SIGUSR2, receiveSignal)&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and the appropriate function which handles the signals&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Menlo, Monaco, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 18px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;def&lt;/span&gt; receiveSignal(signalNumber, frame):&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;global&lt;/span&gt; logic&lt;/div&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;try&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;if&lt;/span&gt; signalNumber == signal.SIGINT:&lt;/div&gt;&lt;div&gt;            ticker_ws.close()&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;elif&lt;/span&gt; signalNumber == signal.SIGUSR1:&lt;/div&gt;&lt;div&gt;            logic.simulate = &lt;span style=&quot;color: #569cd6;&quot;&gt;False&lt;/span&gt;&lt;/div&gt;&lt;div&gt;        &lt;span style=&quot;color: #569cd6;&quot;&gt;elif&lt;/span&gt; signalNumber == signal.SIGUSR2:&lt;/div&gt;&lt;div&gt;            logic.simulate = &lt;span style=&quot;color: #569cd6;&quot;&gt;True&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;    &lt;span style=&quot;color: #569cd6;&quot;&gt;except&lt;/span&gt; Exception &lt;span style=&quot;color: #569cd6;&quot;&gt;as&lt;/span&gt; e:&lt;/div&gt;&lt;div&gt;        print(e)&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tried and tested on a bot which just consumes but does not act on the messages coming from the websocket.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;    &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt; countChapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;).length chapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;) flagLevel = false var toc = &#39;&#39; for (i = 0; i &lt; countChapters; i++){ chapter = chapters[i] chapterTitle = chapters[i].textContent;   chapters[i].setAttribute(&quot;id&quot;, &quot;chapter&quot;+i); if(&#39;H2&#39; == chapter.tagName){ if(flagLevel){ toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }else{ toc += &quot;&lt;ul&gt;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; } flagLevel = true }else{ if(flagLevel){ toc += &quot;&lt;/ul&gt;&quot; flagLevel = false } toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }   // subchapter = document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].getElementsByTagName(&quot;h2&quot;).length; // alert(&quot;Chapter: &quot; + document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].textContent + &quot; has &quot; + subchapter + &quot; subchapters&quot;) } document.getElementById(&quot;myToc&quot;).innerHTML = toc;  &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/1845705104554139269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/coding.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1845705104554139269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1845705104554139269'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/coding.html' title='Coding'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-4372938102543581322</id><published>2021-01-28T16:40:00.003+01:00</published><updated>2021-01-28T20:02:22.711+01:00</updated><title type='text'>Stop Loss Trading explained</title><content type='html'>          &lt;div id=&quot;myToc&quot;&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;Other blogs about the topic&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html&quot;&gt;Main Blog about creating a trading bot&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading strategy explained&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule applications in macOS Big Sur&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With my trading bot project in NodeJS I want to prove one thing:&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: red; font-size: large;&quot;&gt;One can profit even in bearish markets&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;h1&gt;Stop Loss Trading explained&lt;/h1&gt;&lt;div&gt;&lt;div&gt;What most people involved in trading, be it crypto or stock trading, don&#39;t know: You can even in bear markets improve your position.&lt;/div&gt;&lt;div&gt;If you know, or are quite certain, your asset will one day have a high price you would want to have as much of that asset as you can, right?&lt;/div&gt;&lt;div&gt;Here&#39;s the basic logic:&lt;/div&gt;&lt;div&gt;Does the price drop? Sell after you&#39;re about 5-10% in the red. In worst case you made 5% minus. In best case the price of the asset drops further, which means you can buy in again with the money you still have.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me illustrate this.&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-NmxndbHtHvc/X_EPIuos04I/AAAAAAAAEig/wct3W6j74-8ilH2Yi6oyYE6qBGWL1m9xACPcBGAYYCw/s506/StopLossExplained.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;365&quot; data-original-width=&quot;506&quot; src=&quot;https://1.bp.blogspot.com/-NmxndbHtHvc/X_EPIuos04I/AAAAAAAAEig/wct3W6j74-8ilH2Yi6oyYE6qBGWL1m9xACPcBGAYYCw/s320/StopLossExplained.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Your asset is at 1 ($/€) and you have 100 ($/€).&lt;/div&gt;&lt;div&gt;You buy the asset, you now have 100 of it, but 0 ($/€) balance.&lt;/div&gt;&lt;div&gt;Price drops to 90 cents. Now you sell, you make a loss, you only receive 90 ($/€) back.&amp;nbsp;&lt;/div&gt;&lt;div&gt;If the price drops furtherto 80 cents, it makes a lot of sense to rebuy in. At 80 cents with 90 ($/€) you now get 112.5 assets.&lt;/div&gt;&lt;div&gt;If the price goes up to 1 ($/€) where you initially bought, you made 12.5% profit!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-88pKmgly_vM/X_EPQA9bLYI/AAAAAAAAEig/z4B-1HCiKd4HjXe9W6ftJ_u-_IBlPUmqgCPcBGAYYCw/s506/StopLossExplainedLow.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;365&quot; data-original-width=&quot;506&quot; src=&quot;https://1.bp.blogspot.com/-88pKmgly_vM/X_EPQA9bLYI/AAAAAAAAEig/z4B-1HCiKd4HjXe9W6ftJ_u-_IBlPUmqgCPcBGAYYCw/s320/StopLossExplainedLow.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Even if the price only goes back to 90 cents you&#39;ll still make a small profit.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And even if the price drops 50% from 1 ($/€) to 50 cents. It still would pay off to sell now, wait for a further drop.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-j0nR9BAQCss/X_OXDOn2rEI/AAAAAAAAEjY/cLKJHkj6Z2859b5oDyJUcHH4Gy0psaH4wCPcBGAYYCw/s506/StopLossReducesLoss.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;365&quot; data-original-width=&quot;506&quot; src=&quot;https://1.bp.blogspot.com/-j0nR9BAQCss/X_OXDOn2rEI/AAAAAAAAEjY/cLKJHkj6Z2859b5oDyJUcHH4Gy0psaH4wCPcBGAYYCw/s320/StopLossReducesLoss.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;If you can buy in again at 40 cents, and the asset will only rise to 60% thereafter, you minimised a potential (had you not sold/rebought) 40% loss to only 25% loss.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;Does the asset go up to 1$ however again, then you made AT YOUR initial price already 25% profit! As a matter of fact, would you not sell at 50 cents and just wait for a 25% profit, the asset would need to go to 1.25 ($/€). At that level IF you had sold at 50 cents and rebought at 40 cents, you&#39;d have a whopping 50% profit already!&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;              &lt;/div&gt;&lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt; countChapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;).length chapters = $(&quot;#myContents &gt; h1, #myContents &gt; h2&quot;) flagLevel = false var toc = &#39;&#39; for (i = 0; i &lt; countChapters; i++){ chapter = chapters[i] chapterTitle = chapters[i].textContent;   chapters[i].setAttribute(&quot;id&quot;, &quot;chapter&quot;+i); if(&#39;H2&#39; == chapter.tagName){ if(flagLevel){ toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }else{ toc += &quot;&lt;ul&gt;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; } flagLevel = true }else{ if(flagLevel){ toc += &quot;&lt;/ul&gt;&quot; flagLevel = false } toc += &quot;&lt;li&gt;&lt;a href=&#39;#chapter&quot;+i+&quot;&#39;&gt;&quot;+chapterTitle+&quot;&lt;/a&gt;&lt;/li&gt;&quot;; }   // subchapter = document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].getElementsByTagName(&quot;h2&quot;).length; // alert(&quot;Chapter: &quot; + document.getElementById(&quot;myContents&quot;).getElementsByTagName(&quot;h1&quot;)[i].textContent + &quot; has &quot; + subchapter + &quot; subchapters&quot;) } document.getElementById(&quot;myToc&quot;).innerHTML = toc;  &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/4372938102543581322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4372938102543581322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4372938102543581322'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html' title='Stop Loss Trading explained'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-NmxndbHtHvc/X_EPIuos04I/AAAAAAAAEig/wct3W6j74-8ilH2Yi6oyYE6qBGWL1m9xACPcBGAYYCw/s72-c/StopLossExplained.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-3422123640695192146</id><published>2021-01-01T15:41:00.071+01:00</published><updated>2021-02-03T11:54:23.675+01:00</updated><title type='text'>Trading Bot on macOS Big Sur: my experiences during the project</title><content type='html'>   &lt;div&gt;This blog is like a daily journal, I will continue to update this post about my findings during the journey. It is more about difficulties or challenges I had to deal with than about the actual code.&lt;/div&gt;&lt;div&gt;&lt;div&gt;While most content is macOS (or Unix) related, I am very confident that the shown approaches will work in a rather similar way in other environments (Windows) as well.&lt;/div&gt;&lt;div&gt;The actual code/approach how to make the trading bot itself I have explained (with docu/code in the documentation of the video)&lt;/div&gt;&lt;div&gt;here: &lt;a href=&quot;https://www.youtube.com/watch?v=l3undRJAuAU&quot;&gt;https://www.youtube.com/watch?v=l3undRJAuAU&lt;/a&gt;&lt;/div&gt;&lt;div&gt;This project is mainly based on NodeJS, there are parts I am using in Python, cause I had the code already.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Most important Tip&lt;/h1&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: red; font-size: x-large;&quot;&gt;&lt;b&gt;De-complexify problems&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Start with something you can handle and increase step by step the complexity of the task.&lt;/div&gt;&lt;div&gt;Run a script manually, before trying to schedule it, to see if the script runs at all. Run first a very simple script scheduled, before you run a complicated script, to see if you can successfully schedule a script.&lt;/div&gt;&lt;div&gt;Feed a tool first manual data, get a feeling for the data structures you need to supply (JSON, Arrays, ...). Play around, meaning, feed wrong structures to see the outcome. Only once you know what the tool expects start to feed data automatically.&lt;/div&gt;&lt;div&gt;Check the chapter about bot simulations for another tip how to &quot;de-complexify&quot; problems.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Summary&lt;/h1&gt;&lt;div&gt;So after a lot of trials and errors, fixing errors, bringing new ones in, due to being tired, I think I have finally found a version which makes me optimistic to make some profit. The simulations I run, with the triggers I chose, came 75% of the times with a profit, ranging up to more than 20% in 2 weeks.&lt;/div&gt;&lt;div&gt;My bot has higher profits in &quot;normal&quot; times, in high volatile times, like end of January where XRP soared heavily, it performed worse, but still in an acceptable area, where few humans would be able to do better without just being lucky. Once I see it performs bad, I simply send a signal to stop trading, yet I do not need to fiddle with scripts/cron etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will leave my bot now running for a few weeks to check how it performs, no interruption anymore.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Feels good, having coded a lot, having learned a lot about macOS, Unix shell scripting, Python, Signals.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have any questions, feel free to contact me at @iPinky77 on Twitter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;h1&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/stop-loss-trading-explained.html&quot; target=&quot;_blank&quot;&gt;Stop Loss Trading explained&lt;/a&gt;&lt;/h1&gt;&lt;div&gt;&lt;div&gt;&lt;h1&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#chapter0&quot; target=&quot;_blank&quot;&gt;Create a tool to visually analyse data&lt;/a&gt;&lt;/h1&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#chapter3&quot; target=&quot;_blank&quot;&gt;Intercept key presses&lt;/a&gt;&lt;/h2&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#chapter4&quot; target=&quot;_blank&quot;&gt;Adjusting my line chart&lt;/a&gt;&lt;/h2&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#chapter5&quot; target=&quot;_blank&quot;&gt;How to zoom-out of a chart&lt;/a&gt;&lt;/h2&gt;&lt;/div&gt;&lt;div&gt;&lt;h2&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/create-tool-to-visually-analyse-data.html#chapter6&quot; target=&quot;_blank&quot;&gt;Adding a slider to move between pages of data&lt;/a&gt;&lt;/h2&gt;&lt;/div&gt;&lt;/div&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html&quot; target=&quot;_blank&quot;&gt;Coding&lt;/a&gt;&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html#chapter0&quot; target=&quot;_blank&quot;&gt;Creating a responsive web server&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html#chapter1&quot; target=&quot;_blank&quot;&gt;Going back to Python&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html#chapter2&quot; target=&quot;_blank&quot;&gt;Bot simulation&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html#chapter3&quot; target=&quot;_blank&quot;&gt;Profiling code&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/coding.html#chapter4&quot; target=&quot;_blank&quot;&gt;Sending Signals to running code&lt;/a&gt;&lt;/h2&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html&quot; target=&quot;_blank&quot;&gt;Schedule programs on macOS&lt;/a&gt;&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html#chapter3&quot; target=&quot;_blank&quot;&gt;Write output immediately to log files&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html#chapter4&quot; target=&quot;_blank&quot;&gt;Simplify scheduled jobs&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/schedule-programs-on-macos.html#chapter6&quot; target=&quot;_blank&quot;&gt;Giving launchd another chance&lt;/a&gt;&lt;/h2&gt;&lt;h1&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html&quot; target=&quot;_blank&quot;&gt;Other stuff&lt;/a&gt;&lt;/h1&gt;&lt;/div&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html#chapter0&quot; target=&quot;_blank&quot;&gt;Improving blogger experience&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html#chapter1&quot; target=&quot;_blank&quot;&gt;Install web server&lt;/a&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://in-mood.blogspot.com/2021/01/other-stuff.html#chapter2&quot; target=&quot;_blank&quot;&gt;Make web server accessible from afar&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;              </content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/3422123640695192146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3422123640695192146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3422123640695192146'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/trading-bot-on-macos-big-sur.html' title='Trading Bot on macOS Big Sur: my experiences during the project'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-547481410268956089</id><published>2021-01-01T15:11:00.006+01:00</published><updated>2021-01-01T15:38:55.173+01:00</updated><title type='text'>toc test 2</title><content type='html'>    &lt;div id=&quot;myToc&quot;&gt;        &lt;h3&gt;Table of Contents&lt;/h3&gt;    &lt;/div&gt;    &lt;hr /&gt;    &lt;div id=&quot;myContents&quot;&gt;        &lt;h1&gt;Fruits&lt;/h1&gt;        more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;        &lt;h2&gt;Red Fruits&lt;/h2&gt;    &lt;p&gt;asdasds&lt;/p&gt;        &lt;h3&gt;Apple&lt;/h3&gt;        &lt;h3&gt;Raspberry&lt;/h3&gt; &lt;h4&gt;asdfasdfsad&lt;/h4&gt;    &lt;p&gt;asdasd&lt;/p&gt;        &lt;h2&gt;Orange Fruits&lt;/h2&gt;        more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;        &lt;h3&gt;Orange&lt;/h3&gt;        &lt;h3&gt;Tangerine&lt;/h3&gt;        &lt;h1&gt;Vegetables&lt;/h1&gt;        more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;        &lt;h2&gt;Vegetables Which Are Actually Fruits&lt;/h2&gt;        &lt;h3&gt;Tomato&lt;/h3&gt;        more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;        &lt;h3&gt;Eggplant&lt;/h3&gt;        more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;more text&lt;br /&gt;    &lt;/div&gt;       &lt;script&gt; window.onload = function () {    var toc = &quot;&quot;;   var level = 0;   var maxLevel = 2;    document.getElementById(&quot;myContents&quot;).innerHTML =   document.getElementById(&quot;myContents&quot;).innerHTML.replace(   /&lt;h([\d])&gt;([^&lt;]+)&lt;\/h([\d])&gt;/gi,   function (str, openLevel, titleText, closeLevel) {     if (openLevel != closeLevel) {       c.log(openLevel);       return str + &#39; - &#39; + openLevel;     }      if (openLevel &gt; level) {       toc += new Array(openLevel - level + 1).join(&quot;&lt;ul&gt;&quot;);     } else if (openLevel &lt; level) {       toc += new Array(level - openLevel + 1).join(&quot;&lt;/ul&gt;&quot;);     }      level = parseInt(openLevel);      var anchor = titleText.replace(/ /g, &quot;_&quot;);     toc += &quot;&lt;li&gt;&lt;a href=\&quot;#&quot; + anchor + &quot;\&quot;&gt;&quot; + titleText +     &quot;&lt;/a&gt;&lt;/li&gt;&quot;;      return &quot;&lt;h&quot; + openLevel + &quot;&gt;&lt;a name=\&quot;&quot; + anchor + &quot;\&quot;&gt;&quot; +     titleText + &quot;&lt;/a&gt;&lt;/h&quot; + closeLevel + &quot;&gt;&quot;;   });     if (level) {     toc += new Array(level + 1).join(&quot;&lt;/ul&gt;&quot;);   }    document.getElementById(&quot;myToc&quot;).innerHTML += toc; }; //# sourceURL=pen.js     &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/547481410268956089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2021/01/table-of-contents-fruits-more-text-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/547481410268956089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/547481410268956089'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2021/01/table-of-contents-fruits-more-text-more.html' title='toc test 2'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-5849768648567254575</id><published>2014-09-17T13:22:00.000+02:00</published><updated>2014-09-17T13:22:27.816+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Lotus Script"/><category scheme="http://www.blogger.com/atom/ns#" term="Notes Designer"/><title type='text'>QUINDIP: document your code properly in LotusScript</title><content type='html'>Hi&lt;br /&gt;&lt;br /&gt;this is not related to xPages but to LotusScript:&lt;br /&gt;&lt;br /&gt;we have started years ago to use &quot;kind-of&quot; javadoc-ish style of documentation of our code:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-QmZgua8d4xQ/VBltsVPvJCI/AAAAAAAAER4/QuImMIoi1_w/s1600/documentation.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-QmZgua8d4xQ/VBltsVPvJCI/AAAAAAAAER4/QuImMIoi1_w/s1600/documentation.jpg&quot; height=&quot;103&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;and just today i figured it actually is used using typeahead (similar as in the java editor):&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-Rhe3k94K2sw/VBltsZ4J2HI/AAAAAAAAER8/tellB_X6lMk/s1600/documentationHelp.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-Rhe3k94K2sw/VBltsZ4J2HI/AAAAAAAAER8/tellB_X6lMk/s1600/documentationHelp.jpg&quot; height=&quot;100&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;really neat ;-)&lt;br /&gt;&lt;br /&gt;enjoy</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/5849768648567254575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/09/quindip-document-your-code-properly-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5849768648567254575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5849768648567254575'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/09/quindip-document-your-code-properly-in.html' title='QUINDIP: document your code properly in LotusScript'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-QmZgua8d4xQ/VBltsVPvJCI/AAAAAAAAER4/QuImMIoi1_w/s72-c/documentation.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-3909558519944038665</id><published>2014-09-12T18:40:00.001+02:00</published><updated>2014-09-12T18:40:14.501+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="QUINDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>QUINDIP: intercept wrong/inexistent documentId</title><content type='html'>Hi&lt;br /&gt;&lt;br /&gt;long time no post... but alas.. finally something I really like:&lt;br /&gt;&lt;br /&gt;Have you ever had the situation, that you have a xPage which is workflow enabled, and you have (maybe) multiple servers? Some users might even use the LN client front-end on another server. The workflow sends out a mail telling the approver to approve.&lt;br /&gt;&lt;br /&gt;Boom... the document did not yet replicate to the target server...&lt;br /&gt;&lt;br /&gt;you do not want either of this message displayed:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-28Tn0cYDfjI/VBMblq384TI/AAAAAAAAERk/d0U0yE0OWtU/s1600/couldNotOpenDocument.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-28Tn0cYDfjI/VBMblq384TI/AAAAAAAAERk/d0U0yE0OWtU/s1600/couldNotOpenDocument.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-4sSs7n5vWQs/VBMblscrTAI/AAAAAAAAERg/td0pJ2upm5I/s1600/unableToGetdocumentPage.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-4sSs7n5vWQs/VBMblscrTAI/AAAAAAAAERg/td0pJ2upm5I/s1600/unableToGetdocumentPage.jpg&quot; height=&quot;54&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;what to do?&lt;br /&gt;&lt;br /&gt;hmm.. I first tried with &lt;a href=&quot;http://hasselba.ch/blog/?p=131&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;, sorry, was not happy with it...&lt;br /&gt;&lt;br /&gt;thing is: we use the same xpView for production and for archive, only the data source changes in the background. This will open the documents from the archive with such an URL:&lt;br /&gt;http://server/db.nsf/%24%24OpenDominoDocument.xsp?databaseName=server!!otherDb.nsf&amp;amp;documentId=6496BA354B37544CC1257C680059C04B&amp;amp;action=openDocument&lt;br /&gt;&lt;br /&gt;I could not get this to work..&lt;br /&gt;&lt;br /&gt;So I had to figure out another way to intercept a &quot;wrong&quot; documentId.&lt;br /&gt;&lt;br /&gt;Solution: use a phaselistener!!! (how to implement see &lt;a href=&quot;http://hasselba.ch/blog/?p=1243&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, kudos to Sven)&lt;br /&gt;&lt;br /&gt;Now I only need to intercept the first phase in the JSF lifecycle, test if the supplied documentId exists and redirect:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;event.getFacesContext().getExternalContext().redirect(&quot;xpDocumentNotFound.xsp&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;event.getFacesContext().responseComplete();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;I do some checks and then call redirect and responseComplete which executes immediately and does not continue with the other JSF phases &lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and the best thing: this is UNIVERSAL!!! I don&#39;t need to implement it for all xPages I use!&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/3909558519944038665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/09/quindip-intercept-wronginexistent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3909558519944038665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3909558519944038665'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/09/quindip-intercept-wronginexistent.html' title='QUINDIP: intercept wrong/inexistent documentId'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-28Tn0cYDfjI/VBMblq384TI/AAAAAAAAERk/d0U0yE0OWtU/s72-c/couldNotOpenDocument.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-8427961527089648081</id><published>2014-08-11T16:20:00.002+02:00</published><updated>2014-08-11T16:29:21.614+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Notes Designer"/><title type='text'>QUINDIP: set JAVA Compiler target in notes.ini</title><content type='html'>Literally EVERY time I created a Java agent or library the compiler target was set to 1.2 even though I have been using LN 7 or later...&lt;br /&gt;I always had to find the noteId and use a tool to manually change the source and target to 1.6.&lt;br /&gt;&lt;br /&gt;here&#39;s how you can change that behaviour:&lt;br /&gt;http://www-10.lotus.com/ldd/ddwiki.nsf/dx/07152009034956PMMSTR75.htm&lt;br /&gt;&lt;br /&gt;enjoy&lt;br /&gt;&lt;br /&gt;AND make sure you add an EMPTY at the end in case&amp;nbsp;JavaCompilerTarget=1.6 is your last line! otherwise this setting will not be used!</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/8427961527089648081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/08/quindip-set-java-compiler-target-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8427961527089648081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8427961527089648081'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/08/quindip-set-java-compiler-target-in.html' title='QUINDIP: set JAVA Compiler target in notes.ini'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-6706907986974511395</id><published>2014-06-02T22:04:00.002+02:00</published><updated>2014-06-02T22:04:42.605+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>hmmmmmm.. that does not really improve my trust in &quot;stable xPages&quot; ;-)</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-BffdUIvrNvo/U4zYub3nmNI/AAAAAAAAEQo/hdN0GQyHDGI/s1600/Error500+on+OpenNTF.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-BffdUIvrNvo/U4zYub3nmNI/AAAAAAAAEQo/hdN0GQyHDGI/s1600/Error500+on+OpenNTF.png&quot; height=&quot;114&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;seems i&#39;m really not the only one getting those!!!!</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/6706907986974511395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/06/hmmmmmm-that-does-not-really-improve-my.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/6706907986974511395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/6706907986974511395'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/06/hmmmmmm-that-does-not-really-improve-my.html' title='hmmmmmm.. that does not really improve my trust in &quot;stable xPages&quot; ;-)'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-BffdUIvrNvo/U4zYub3nmNI/AAAAAAAAEQo/hdN0GQyHDGI/s72-c/Error500+on+OpenNTF.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-8359139073284232723</id><published>2014-05-02T09:49:00.002+02:00</published><updated>2014-05-02T09:49:53.586+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Notes Designer"/><title type='text'>QUINDIP: filter design elements in LN designer</title><content type='html'>did you ever happen to notice this nice little &quot;filter&quot; field on the top right hand side of the LN designer when in a list of design elements?&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-cVhmCXZrs4o/U2NN-LeQE1I/AAAAAAAAEQI/cPzixxmL8Ak/s1600/filterDesignElements.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-cVhmCXZrs4o/U2NN-LeQE1I/AAAAAAAAEQI/cPzixxmL8Ak/s1600/filterDesignElements.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;really neat!&lt;br /&gt;&lt;br /&gt;if only I could access it via keyboard, any ideas?</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/8359139073284232723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/05/quindip-filter-design-elements-in-ln.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8359139073284232723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8359139073284232723'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/05/quindip-filter-design-elements-in-ln.html' title='QUINDIP: filter design elements in LN designer'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-cVhmCXZrs4o/U2NN-LeQE1I/AAAAAAAAEQI/cPzixxmL8Ak/s72-c/filterDesignElements.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-5277575389422012828</id><published>2014-04-11T11:29:00.001+02:00</published><updated>2014-04-11T11:29:43.298+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="QUINDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>QUINDIP: need to run an agent as signer from an xPage?</title><content type='html'>we needed a possibility for users to &quot;override&quot; the workflow, ie. interfere even though they were not &quot;authors&quot; at the moment. The only way was to do with an agent running with more access rights.&lt;br /&gt;&lt;br /&gt;solution was: us &quot;sessionAsSigner&quot;&lt;br /&gt;&lt;br /&gt;this would not work:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var agent = currentDatabase.getAgent(&quot;(agnXPageWFMoveToState60)&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;agent.runWithDocumentContext(currentDocument.getDocument() );&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return &quot;xsp-reopen&quot;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;this did work (kudos to &lt;a href=&quot;http://stackoverflow.com/questions/12512300/xpages-run-agent-as-signer&quot; target=&quot;_blank&quot;&gt;Sven Hasselbach&lt;/a&gt;):&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var agent = sessionAsSigner.getCurrentDatabase().getAgent(&quot;(agnXPageWFMoveToState60)&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;agent.runWithDocumentContext(currentDocument.getDocument() );&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return &quot;xsp-reopen&quot;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;hope this helps some people to achieve similar things</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/5277575389422012828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/04/quindip-need-to-run-agent-as-signer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5277575389422012828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/5277575389422012828'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/04/quindip-need-to-run-agent-as-signer.html' title='QUINDIP: need to run an agent as signer from an xPage?'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-1566412947652749409</id><published>2014-03-28T17:28:00.000+01:00</published><updated>2014-03-28T17:28:15.943+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="INDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>INDIP: add visual indicator to type ahead</title><content type='html'>that&#39;s how it looks:&lt;br /&gt;&lt;br /&gt;field with type ahead waiting for input: &lt;a href=&quot;http://2.bp.blogspot.com/-KnbsaRerfpU/UzWg32jmESI/AAAAAAAAEPg/PGCdn2vxw_w/s1600/type+ahead+ready+for+input.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-KnbsaRerfpU/UzWg32jmESI/AAAAAAAAEPg/PGCdn2vxw_w/s1600/type+ahead+ready+for+input.jpg&quot; /&gt;&lt;/a&gt;&lt;br /&gt;field with type ahead thinking  &lt;a href=&quot;http://3.bp.blogspot.com/-Uo08wwpCapE/UzWhBgcQWaI/AAAAAAAAEPo/p-m9Ifo0XuQ/s1600/type+ahead+thinking.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-Uo08wwpCapE/UzWhBgcQWaI/AAAAAAAAEPo/p-m9Ifo0XuQ/s1600/type+ahead+thinking.jpg&quot; /&gt;&lt;/a&gt;&lt;br /&gt;field with type ahead failure &lt;a href=&quot;http://4.bp.blogspot.com/-I9y2aW144cI/UzWhJDByR1I/AAAAAAAAEPw/bJJO0mkpiTw/s1600/type+ahead+failed.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-I9y2aW144cI/UzWhJDByR1I/AAAAAAAAEPw/bJJO0mkpiTw/s1600/type+ahead+failed.jpg&quot; /&gt;  &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;this is the XML code of the field for the events:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;xp:eventHandler event=&quot;onkeypress&quot; submit=&quot;false&quot; id=&quot;eventHandler2&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;xp:this.script&amp;gt;&amp;lt;![CDATA[if (event.keyCode==9 || event.keyCode==13){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;removeVisual(&#39;view:_id1:inputText3&#39;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}else{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;addVisual(&#39;view:_id1:inputText3&#39;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}]]&amp;gt;&amp;lt;/xp:this.script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;/xp:eventHandler&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;xp:eventHandler event=&quot;onblur&quot; submit=&quot;false&quot; id=&quot;eventHandler3&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;xp:this.script&amp;gt;&amp;lt;![CDATA[removeVisual(&#39;view:_id1:inputText3&#39;)]]&amp;gt;&amp;lt;/xp:this.script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;/xp:eventHandler&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and this is the style assigned to the field:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;xp:this.styleClass&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;![CDATA[#{javascript:if( currentDocument.isEditable()){ return &#39;useTypeAhead&#39;; }}]]&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;/xp:this.styleClass&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;this is needed in the CSS:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;.useTypeAhead{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;background: #fff url(&quot;TypeAhead.gif&quot;) no-repeat right;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;.dijitValidationContainer{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;width: 20px;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: x-small;&quot;&gt;.dijitValidationContainer .dijitValidationIcon{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;width: 20px;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: x-small;&quot;&gt;}&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;this is needed in a CSJS library (cudos to &lt;a href=&quot;http://xomino.com/2012/02/28/adding-a-working-visual-indicator-to-the-xpages-typeahead/&quot; target=&quot;_blank&quot;&gt;Mark Roden&lt;/a&gt; and&lt;a href=&quot;http://xomino.com/2012/03/20/xpages-typeahead-v2-0-with-added-fail-icon/&quot; target=&quot;_blank&quot;&gt; Sven Hasselbach&lt;/a&gt;)&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;function x$(idTag, param, jd){ //Updated 28 Feb 2012&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// hardcoded&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;idTag=idTag.replace(/:/gi, &quot;\\:&quot;)+(param ? param : &quot;&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return( jd==&quot;d&quot; ? &quot;#&quot;+idTag : $(&quot;#&quot;+idTag));&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;var inputField;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//addVisual function used to add a loading image to the screen and make it visible&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//expected input string similar to view1_:id1_:viewPanel1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;function addVisual(idTag){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var newImage=&quot;url(&#39;loading.gif&#39;)&quot; //Change me for your server&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField=dojo.query(x$(&quot;widget_&quot;+idTag, &quot; .dijitValidationIcon&quot;, &quot;d&quot;))&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;backgroundImage&quot;, newImage);&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;visibility&quot;, &quot;visible&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;backgroundRepeat&quot;, &quot;no-repeat&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;backgroundPosition&quot;, &quot;right&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;dojo.query(x$(&quot;widget_&quot;+idTag, &quot; .dijitValidationContainer&quot;, &quot;d&quot;)).style(&quot;display&quot;, &quot;block&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.attr(&quot;value&quot;,&quot;&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//--- hijack dojo XHR calls&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//Thanks to Sven Hasselbach for this ajax intercept code&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;var typeAheadLoad;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;dojo.addOnLoad( function(){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp;/*** hijacking xhr request ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp;if( !dojo._xhr )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; dojo._xhr = dojo.xhr;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp;dojo.xhr = function(){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; try{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var args = arguments[1];&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if( args[&#39;content&#39;] ){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var content = args[&#39;content&#39;];&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if( content[&#39;$$ajaxmode&#39;] ){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if( content[&#39;$$ajaxmode&#39;] == &quot;typeahead&quot; ){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*** hook in load function ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;typeAheadLoad = args[&quot;load&quot;];&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*** overwrite error function ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // &amp;nbsp; args[&quot;error&quot;] = function(){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// &amp;nbsp; &amp;nbsp; alert(&#39;Error raised!&#39;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // &amp;nbsp; };&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/*** hijack load function ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;args[&quot;load&quot;] = function(arguments){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*** On Start ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// alert(&quot;On Start!&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*** call original function ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typeAheadLoad(arguments);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /*** On Complete ***/&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp; if (arguments.toLowerCase()==&quot;&amp;lt;ul&amp;gt;&amp;lt;/ul&amp;gt;&quot;){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt; &amp;nbsp; var newImage=&quot;url(&#39;typeAheadFailure.gif&#39;)&quot; //Change me for your server&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt; &amp;nbsp; inputField.style(&quot;backgroundImage&quot;, newImage) &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp; }else{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt; &amp;nbsp; inputField.style(&quot;background&quot;, &quot;white&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;};&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; }catch(e){}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; dojo._xhr( arguments[0], arguments[1], arguments[2] );&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//removeVisual function used to remove the loading image from the screen and make it hidden&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//expected input string similar to view1_:id1_:viewPanel1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;function removeVisual(idTag){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var inputField=dojo.query(x$(&quot;widget_&quot;+idTag, &quot; .dijitValidationIcon&quot;, &quot;d&quot;))&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;backgroundImage&quot;, &quot;&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;inputField.style(&quot;visibility&quot;, &quot;hidden&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;dojo.query(x$(&quot;widget_&quot;+idTag, &quot; .dijitValidationContainer&quot;, &quot;d&quot;)).style(&quot;display&quot;, &quot;none&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;//Checks to see if the visual icon is still running - if so then assume fail and kill it&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;function checkTimer(idTag){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;dojo.query(x$(&quot;widget_&quot;+idTag, &quot; .dijitValidationContainer&quot;, &quot;d&quot;)).style(&quot;display&quot;, &quot;none&quot;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/1566412947652749409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-add-visual-indicator-to-type-ahead.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1566412947652749409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1566412947652749409'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-add-visual-indicator-to-type-ahead.html' title='INDIP: add visual indicator to type ahead'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-KnbsaRerfpU/UzWg32jmESI/AAAAAAAAEPg/PGCdn2vxw_w/s72-c/type+ahead+ready+for+input.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-7988338555563726638</id><published>2014-03-28T17:13:00.001+01:00</published><updated>2014-03-28T17:13:50.508+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="INDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>INDIP: how to figure out the id of an element which triggered an event!</title><content type='html'>here&#39;s the scenario:&lt;br /&gt;&lt;br /&gt;We have what we call dynamic tables. It lets the user add as many rows as he requires. Really neat.&lt;br /&gt;In some of the fields we use type ahead.&lt;br /&gt;&lt;br /&gt;Recently I figured: it would be nice to see an indicator if the server is &quot;thinking&quot;... something like  &lt;a href=&quot;http://3.bp.blogspot.com/-StvsQJ9CsOE/UzWfNKbyunI/AAAAAAAAEPU/Oeoa_4em9oM/s1600/loading.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-StvsQJ9CsOE/UzWfNKbyunI/AAAAAAAAEPU/Oeoa_4em9oM/s1600/loading.gif&quot; /&gt;&lt;/a&gt;&lt;br /&gt;I could do it easily via one specific field from which I knew it&#39;s id ...&lt;br /&gt;&lt;br /&gt;But in those dynamic tables I have no clue on which field the event for type ahead was triggered....&lt;br /&gt;&lt;br /&gt;until now:&lt;br /&gt;Cudos to&lt;a href=&quot;http://wpc.0b0c.edgecastcdn.net/000B0C/LUG/VUG/2011/AdminDevSessions/MainSessions/Admin2011_Calhoun_Workingwithclientside.pdf&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;Paul Calhoun with his incredibly useful tips about CSJS&lt;/a&gt; (something I usually avoid as much as I can)&lt;br /&gt;&lt;br /&gt;There I found the solution! You can call SERVER side JS from CLIENT side JS... isn&#39;t that fantastic?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;here&#39;s how:&lt;/b&gt;&lt;br /&gt;call the SSJS like this:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&quot;#{javascript:&amp;lt;ServerSide JavaScript&amp;gt;}&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;example to alert the id of an element via it&#39;s event, in this case onFocus, which was triggered:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;alert( &quot;#{javascript:BackingBean.getElementId(this)}&quot; )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;For those ones interested what the getElementId does in my Java Bean:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;UIInput input = (UIInput) handler.getParent();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: x-small;&quot;&gt;return input.getClientId(FacesContext.getCurrentInstance());&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, &#39;Times New Roman&#39;, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Of course the UIInput could be changed to something more generic like&amp;nbsp;UIComponent&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;stay tuned for my next blog which tells how I achieved proper visual indication</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/7988338555563726638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-how-to-figure-out-id-of-element.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7988338555563726638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7988338555563726638'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-how-to-figure-out-id-of-element.html' title='INDIP: how to figure out the id of an element which triggered an event!'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-StvsQJ9CsOE/UzWfNKbyunI/AAAAAAAAEPU/Oeoa_4em9oM/s72-c/loading.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-1146665480680838852</id><published>2014-03-20T14:07:00.002+01:00</published><updated>2014-03-20T14:07:59.161+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="INDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="Lotus Notes"/><title type='text'>INDIP: beware of the document.copytoDatabase method!</title><content type='html'>We had to merge two applications, so I created a background agent which copied all required documents to the &quot;new&quot; database. The customer tested and we set a due date for the real migration.&lt;br /&gt;The night before actual migration I run an agent which deleted all &quot;test&quot; migration documents before the real agent to copy the documents run again!&lt;br /&gt;&lt;br /&gt;Next morning I came to the office and thought: oh my dear. something went wrong! Only a few dozen documents had been copied, I thought!&lt;br /&gt;&lt;br /&gt;So I rerun the agent again. First all seemed to be fine. Then a few hours later documents started disappearing. With no obvious reasons.&lt;br /&gt;&lt;br /&gt;It took me about 3 hours to figure out that the method document.copyToDatabase would create the same UniversalId again!&lt;br /&gt;&lt;br /&gt;So after having deleted the first round of &quot;test&quot; documents and recopied again at due date, the universalids of the documents had been in the deletion list of the LN db already. That&#39;s why they started disappearing again after a while!&lt;br /&gt;&lt;br /&gt;So I had to delete everything again to make sure, rerun the copy agent again but this time change the universalid.&lt;br /&gt;&lt;br /&gt;Took me roughly a day to fix everything, something which normally would have taken about one hour.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/1146665480680838852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-beware-of-documentcopytodatabase.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1146665480680838852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/1146665480680838852'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/03/indip-beware-of-documentcopytodatabase.html' title='INDIP: beware of the document.copytoDatabase method!'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-4780307948568581967</id><published>2014-01-23T14:10:00.002+01:00</published><updated>2014-01-23T14:10:28.661+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Export"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>INDIP: How do you export data from an web application into Excel?</title><content type='html'>You could use POI to write an Excel file, but writing to a file with APIs is usually really slow.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: yellow;&quot;&gt;&lt;b style=&quot;background-color: black;&quot;&gt;MYYYYYYYYYYYYYYYYYY approach is blazingly faaaaaaaaaaaaaaaaaaaaast........&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In our company we are in the lucky situation that we have single-sign-on on the web towards our Domino servers. This is important for the following solution to export documents to work properly.&lt;br /&gt;&lt;br /&gt;Steps:&lt;br /&gt;1. Create some kind of &quot;profile&quot; document which defines the filters for the data the user wants to export&lt;br /&gt;2. Create an agent which processes those filters from the profile document and outputs XML for all documents&lt;br /&gt;&lt;b&gt;Example XML:&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;data xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;document&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;processeddate xs:nil=&quot;true&quot;&amp;gt;&amp;lt;/processeddate&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;wfcurrentstate&amp;gt;&amp;lt;![CDATA[70]]&amp;gt;&amp;lt;/wfcurrentstate&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;wfcurrentstatename&amp;gt;&amp;lt;![CDATA[Returned for modification]]&amp;gt;&amp;lt;/wfcurrentstatename&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;timecreated&amp;gt;2013-10-08&amp;lt;/timecreated&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;regionname&amp;gt;&amp;lt;![CDATA[SOUTH AMERICA]]&amp;gt;&amp;lt;/regionname&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;/document&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Important here is only the &quot;xs:nil&quot; attribute for &quot;empty&quot; fields, dates/numbers you can submit as is, text fields I advise to put into the &amp;lt;![CDATA[textvalue]]&amp;gt; format.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. Import the XML via the URL of the web agent (eg. http://yourserver/yourpath/youragent?openagent) file into Excel via Data Import from other sources from XML data import.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now the first time you do this you are have to go through some wizard actions done by Excel.&lt;/div&gt;&lt;div&gt;Once the XML map &amp;nbsp;has been created you can use that file over and over again (say as template). You simply need to refresh the data via the data tab in Excel.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My development &lt;b&gt;workflow &lt;/b&gt;(to get this working start slow)&lt;/div&gt;&lt;div&gt;first only export some text fields&lt;/div&gt;&lt;div&gt;then try also empty fields (with the xs:nil) attribute&lt;/div&gt;&lt;div&gt;then continue with numbers and dates to see if it works&lt;/div&gt;&lt;div&gt;call the agent directly in the browser to check if the XML is properly formatted (Google Chrome will tell you so, maybe other browers as well)&lt;/div&gt;&lt;div&gt;then import that XML into Excel, ie. use the refresh button&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I use to &quot;log&quot; the filters from the profile when the agent runs. My agent uses mostly FT Search to find the documents, only if more than 5000 are found it reverts to (if possible) view categories.&lt;/div&gt;&lt;div&gt;The &quot;constructed&quot; query is also logged. That way I can run the same query directly in the LN client to check for FT Query mistakes. As example I figured I need to put texts into double quotation marks to make queries, with filters consisting of more than one word, properly working.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The result is phantastic! I can export 5000 documents via VPN connection from my home office in about less than 30sec!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Questions? please don&#39;t hesitate to write comments&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;otherwise enjoy!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/4780307948568581967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/01/indip-how-do-you-export-data-from-web.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4780307948568581967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/4780307948568581967'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/01/indip-how-do-you-export-data-from-web.html' title='INDIP: How do you export data from an web application into Excel?'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-2805570714615739240</id><published>2014-01-16T11:25:00.002+01:00</published><updated>2014-01-16T14:27:23.365+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>QUIND: Profile documents: sort of ;-)</title><content type='html'>I&#39;m sure you also need sort of &quot;profile documents&quot; once in a while. Documents where a user can store some values he wants to use over and over again, in Web technology term thing of a &quot;cookie&quot;.&lt;br /&gt;&lt;br /&gt;This is plain easy!&lt;br /&gt;&lt;br /&gt;Simply open the xPage and as a Data source document id (red box) define a computed value like this:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-u2zbGbcgvec/UteyKr8zYbI/AAAAAAAAEOs/oGoRMMntNT8/s1600/Data+Source.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-u2zbGbcgvec/UteyKr8zYbI/AAAAAAAAEOs/oGoRMMntNT8/s1600/Data+Source.jpg&quot; height=&quot;275&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Document ID code:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;var doc:NotesDocument = database.getView(&quot;lupUserProfiles&quot;).getDocumentByKey(session.getEffectiveUserName(), true);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;if( null != doc ){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return doc.getUniversalID();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;that way the xPage will either be displayed empty (when no such &quot;profile&quot; document exists) or it will use the appropriate user profile it finds.&lt;br /&gt;&lt;br /&gt;In the QuerySave (or somewhere else) you need to make sure to save the user name and have it in the view as sorted first column of course&lt;br /&gt;&lt;br /&gt;QuerySave code:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;try{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var doc:NotesDocument = docCurrent.getDocument();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;var item:NotesItem = doc.replaceItemValue(&quot;userName&quot;, session.getEffectiveUserName())&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;item.setAuthors(true);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}catch(e){&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// handle error&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/2805570714615739240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2014/01/quind-profile-documents-sort-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/2805570714615739240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/2805570714615739240'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2014/01/quind-profile-documents-sort-of.html' title='QUIND: Profile documents: sort of ;-)'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-u2zbGbcgvec/UteyKr8zYbI/AAAAAAAAEOs/oGoRMMntNT8/s72-c/Data+Source.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-436030921715144505</id><published>2013-12-01T16:26:00.001+01:00</published><updated>2013-12-01T16:26:27.661+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Notes Designer"/><category scheme="http://www.blogger.com/atom/ns#" term="YOUFEB"/><title type='text'>YOUFEB: anyone else being mad about the copy&amp;paste (via keyboard / not working in designer?</title><content type='html'>I am getting over and over mad that copy &amp;amp; paste is not working well at all in the LN designer especially when dealing with xPages stuff..&lt;br /&gt;&lt;br /&gt;I add a template inheritance to a design element, select it, copy via &amp;lt;ctrl&amp;gt;&amp;lt;c&amp;gt; and paste it onto another design element, either I get something pasted i copied long time ago, or nothing at all.&lt;br /&gt;&lt;br /&gt;so I have to revert to right click copy and right click paste..&lt;br /&gt;&lt;br /&gt;this annoys me a lot.. is it just me or anyone else facing the same issue?</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/436030921715144505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/12/youfeb-anyone-else-being-mad-about-copy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/436030921715144505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/436030921715144505'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/12/youfeb-anyone-else-being-mad-about-copy.html' title='YOUFEB: anyone else being mad about the copy&amp;paste (via keyboard &lt;ctrl&gt;&lt;c&gt;/&lt;v&gt; not working in designer?'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-7523536036543500499</id><published>2013-11-17T22:47:00.002+01:00</published><updated>2013-11-17T22:47:57.832+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Illustrator"/><title type='text'>create golden text in Illustrator</title><content type='html'>&lt;ul&gt;&lt;li&gt;create text you want to display in color, make it big and bold&lt;/li&gt;&lt;li&gt;select the font frame and then “Object\Expand”&lt;/li&gt;&lt;li&gt;create several containers (squares) and copy color gradients from a gold bar into them, select them and use &amp;lt;i&amp;gt; to pick up a color from the gold bars and assign it to the container&lt;br /&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-wifIeAy_RXQ/Uok1dQf8diI/AAAAAAAAENA/sg9XqLIykLE/s1600/EvernoteScreenSnapz001.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://1.bp.blogspot.com/-wifIeAy_RXQ/Uok1dQf8diI/AAAAAAAAENA/sg9XqLIykLE/s320/EvernoteScreenSnapz001.png&quot; width=&quot;303&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;create a new gradient having about 8 sections and fill with those colors repeatingly&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-vCmH_MziY6M/Uok2KPbYsxI/AAAAAAAAENE/0DYi78DAtow/s1600/EvernoteScreenSnapz002.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;259&quot; src=&quot;http://4.bp.blogspot.com/-vCmH_MziY6M/Uok2KPbYsxI/AAAAAAAAENE/0DYi78DAtow/s320/EvernoteScreenSnapz002.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;br /&gt;use the eye dropper tool to pick up the color from the containers to assign to the individual sections, keep &amp;lt;shift&amp;gt; pressed while doing so, otherwise the whole gradient will be filled with the picked up color&lt;br /&gt;fill gradient&lt;br /&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-fg0liq8kXtk/Uok42iWMsjI/AAAAAAAAEN0/pOaQ46s8ytc/s1600/Adobe+Illustrator+CS6ScreenSnapz001.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-fg0liq8kXtk/Uok42iWMsjI/AAAAAAAAEN0/pOaQ46s8ytc/s1600/Adobe+Illustrator+CS6ScreenSnapz001.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;border/stroke gradient&lt;br /&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-eh1Go0HLc7g/Uok42otgtiI/AAAAAAAAEN4/Zw_eJqd3Y78/s1600/Adobe+Illustrator+CS6ScreenSnapz002.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-eh1Go0HLc7g/Uok42otgtiI/AAAAAAAAEN4/Zw_eJqd3Y78/s1600/Adobe+Illustrator+CS6ScreenSnapz002.png&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;apply the newly created gradient to text&lt;/li&gt;&lt;li&gt;use gradient tool &amp;lt;g&amp;gt; to “drag” the gradient into proper position: vertical/horizontal etc.&lt;a href=&quot;http://3.bp.blogspot.com/-IztJYsSYh_s/Uok2qoLrsII/AAAAAAAAENM/1JAI4gettds/s1600/EvernoteScreenSnapz003.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;122&quot; src=&quot;http://3.bp.blogspot.com/-IztJYsSYh_s/Uok2qoLrsII/AAAAAAAAENM/1JAI4gettds/s320/EvernoteScreenSnapz003.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-9TNFp-k7-hs/Uok3NOairKI/AAAAAAAAENY/qJHT2eGIsXg/s1600/EvernoteScreenSnapz004.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;96&quot; src=&quot;http://3.bp.blogspot.com/-9TNFp-k7-hs/Uok3NOairKI/AAAAAAAAENY/qJHT2eGIsXg/s320/EvernoteScreenSnapz004.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;assign a stroke to the text and expand (Object\Expand) only the stroke (deselect &quot;fill&quot;)&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-nRCjnReDzeI/Uok3n7n4NbI/AAAAAAAAENg/HUWnnubllLM/s1600/EvernoteScreenSnapz005.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;93&quot; src=&quot;http://4.bp.blogspot.com/-nRCjnReDzeI/Uok3n7n4NbI/AAAAAAAAENg/HUWnnubllLM/s320/EvernoteScreenSnapz005.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;ungroup all twice, such that all the “borders” can be selected and applied the gradient fill&lt;/li&gt;&lt;li&gt;select the borders (strokes) and assign a nice &quot;colored&quot; gradient, see above&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-VjY0vRDX6AM/Uok327Qa8WI/AAAAAAAAENo/oYGRoNre214/s1600/EvernoteScreenSnapz006.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;92&quot; src=&quot;http://3.bp.blogspot.com/-VjY0vRDX6AM/Uok327Qa8WI/AAAAAAAAENo/oYGRoNre214/s320/EvernoteScreenSnapz006.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;/h2&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/7523536036543500499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/11/create-golden-text.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7523536036543500499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/7523536036543500499'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/11/create-golden-text.html' title='create golden text in Illustrator'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-wifIeAy_RXQ/Uok1dQf8diI/AAAAAAAAENA/sg9XqLIykLE/s72-c/EvernoteScreenSnapz001.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-23210944270853667</id><published>2013-11-02T13:35:00.002+01:00</published><updated>2013-11-02T13:35:37.386+01:00</updated><title type='text'>Error 500: your thoughts?</title><content type='html'>Developing xPages i&#39;m sure you also have come across those nasty &quot;Error 500&quot; errors.&lt;br /&gt;&lt;br /&gt;This bugs me right now. The error.log I get won&#39;t help me at all.&lt;br /&gt;&lt;br /&gt;Any ideas how to easier figure out the problem?&lt;br /&gt;&lt;br /&gt;In my case the error.log simply states: &quot;Unable to find component with ID xyz&quot;.&lt;br /&gt;&lt;br /&gt;Interestingly: the component IS visible.&lt;br /&gt;&lt;br /&gt;I am a bit lost here: this happens in my xPage only when I copy the contents (some of them) to a new document which is then redirected to and opened in edit mode.&lt;br /&gt;If I create the new document afresh all works as it should.&lt;br /&gt;If I &quot;copy all Items&quot; to the new document then it also works fine.&lt;br /&gt;&lt;br /&gt;any ideas?</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/23210944270853667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/11/error-500-your-thoughts.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/23210944270853667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/23210944270853667'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/11/error-500-your-thoughts.html' title='Error 500: your thoughts?'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-3097441620761077600</id><published>2013-10-31T09:31:00.000+01:00</published><updated>2013-10-31T09:31:11.460+01:00</updated><title type='text'>BUG in Lotus Notes applications: saving documents with private folders (not stored on desktop) and folder references enabled</title><content type='html'>Long time no see, but stay tuned, there will be more updates again soon regarding the xPages development from my side.&lt;br /&gt;&lt;br /&gt;This week we have a very nasty bug. When people tried to save documents they got an &quot;You are not authorised to perform that operation&quot; error message.&lt;br /&gt;&lt;br /&gt;After a while fiddling around we figured: We copied&amp;amp;pasted documents we could save the newly copied documents. So where was the difference? We used TeamStudio Delta to figure out differences between the two documents. It turned out mostly just the &quot;Folder References&quot; fields.&lt;br /&gt;&lt;br /&gt;I googled and surely enough found this bug report:&amp;nbsp;&lt;a href=&quot;http://www-01.ibm.com/support/docview.wss?rs=463&amp;amp;uid=swg21099783&quot;&gt;http://www-01.ibm.com/support/docview.wss?rs=463&amp;amp;uid=swg21099783&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It basically states that users do get this error when folder references are enabled and the documents are stored in private folders which are not stored on the desktop.&lt;br /&gt;&lt;br /&gt;maybe this information helps anyone out there to not &quot;desperate&quot; if faced with a similar issue.&lt;br /&gt;&lt;br /&gt;yours&lt;br /&gt;&lt;br /&gt;Michael</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/3097441620761077600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/10/bug-in-lotus-notes-applications-saving.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3097441620761077600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/3097441620761077600'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/10/bug-in-lotus-notes-applications-saving.html' title='BUG in Lotus Notes applications: saving documents with private folders (not stored on desktop) and folder references enabled'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-2647328905440471299</id><published>2013-05-18T14:02:00.000+02:00</published><updated>2013-05-18T14:02:00.089+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>HAPPY!!! first full featured xPage application productive!</title><content type='html'>I am happy to report that our first full featured (integrated workflow, cool typeAheads, fantastic validation, dynamic tables and many more features) is fully productive!&lt;br /&gt;&lt;br /&gt;Thanks to all readers and commenters on my blog and all other bloggers out-there giving me help and insight into the deeper workings of the xPages.&lt;br /&gt;&lt;br /&gt;Summarized main difficulties:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;getting the validation to work the way we required (ie. without needing ExtensionLibrary tabbed tables, all fields should be validated, even if currently invisible and the validation should be customizable by the customer himself)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Solution was: not using validators at all, simply prevent the save with a condition on the action group in the save buttons, the condition is a &quot;result&quot; from our custom validator which sets JSF messages where appropriate&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;customized typeAheads (&lt;a href=&quot;http://in-mood.blogspot.ch/2013/01/quindip-teaser-wanna-know-how-to-make.html&quot; target=&quot;_blank&quot;&gt;see this blog&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;workflow integration (we can continue to use the LN client based code, which is important as the interface is now working on both &quot;clients&quot;, notes and web)&lt;/li&gt;&lt;li&gt;certain parts of the form stored in different documents (&lt;a href=&quot;http://in-mood.blogspot.ch/2013/04/frule-9h-to-find-ignorerequestparamstru.html?q=true&quot; target=&quot;_blank&quot;&gt;see this blog&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;dynamic tables which lets the user add new rows to tables of data&lt;/li&gt;&lt;li&gt;simple yet full featured and customizable views, using the DynamicViewPanel with different filter options per selected view, customizable (via styles) view columns&lt;/li&gt;&lt;li&gt;fancy field help (&lt;a href=&quot;http://in-mood.blogspot.ch/2013/04/quindip-solved-that-damn-dominodocument.html?q=true&quot; target=&quot;_blank&quot;&gt;see this blog&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Result:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;What we now have is a full featured framework which will help us create future xPage applications in a fraction of the time spent on this one! As a matter of fact we could create a simple form/view db with full featured workflow within one day!!!!!!!!!!!!! Most of the work actually could even be &quot;outsourced&quot; to the customer, work such as &quot;defining&quot; field help, column customizations, validations etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Best features in xPages (imho):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;CustomControls!!! &lt;/b&gt;change in one place an all&amp;nbsp;occurrences&amp;nbsp;are updated! Subforms in the old LN days were no match at all!!!&lt;/li&gt;&lt;li&gt;typeAheads&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Worst feature in xPages&lt;/b&gt; (imho):&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;error messages from server: an HTML 500 error is of no use, sometimes I needed to dissect the whole app again to find where the problem was&lt;/li&gt;&lt;li&gt;OneUI: it&#39;s a pain in the ass, but we did it, to figure out how to properly change certain GUI elements look and feel (such as typeAheads)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Recommendation:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;don&#39;t use JavaScript (or only to call backend Java code) !!!! &lt;/span&gt;debugging JavaScript is a pain in the ass where as debugging Java is so straight forward (&lt;a href=&quot;http://in-mood.blogspot.ch/2012/12/quindip-debugging-java-in-xpages-made.html?q=true&quot; target=&quot;_blank&quot;&gt;see this blog&lt;/a&gt;) and the speed of the code execution is SOOOOOOOOOOOOOOOOOOOOO freaking fast!!!&lt;/li&gt;&lt;li&gt;use where ever possible &quot;static&quot; methods so you don&#39;t need to instantiate the class, eg. our StandardUtil class has ONLY static methods such as: getKeywordValues, searchUser (for typeAhead), getSortedDocumentCollection, getEmptyDocumentCollection, hasAccess, hasRole etc.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #8e7cc3;&quot;&gt;I now need some rest. The past few weeks were mostly sleepless. Any recommendation for a nice &quot;get-well-again&quot; resort close to Switzerland are welcome ;-) ! (can be south&amp;nbsp;Germany&amp;nbsp;or&amp;nbsp;Austria&amp;nbsp;as well)&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/2647328905440471299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/05/happy-first-full-featured-xpage.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/2647328905440471299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/2647328905440471299'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/05/happy-first-full-featured-xpage.html' title='HAPPY!!! first full featured xPage application productive!'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4545464012838172159.post-8628364281867683228</id><published>2013-05-13T12:59:00.001+02:00</published><updated>2013-05-13T14:49:01.127+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="INDIP"/><category scheme="http://www.blogger.com/atom/ns#" term="XPages"/><title type='text'>INDIP: xPages isEditable() won&#39;t work on panels with READ ACL! see my workaround</title><content type='html'>If you have workflow applications then it&#39;s most likely that you wanna make certain parts of your xPage READonly for certain states (eg. such that an approver cannot change the details of the request he has to approve)&lt;br /&gt;&lt;br /&gt;In old days we used access controlled sections. xPages gives us the possibility to add ACLs to panels, that servers (almost) the same purpose.&lt;br /&gt;&lt;br /&gt;Why only almost? Cause all elements you put there to set data (buttons, links etc.) won&#39;t be hidden even if you use currentDocument.isEditable().&lt;br /&gt;&lt;br /&gt;Here&#39;s my workaround:&lt;br /&gt;&lt;br /&gt;on the Visible property of such a button etc.&lt;br /&gt;instead of just:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;currentDocument.isEditable()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;use:&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;currentDocument.isEditable() &amp;amp;&amp;amp; !&lt;span style=&quot;color: magenta;&quot;&gt;YourClass&lt;/span&gt;.hasParentReadACL(getClientId(this.getId()))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;now create a &lt;span style=&quot;color: magenta;&quot;&gt;YourClass&lt;/span&gt; (we use our StandardUtil as it contains &quot;standard&quot; methods) and add this method:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;public static boolean hasParentReadACL(String id) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;String[] components = id.split(&quot;:&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;UIComponent parent = null;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;String parentId = null;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;int i = 2;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// the || is important as repeat controls within custom controls use the same id, so we have to&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// get their parent as unique parent&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;while (null == parent || parent instanceof XspDataIterator) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;parentId = components[components.length - i++];&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;parent = JSFConnector.findComponent(parentId);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;UIViewRoot root = FacesContext.getCurrentInstance().getViewRoot();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;boolean hasACL = false;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;while (root != parent) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;if (parent instanceof UIPanelEx) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;if (null != ((UIPanelEx) parent).getAcl()) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;hasACL = true;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;break;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;parent = parent.getParent();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return hasACL;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and voila all your additional buttons etc. are hidden if one of the parent panels has an ACL!&lt;br /&gt;Of course you might change the code to really check for a READ ACL. We only use ACLs for READ so this check is at the moment superfluous.&lt;br /&gt;&lt;br /&gt;ah.. a not so minor thing: we define the StandardUtil in a SSJS library to easy reference StandardUtil, in your case you may wanna use:&lt;br /&gt;&lt;span style=&quot;color: magenta; font-family: Georgia, Times New Roman, serif; font-size: x-small;&quot;&gt;&amp;amp;&amp;amp; com.yourcompany.YourClass.hasParentReadACL()&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://in-mood.blogspot.com/feeds/8628364281867683228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://in-mood.blogspot.com/2013/05/indip-xpages-iseditable-wont-work-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8628364281867683228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4545464012838172159/posts/default/8628364281867683228'/><link rel='alternate' type='text/html' href='http://in-mood.blogspot.com/2013/05/indip-xpages-iseditable-wont-work-on.html' title='INDIP: xPages isEditable() won&#39;t work on panels with READ ACL! see my workaround'/><author><name>iPinky7</name><uri>http://www.blogger.com/profile/13920796471859274870</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid Atom 1.0" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//feeds.feedburner.com/blogspot/MeceN

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda