<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andrei Kislitsyn</title>
    <description>The latest articles on Forem by Andrei Kislitsyn (@andrei_kingsley).</description>
    <link>https://forem.com/andrei_kingsley</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1411892%2Fb8f4ff86-4e80-46ff-9fcc-016c41d9954c.png</url>
      <title>Forem: Andrei Kislitsyn</title>
      <link>https://forem.com/andrei_kingsley</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andrei_kingsley"/>
    <language>en</language>
    <item>
      <title>Plotting Financial Data in Kotlin with Kandy</title>
      <dc:creator>Andrei Kislitsyn</dc:creator>
      <pubDate>Tue, 09 Apr 2024 11:10:03 +0000</pubDate>
      <link>https://forem.com/andrei_kingsley/plotting-financial-data-in-kotlin-with-kandy-4gc3</link>
      <guid>https://forem.com/andrei_kingsley/plotting-financial-data-in-kotlin-with-kandy-4gc3</guid>
      <description>&lt;p&gt;Hi! I want to show a simple financial data workflow – download, analysis, and visualizations – using Kotlin for Data Analysis tools.&lt;/p&gt;

&lt;p&gt;This post is also available as a notebook (&lt;a href="https://gist.github.com/AndreiKingsley/ec8fd0e0cd76734c47df56c74a0d5b8e"&gt;GitHub Gist&lt;/a&gt;/&lt;a href="https://datalore.jetbrains.com/report/static/KQKedA4jDrKu63O53gEN0z/YfY7pHE1TZRzVyLNDL3pK8"&gt;Datalore&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;For working with datasets (loading and processing), I use &lt;a href="https://github.com/Kotlin/dataframe"&gt;Kotlin DataFrame&lt;/a&gt;. It is a library designed for working with structured in-memory data, such as tabular or JSON. It offers convenient storage, manipulation, and data analysis with a convenient, typesafe, readable API. With features for data initialization and operations like filtering, sorting, and integration, Kotlin DataFrame is a powerful tool for data analytics.&lt;br&gt;
I also use the &lt;a href="https://github.com/Kotlin/kandy"&gt;Kandy&lt;/a&gt; - Kotlin plotting library, designed specifically for full compatibility with Kotlin DataFrame. It brings many types of plots (including statistical) with rich customization options via a powerful Kotlin DSL.&lt;br&gt;
The best way to run all of this is &lt;a href="https://plugins.jetbrains.com/plugin/16340-kotlin-notebook"&gt;Kotlin Notebook&lt;/a&gt;. It works out of the box, has native rendering of Kandy plots and DataFrame tables, and has IntelliJ IDEA support. It can also be run in Jupyter notebooks with a &lt;a href="https://github.com/Kotlin/kotlin-jupyter"&gt;Kotlin kernel&lt;/a&gt; and on &lt;a href="https://datalore.jetbrains.com"&gt;Datalore&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Load and Info
&lt;/h3&gt;

&lt;p&gt;I downloaded the last six months of &lt;a href="https://en.wikipedia.org/wiki/Nasdaq_Composite"&gt;&lt;strong&gt;NASDAQ Composite Index (COMP)&lt;/strong&gt;&lt;/a&gt; historical data as a CSV file (available on &lt;a href="https://www.nasdaq.com/market-activity/index/comp/historical"&gt;the official website&lt;/a&gt;). This process applies to any kind of financial data related to stock, foreign exchange, or cryptocurrency markets. You can download such data from the &lt;a href="https://www.nasdaq.com"&gt;NASDAQ&lt;/a&gt;, &lt;a href="https://finance.yahoo.com"&gt;YAHOO Finance&lt;/a&gt;, or other sources. The dataset I used can be accessed &lt;a href="https://gist.github.com/AndreiKingsley/5fe289c4f694161fa557b55fcf6ab88f"&gt;here&lt;/a&gt;. Note that with a different dataset, the plots will be different.&lt;/p&gt;

&lt;p&gt;Create a dataframe with data from this file and take a look at its head:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// read CSV file into DataFrame&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dfRaw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nasdaq_comp_6m.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dfRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Close/Last&lt;/th&gt;
&lt;th&gt;Open&lt;/th&gt;
&lt;th&gt;High&lt;/th&gt;
&lt;th&gt;Low&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;03/20/2024&lt;/td&gt;
&lt;td&gt;16369.41&lt;/td&gt;
&lt;td&gt;16185.76&lt;/td&gt;
&lt;td&gt;16377.44&lt;/td&gt;
&lt;td&gt;16127.48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03/19/2024&lt;/td&gt;
&lt;td&gt;16166.79&lt;/td&gt;
&lt;td&gt;16031.93&lt;/td&gt;
&lt;td&gt;16175.59&lt;/td&gt;
&lt;td&gt;15951.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03/18/2024&lt;/td&gt;
&lt;td&gt;16103.45&lt;/td&gt;
&lt;td&gt;16154.92&lt;/td&gt;
&lt;td&gt;16247.59&lt;/td&gt;
&lt;td&gt;16094.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03/15/2024&lt;/td&gt;
&lt;td&gt;15973.17&lt;/td&gt;
&lt;td&gt;16043.58&lt;/td&gt;
&lt;td&gt;16055.33&lt;/td&gt;
&lt;td&gt;15925.91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03/14/2024&lt;/td&gt;
&lt;td&gt;16128.53&lt;/td&gt;
&lt;td&gt;16209.19&lt;/td&gt;
&lt;td&gt;16245.32&lt;/td&gt;
&lt;td&gt;16039.68&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Check out the dataset summary using the &lt;code&gt;.describe()&lt;/code&gt; method, which shows information about DataFrame columns (including their name, type, null values, and simple descriptive statistics):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;dfRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;th&gt;unique&lt;/th&gt;
&lt;th&gt;nulls&lt;/th&gt;
&lt;th&gt;top&lt;/th&gt;
&lt;th&gt;freq&lt;/th&gt;
&lt;th&gt;mean&lt;/th&gt;
&lt;th&gt;std&lt;/th&gt;
&lt;th&gt;min&lt;/th&gt;
&lt;th&gt;median&lt;/th&gt;
&lt;th&gt;max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Date&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;03/20/2024&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;01/02/2024&lt;/td&gt;
&lt;td&gt;10/02/2023&lt;/td&gt;
&lt;td&gt;12/29/2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Close/Last&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;16369.41&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14620.494&lt;/td&gt;
&lt;td&gt;1082.263&lt;/td&gt;
&lt;td&gt;12595.61&lt;/td&gt;
&lt;td&gt;14761.56&lt;/td&gt;
&lt;td&gt;16369.41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;16185.76&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14606.285&lt;/td&gt;
&lt;td&gt;1079.916&lt;/td&gt;
&lt;td&gt;12718.69&lt;/td&gt;
&lt;td&gt;14641.47&lt;/td&gt;
&lt;td&gt;16322.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;16377.44&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14691.6&lt;/td&gt;
&lt;td&gt;1073.478&lt;/td&gt;
&lt;td&gt;12772.43&lt;/td&gt;
&lt;td&gt;14846.9&lt;/td&gt;
&lt;td&gt;16449.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;16127.48&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14523.346&lt;/td&gt;
&lt;td&gt;1081.461&lt;/td&gt;
&lt;td&gt;12543.86&lt;/td&gt;
&lt;td&gt;14577.44&lt;/td&gt;
&lt;td&gt;16199.06&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, our data is a simple DataFrame of five columns: &lt;code&gt;Date&lt;/code&gt;, &lt;code&gt;Close/Last&lt;/code&gt;, &lt;code&gt;Open&lt;/code&gt;, &lt;code&gt;High&lt;/code&gt;, &lt;code&gt;Low&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each row corresponds to one trading day (note that there are no weekends); During the trading day, the price (for financial assets — stocks, currencies, etc.) or market index (in our case) changes. The values at the beginning and end of the day, as well as the minimum and maximum for the day, are used for analytics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Date&lt;/code&gt; corresponds to the date. It's in String format and should be converted to a more convenient datetime type. After that, we can sort rows by date to easily calculate metrics based on sequential data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Open&lt;/code&gt; corresponds to the opening value at the beginning of the trading day.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;High&lt;/code&gt; corresponds to the maximum value during the day.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Low&lt;/code&gt; corresponds to the minimum value during the day.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Close/Last&lt;/code&gt; corresponds to the closing value – the value at the end of the trading day. It is a commonly used benchmark used to analyze value changes over time. We'll simplify this column name to just "Close" for ease of use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also prefer to work with columns whose names are in camel case, so let's rename them.&lt;/p&gt;

&lt;p&gt;Also note that there are no nulls in the dataset, so we don't need to process them in any way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Processing
&lt;/h3&gt;

&lt;p&gt;Before we get to plotting, let's process the data a bit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert &lt;code&gt;Date&lt;/code&gt; column to &lt;code&gt;LocalDate&lt;/code&gt; type (see &lt;a href="https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#types"&gt;kotlinx.datetime types&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Sort rows by &lt;code&gt;Date&lt;/code&gt; (ascending).&lt;/li&gt;
&lt;li&gt;Rename &lt;code&gt;Close/Last&lt;/code&gt; into just &lt;code&gt;Close&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Change all column names to camel case.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://kotlin.github.io/dataframe/extensionpropertiesapi.html"&gt;autogenerated dataframe column extension properties&lt;/a&gt; inside the contexts of the transform functions are used here and further as they allow avoiding misspelling column names and add type safety.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;df&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dfRaw&lt;/span&gt;
    &lt;span class="c1"&gt;// convert `Date` column to `LocalDate` type by given pattern&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;toLocalDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MM/dd/yyyy"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// sort rows by `Date` - ascending by default&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sortBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// rename `Close/Last` into "Close"&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rename&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;`Close-Last`&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;into&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Close"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// rename columns to camel case&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;renameToCamelCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;date&lt;/th&gt;
&lt;th&gt;close&lt;/th&gt;
&lt;th&gt;open&lt;/th&gt;
&lt;th&gt;high&lt;/th&gt;
&lt;th&gt;low&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;13223.98&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-22&lt;/td&gt;
&lt;td&gt;13211.81&lt;/td&gt;
&lt;td&gt;13287.17&lt;/td&gt;
&lt;td&gt;13353.22&lt;/td&gt;
&lt;td&gt;13200.64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-25&lt;/td&gt;
&lt;td&gt;13271.32&lt;/td&gt;
&lt;td&gt;13172.54&lt;/td&gt;
&lt;td&gt;13277.83&lt;/td&gt;
&lt;td&gt;13132&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-26&lt;/td&gt;
&lt;td&gt;13063.61&lt;/td&gt;
&lt;td&gt;13180.96&lt;/td&gt;
&lt;td&gt;13199.13&lt;/td&gt;
&lt;td&gt;13033.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-27&lt;/td&gt;
&lt;td&gt;13092.85&lt;/td&gt;
&lt;td&gt;13115.36&lt;/td&gt;
&lt;td&gt;13156.37&lt;/td&gt;
&lt;td&gt;12963.16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let’s make sure we got it right:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;th&gt;unique&lt;/th&gt;
&lt;th&gt;nulls&lt;/th&gt;
&lt;th&gt;top&lt;/th&gt;
&lt;th&gt;freq&lt;/th&gt;
&lt;th&gt;mean&lt;/th&gt;
&lt;th&gt;std&lt;/th&gt;
&lt;th&gt;min&lt;/th&gt;
&lt;th&gt;median&lt;/th&gt;
&lt;th&gt;max&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;date&lt;/td&gt;
&lt;td&gt;LocalDate&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;2023-12-19&lt;/td&gt;
&lt;td&gt;2024-03-20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;close&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;13223.98&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14620.494&lt;/td&gt;
&lt;td&gt;1082.263&lt;/td&gt;
&lt;td&gt;12595.61&lt;/td&gt;
&lt;td&gt;14761.56&lt;/td&gt;
&lt;td&gt;16369.41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14606.285&lt;/td&gt;
&lt;td&gt;1079.916&lt;/td&gt;
&lt;td&gt;12718.69&lt;/td&gt;
&lt;td&gt;14641.47&lt;/td&gt;
&lt;td&gt;16322.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14691.6&lt;/td&gt;
&lt;td&gt;1073.478&lt;/td&gt;
&lt;td&gt;12772.43&lt;/td&gt;
&lt;td&gt;14846.9&lt;/td&gt;
&lt;td&gt;16449.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;125&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14523.346&lt;/td&gt;
&lt;td&gt;1081.461&lt;/td&gt;
&lt;td&gt;12543.86&lt;/td&gt;
&lt;td&gt;14577.44&lt;/td&gt;
&lt;td&gt;16199.06&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ok, let's build some plots!&lt;/p&gt;

&lt;h2&gt;
  
  
  Plots
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Closing Price Line Plot
&lt;/h3&gt;

&lt;p&gt;Let's start with something simple – looking at the changes in the index over time. As described above, the closing price signifies the final value at which a stock changes hands during the day. It is the standard reference point for investors to monitor the stock's performance across various periods. Let's visualize &lt;code&gt;close&lt;/code&gt; value changes over a given period with a line plot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// create a plot using DataFrame.plot {} extension&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// add line layer&lt;/span&gt;
    &lt;span class="nf"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// `date` corresponds to `x`&lt;/span&gt;
        &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// use extension properties again&lt;/span&gt;
        &lt;span class="c1"&gt;// `close` corresponds to `y`&lt;/span&gt;
        &lt;span class="nf"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F04dw1wq3grts1u0rbtix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F04dw1wq3grts1u0rbtix.png" alt="Closing price plot" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can clearly see the growth with minor drawdowns. However, in recent days the growth has gradually slowed, transitioning to a plateau.&lt;/p&gt;

&lt;p&gt;However, our data still isn’t very visually appealing. Let’s change that by customizing the appearance of the line (increase width and change color) and the plot layout (increase the size and add a title):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// set the line width&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
        &lt;span class="c1"&gt;// set the line color&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BLUE&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// layout parameters&lt;/span&gt;
    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// increase the plot width&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
        &lt;span class="c1"&gt;// set the plot title&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP) Closing price"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqb9sktvckfphvree8vqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqb9sktvckfphvree8vqj.png" alt="Closing price plot customized" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it looks so much better!&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing Price Moving Average
&lt;/h3&gt;

&lt;p&gt;The moving average (MA) is a standard technique that smooths a series of data points for analysis, making it easier to identify the direction of a trend. Let's count the moving average for 10 days and compare it with the MA for 1 day (in this case just &lt;code&gt;close&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// set size of window; it also can be 5 days, 20 or 40.&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;window&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="c1"&gt;// create a new dataframe with a new column with MA values&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dfWithMA10&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ma$window"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// new column builder; returning value is a value for MA for current given row.&lt;/span&gt;
    &lt;span class="c1"&gt;// if row index is less than window, return null&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// take a window (previous `window` rows incl. this one) and count their `Close` values mean&lt;/span&gt;
        &lt;span class="nf"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;(-(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;dfWithMA10&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;date&lt;/th&gt;
&lt;th&gt;close&lt;/th&gt;
&lt;th&gt;open&lt;/th&gt;
&lt;th&gt;high&lt;/th&gt;
&lt;th&gt;low&lt;/th&gt;
&lt;th&gt;ma10&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;13223.98&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-22&lt;/td&gt;
&lt;td&gt;13211.81&lt;/td&gt;
&lt;td&gt;13287.17&lt;/td&gt;
&lt;td&gt;13353.22&lt;/td&gt;
&lt;td&gt;13200.64&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-25&lt;/td&gt;
&lt;td&gt;13271.32&lt;/td&gt;
&lt;td&gt;13172.54&lt;/td&gt;
&lt;td&gt;13277.83&lt;/td&gt;
&lt;td&gt;13132&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-26&lt;/td&gt;
&lt;td&gt;13063.61&lt;/td&gt;
&lt;td&gt;13180.96&lt;/td&gt;
&lt;td&gt;13199.13&lt;/td&gt;
&lt;td&gt;13033.4&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-27&lt;/td&gt;
&lt;td&gt;13092.85&lt;/td&gt;
&lt;td&gt;13115.36&lt;/td&gt;
&lt;td&gt;13156.37&lt;/td&gt;
&lt;td&gt;12963.16&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now gather columns with &lt;code&gt;close&lt;/code&gt; (since we have daily data, &lt;code&gt;close&lt;/code&gt; contains the moving average for 1 day) and &lt;code&gt;ma10&lt;/code&gt; into one column, &lt;code&gt;movingAverage&lt;/code&gt; (with moving averages in 1-day and 10-day intervals), with a key column &lt;code&gt;interval&lt;/code&gt;. This will allow us to divide the dataset into two groups by this key and draw two lines of different colors (depending on the &lt;code&gt;interval&lt;/code&gt; value) with a legend for color. Unfortunately, at the moment, series plotting is not available in Kandy, so we can't provide several lines as we would in other plotting libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dfWithMA&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dfWithMA10&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// rename `close` into `1 day` and `ma10` into `10 days`&lt;/span&gt;
    &lt;span class="c1"&gt;// these names will be values in `interval` column after `gather`&lt;/span&gt;
    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;named&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1 day"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ma10&lt;/span&gt; &lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="s"&gt;"10 days"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;into&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"movingAverage"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dfWithMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;date&lt;/th&gt;
&lt;th&gt;open&lt;/th&gt;
&lt;th&gt;high&lt;/th&gt;
&lt;th&gt;low&lt;/th&gt;
&lt;th&gt;interval&lt;/th&gt;
&lt;th&gt;movingAverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;td&gt;13223.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;td&gt;10 days&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-22&lt;/td&gt;
&lt;td&gt;13287.17&lt;/td&gt;
&lt;td&gt;13353.22&lt;/td&gt;
&lt;td&gt;13200.64&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;td&gt;13211.81&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-22&lt;/td&gt;
&lt;td&gt;13287.17&lt;/td&gt;
&lt;td&gt;13353.22&lt;/td&gt;
&lt;td&gt;13200.64&lt;/td&gt;
&lt;td&gt;10 days&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-25&lt;/td&gt;
&lt;td&gt;13172.54&lt;/td&gt;
&lt;td&gt;13277.83&lt;/td&gt;
&lt;td&gt;13132&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;td&gt;13271.32&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now we have a column &lt;code&gt;movingAverage&lt;/code&gt; containing the value of the moving average, while the &lt;code&gt;interval&lt;/code&gt; column contains the size of the interval over which it is calculated.&lt;/p&gt;

&lt;p&gt;Let's make another line plot where we compare MA with different intervals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// group dataframe by interval&lt;/span&gt;
&lt;span class="n"&gt;dfWithMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// `movingAverage` values corresponds to `y` &lt;/span&gt;
        &lt;span class="nf"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movingAverage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
        &lt;span class="c1"&gt;// make color of line depends on `interval`&lt;/span&gt;
        &lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP) moving average"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cn7ic8ywx958cvmkyhh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cn7ic8ywx958cvmkyhh.png" alt="Moving average plot" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the trend can be seen more clearly, and all the noise has been filtered out. The window size can be varied to achieve the best result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assessment of Volatility
&lt;/h3&gt;

&lt;p&gt;Volatility is a measure of the price fluctuation of an asset on a financial market, which plays a key role in the analysis of risks and opportunities. Understanding volatility is essential for investors to determine potential risks and investment returns. Volatility aids in analyzing market instability and provides important information for portfolio management strategies, especially during periods of financial uncertainty. Let's calculate the volatility with a window of 10 days and plot it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Same as for moving average but count standard deviation instead of mean&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dfWithVolatility&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"volatility"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;(-(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;dfWithVolatility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;date&lt;/th&gt;
&lt;th&gt;close&lt;/th&gt;
&lt;th&gt;open&lt;/th&gt;
&lt;th&gt;high&lt;/th&gt;
&lt;th&gt;low&lt;/th&gt;
&lt;th&gt;volatility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-21&lt;/td&gt;
&lt;td&gt;13223.98&lt;/td&gt;
&lt;td&gt;13328.06&lt;/td&gt;
&lt;td&gt;13362.23&lt;/td&gt;
&lt;td&gt;13222.56&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-22&lt;/td&gt;
&lt;td&gt;13211.81&lt;/td&gt;
&lt;td&gt;13287.17&lt;/td&gt;
&lt;td&gt;13353.22&lt;/td&gt;
&lt;td&gt;13200.64&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-25&lt;/td&gt;
&lt;td&gt;13271.32&lt;/td&gt;
&lt;td&gt;13172.54&lt;/td&gt;
&lt;td&gt;13277.83&lt;/td&gt;
&lt;td&gt;13132&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-26&lt;/td&gt;
&lt;td&gt;13063.61&lt;/td&gt;
&lt;td&gt;13180.96&lt;/td&gt;
&lt;td&gt;13199.13&lt;/td&gt;
&lt;td&gt;13033.4&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-27&lt;/td&gt;
&lt;td&gt;13092.85&lt;/td&gt;
&lt;td&gt;13115.36&lt;/td&gt;
&lt;td&gt;13156.37&lt;/td&gt;
&lt;td&gt;12963.16&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;dfWithVolatility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nf"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volatility&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GREEN&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP) volatility (10 days)"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpvlcoc8sulc2qqz77m2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpvlcoc8sulc2qqz77m2.png" alt="Volatility Plot" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following observations can be made from the chart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distinct peaks indicate periods of increased market instability. Economic news, corporate events, or market shocks could have caused these peaks.&lt;/li&gt;
&lt;li&gt;The chart shows a trend of increasing volatility around the middle of the observed period (around December), followed by a decreasing trend.&lt;/li&gt;
&lt;li&gt;Periods with lower values suggest relative market stability at those times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can try different windows to calculate the moving average and volatility for the best result!&lt;/p&gt;

&lt;h3&gt;
  
  
  Candlestick Chart
&lt;/h3&gt;

&lt;p&gt;Candlestick charts (also known as OHLC charts) are a popular way to visualize price movements on financial markets. They consist of individual "candles", each representing a specific time period, such as a day or an hour. Each candle displays four key pieces of information: the opening value, closing value, highest value, and lowest value within the given time frame, and also indicates if the value has grown during the period.&lt;/p&gt;

&lt;p&gt;Now, let's make a candlestick!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// add a candlestick by given columns&lt;/span&gt;
    &lt;span class="nf"&gt;candlestick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuel9dxurj689tibgfsj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuel9dxurj689tibgfsj2.png" alt="Candlestick Plot Base" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see significant overplotting. Let's take only the last 50 days, reduce the candle width, and customize the layout as we did before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dfLatest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;takeLast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dfLatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// candlestick() optionally opens a new scope, where it can be configured&lt;/span&gt;
    &lt;span class="nf"&gt;candlestick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// set smaller width&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP)"&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqltvgomwzf7upshi7567.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqltvgomwzf7upshi7567.png" alt="Candlestick Plot Custom Layout" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks better and more informative!&lt;/p&gt;

&lt;p&gt;Each candle represents a daily summary, with opening and closing index values (box edges) and minimum and maximum index values (whisker ends). Its color indicates whether the value has increased or decreased at the end of the day compared to the beginning (if &lt;code&gt;close&lt;/code&gt; is greater than &lt;code&gt;open&lt;/code&gt; it's green, otherwise it’s red).&lt;/p&gt;

&lt;p&gt;We can analyze the candlesticks to draw several conclusions. For instance, until March 1, there were several greens, i.e., upward candles with large bodies, indicating stable growth. From March 1 until March 19, there is a prevalence of candles with small bodies, signaling a plateau.&lt;/p&gt;

&lt;p&gt;Let's customize candlestick a little bit, for example, change the color and increase transparency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;increaseColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#3F8EFC"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;decreaseColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#FF6A00"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dfLatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;candlestick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// change parameters of increase candles&lt;/span&gt;
        &lt;span class="nf"&gt;increase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fillColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;increaseColor&lt;/span&gt;
            &lt;span class="n"&gt;borderLine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;increaseColor&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// change parameters of decrease candles&lt;/span&gt;
        &lt;span class="nf"&gt;decrease&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fillColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;decreaseColor&lt;/span&gt;
            &lt;span class="n"&gt;borderLine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;decreaseColor&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// reduce width for all candles&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP)"&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w9f6dys2juth8v327x7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w9f6dys2juth8v327x7.png" alt="Candlestick Plot Custom Candles" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use any color palette, depending on your preferences and environment. For example, if you are using the plot in a dark theme, more contrasting colors would be appropriate.&lt;/p&gt;

&lt;p&gt;An alternative way to show an increase or decrease is to use a filled box for increase and an empty box for decrease. Let's do this by changing the &lt;code&gt;alpha&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;dfLatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;candlestick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// change alpha for increase / decrease candles through dot &lt;/span&gt;
        &lt;span class="c1"&gt;// instead of opening new scope&lt;/span&gt;
        &lt;span class="n"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
        &lt;span class="n"&gt;decrease&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;
        &lt;span class="c1"&gt;// set constant width, fill and border line colors for all candles&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
        &lt;span class="n"&gt;fillColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GREY&lt;/span&gt;
        &lt;span class="n"&gt;borderLine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GREY&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NASDAQ Composite Index (COMP)"&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7ygkx8qetdbuogfdgns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7ygkx8qetdbuogfdgns.png" alt="Candlestick Plot Filled Candles" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Daily changes distribution analysis
&lt;/h3&gt;

&lt;p&gt;Sometimes it's useful to look at the distribution of daily changes in closing prices.&lt;/p&gt;

&lt;p&gt;To do this, let's calculate them and plot a histogram.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dailyChanges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// count difference with previous `Close`; &lt;/span&gt;
    &lt;span class="c1"&gt;// `0.0` for the first row&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;diff&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// сalculate the relative change in percentage&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;100.0&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// drop the first value with a plug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// add a histogram by given sample&lt;/span&gt;
    &lt;span class="nf"&gt;histogram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dailyChanges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w5tk0i91ft1w545hgwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w5tk0i91ft1w545hgwb.png" alt="Histogram Base" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's count a sample average, use it to align bins, and add a mark line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;changesAvg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dailyChanges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;average&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;changesAvg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;0.1772034203139356&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set average as bins boundary&lt;/span&gt;
    &lt;span class="nf"&gt;histogram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dailyChanges&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binsAlign&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BinsAlign&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boundary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changesAvg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;// add a vertical line with fixed `x`&lt;/span&gt;
    &lt;span class="nf"&gt;vLine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;xIntercept&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changesAvg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// simple line setting&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RED&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
        &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LineType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DASHED&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzsc8obas241u6xuvmlp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzsc8obas241u6xuvmlp.png" alt="Histogram Custom" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can also be useful to add a density (KDE) plot here to see the distribution clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// histogram() optionally opens a new scope, where it can be configured&lt;/span&gt;
    &lt;span class="nf"&gt;histogram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dailyChanges&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binsAlign&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BinsAlign&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boundary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changesAvg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// instead of count, use empirically estimated density in this point&lt;/span&gt;
        &lt;span class="nf"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;density&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;alpha&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// add a density plot by given sample&lt;/span&gt;
    &lt;span class="nf"&gt;densityPlot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dailyChanges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;vLine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;xIntercept&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changesAvg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RED&lt;/span&gt;
        &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
        &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LineType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DASHED&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqecttpdx5xvongyxsg3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqecttpdx5xvongyxsg3.png" alt="Histogram With Density Plot" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on the chart, we can make the following conclusions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The distribution of changes resembles a normal distribution.&lt;/li&gt;
&lt;li&gt;Changes are significantly skewed to the positive side.&lt;/li&gt;
&lt;li&gt;The peak of the histogram is centered, indicating the mean of daily changes, which corresponds to the most probable value.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Throughout this article, you have learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where to find and download financial data.&lt;/li&gt;
&lt;li&gt;How to read them into a Kotlin DataFrame and perform initial processing.&lt;/li&gt;
&lt;li&gt;How to visualize this data and explore it with Kandy using various plots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading! I hope you enjoyed it and learned something new, and I was able to inspire you to experiment! I would be happy to receive feedback and answer any questions you may have.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>analytics</category>
      <category>datascience</category>
      <category>finance</category>
    </item>
  </channel>
</rss>
