<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ fintech - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ fintech - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:25:19 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/fintech/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is NFC? Near Field Communication Uses, Chips, Tags, and Readers Explained ]]>
                </title>
                <description>
                    <![CDATA[ NFC is everywhere these days. You've probably seen it in your phone settings, or heard about it online. While the use of NFC for things like contactless payments was growing steadily, it exploded early this year due to the Coronavirus pandemic. In th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-nfc-near-field-communication-uses-chips-tags-and-readers-explained/</link>
                <guid isPermaLink="false">66ac883f33a54a9b1a44793a</guid>
                
                    <category>
                        <![CDATA[ finance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fintech ]]>
                    </category>
                
                    <category>
                        <![CDATA[ payments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kristofer Koishigawa ]]>
                </dc:creator>
                <pubDate>Tue, 03 Nov 2020 18:00:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9581740569d1a4ca0d5c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>NFC is everywhere these days. You've probably seen it in your phone settings, or heard about it online.</p>
<p>While the use of NFC for things like contactless payments was growing steadily, it exploded early this year due to the Coronavirus pandemic.</p>
<p>In this article we'll go over what NFC is, what it's used for, some creative ways to use NFC, and more.</p>
<h2 id="heading-what-is-nfc-and-how-does-it-work">What is NFC and how does it work?</h2>
<p>NFC stands for near-field communication. It is a standard for devices to communicate with each other wirelessly from a very close distance.</p>
<p>NFC is a subset of another technology called RFID, so let's dig a bit into that before circling back to NFC.</p>
<h3 id="heading-what-is-rfid">What is RFID?</h3>
<p>Radio-frequency identification, or RFID, is a generic term for technologies that use radio waves from a reader to track specific tags. These tags all include an antenna and a tiny chip, and can come in many shapes and sizes. </p>
<p>Highway toll payment devices and those plastic things on clothes and other expensive items in stores are some common examples of RFID tags.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-123.png" alt="Image" width="600" height="400" loading="lazy">
<em>A diagram of an RFID tag. NFC tags look very similar – <a target="_blank" href="https://www.analogictips.com/rfid-tag-and-reader-antennas/">Source</a></em></p>
<p>If you've ever seen those big devices on either side of a store entrance, those are just big RFID readers. They're constantly transmitting radio waves and listening for a response.</p>
<p>So what happens if you try to leave a store and there's still a tag on the item you bought? </p>
<p>Most RFID tags are unpowered, so when the antenna in the tag picks up radio waves from the reader, it generates a small amount of electricity. That electricity activates the chip inside the tag, and it sends a signal with the information stored on the chip back to the reader. </p>
<p>In this case, when the reader receives a signal back from the tag on your item, it sounds an alarm.</p>
<h3 id="heading-how-are-rfid-and-nfc-related">How are RFID and NFC related?</h3>
<p>NFC is a newer, high-frequency version of RFID, and also involves both tags and readers. </p>
<p>NFC's higher frequency means that, while it can transfer data much faster than RFID, it only works from a distance of about 4 cm/1.6 in or less. Meanwhile, RFID works from a distance of up to 12 m/40 ft.</p>
<h2 id="heading-what-is-nfc-used-for">What is NFC used for?</h2>
<p>There are a lot of use cases for NFC, but here are some of the most common you'll see.</p>
<h3 id="heading-contactless-payments">Contactless payments</h3>
<p>These days, the most common thing that NFC is used for is contactless payment. Many newer credit and debit cards include an NFC tag, so you can just hold your card just above a payment terminal rather than swipe or insert it.</p>
<p>Contactless payment enabled credit and debit cards have a symbol on them similar to these:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-124.png" alt="Image" width="600" height="400" loading="lazy">
_Most contactless payment cards will have a similar symbol on the front or back – <a target="_blank" href="https://www.emvco.com/emv_insights_post/contactless-payments-how-emvco-supports-seamless-and-secure-acceptance/">Source</a>_</p>
<p>Most modern phones include an NFC chip, which can act as both an NFC reader/writer and tag. </p>
<p>This chip, paired with a mobile payment app like Google Pay, Apple Pay, and Samsung Pay, means that you might not even need to take your wallet out anymore. </p>
<p>Instead, your phone can act as a virtual NFC tag for your credit or debit card, even if said card doesn't have an actual NFC tag inside it.</p>
<p>Whether you use your contactless card or a mobile payment app, every payment you make involves tokenization for extra security.</p>
<p>Tokenization is when your card's information is used to generate a random, temporary token for each transaction. Then, your card or mobile payment app can send that temporary token safely, rather than transmit your actual card number, name, and other sensitive information.</p>
<p>However you choose to pay, using a contactless payment card, a mobile payment app, or inserting your card's chip are all <a target="_blank" href="https://www.engadget.com/2019-08-29-how-to-make-online-payments-safely-and-securely.html">much safer than the old method of swiping</a>.</p>
<h3 id="heading-interacting-with-products">Interacting with products</h3>
<p>Traditionally RFID is used for tracking inventory in warehouses and stores. But once a product leaves the store, its RFID tag is disabled.</p>
<p>A lot of products now include NFC tags for additional interaction after you leave the store. Nintendo's Amiibo figures are probably the most common recent example of this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-96.png" alt="Image" width="600" height="400" loading="lazy">
<em>If this isn't the cutest NFC tag, I don't know what is – <a target="_blank" href="https://www.nintendo.com/amiibo/detail/detective-pikachu-amiibo/">Source</a></em></p>
<p>When you scan an Amiibo figure with your Nintendo console, you can get special characters, items, or other additional content, depending on the game and figure you use.</p>
<p>Your Nintendo console can also write information back to the NFC tag in your figure, again, depending on the game and figure.</p>
<p>Other companies like Nike have been including NFC tags in things like sports jerseys and sneakers. This allows you to get personalized content based on the product you scan (recent scores for a team, stats for a specific player, and so on), or even check that a product is genuine.</p>
<h3 id="heading-data-transfer">Data transfer</h3>
<p>Unlike RFID, which is typically one-way communication between a reader and a tag, NFC allows for two-way communication.</p>
<p>Some phones are able to use NFC to transfer data like contacts or photos between two devices if you touch them together.</p>
<h2 id="heading-creative-uses-for-nfc">Creative uses for NFC</h2>
<p>One of the coolest things you can do with NFC is buy a pack of tags online and program them to do different things with your phone.</p>
<p>For example, if you're tired of always giving your WiFi password out to guests, you could program an NFC tag to automatically connect to your network. Then, all your guests need to do is make sure NFC is enabled and hold their phones near the tag.</p>
<p>You could also program NFC tags to control different smart devices around your house. You could have a tag that toggles a smart lamp on or off, or one that sets the thermostat. </p>
<p>The commands triggered by the NFC tags can also be personalized to specific devices. For example, if you like the room a bit cooler than your partner, when you scan the thermostat tag it can lower the temperature. But when your partner scans it, it could raise the temperature to their preferred setting.</p>
<p>There are a lot of other interesting ways to use NFC tags to make your life just a little bit easier. Check out this video for more ideas and to see how to program your own NFC tags in both iOS and Android:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/o9WHrX9cvXA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-in-summary">In summary</h2>
<p>Though you might not have heard much about NFC until earlier this year (I certainly hadn't), it will likely become the standard we pay for things. </p>
<p>And considering all the cool stuff you can do with a phone and a pack of NFC tags, it's surprising that NFC isn't more widely adopted.</p>
<p>If you end up programming your own NFC tags, let me know what you did and how you did it over on <a target="_blank" href="https://twitter.com/kriskoishigawa">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Crack Passwords ]]>
                </title>
                <description>
                    <![CDATA[ By Megan Kaczanowski A brief note - this article is about the theory of how to crack passwords. Understanding how cybercriminals execute attacks is extremely important for understanding how to secure systems against those types of attacks.  Attemptin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-intro-to-password-cracking/</link>
                <guid isPermaLink="false">66d46041ffe6b1f641b5fa34</guid>
                
                    <category>
                        <![CDATA[ cyber ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fintech ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ passwords ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 28 Feb 2020 05:52:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9c61740569d1a4ca31d0.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Megan Kaczanowski</p>
<p>A brief note - this article is about the theory of how to crack passwords. Understanding how cybercriminals execute attacks is extremely important for understanding how to secure systems against those types of attacks. </p>
<p>Attempting to hack a system you do not own is likely illegal in your jurisdiction (plus hacking your own systems may [and often does] violate any warranty for that product). </p>
<h2 id="heading-lets-start-with-the-basics-what-is-a-brute-force-attack">Let's start with the basics. What is a brute force attack?</h2>
<p>This type of attack involves repeatedly trying to login as a user by trying every possible letter, number, and character combination (using automated tools). </p>
<p>This can be done either online (so in real-time, by continually trying different username/password combinations on accounts like social media or banking sites) or offline (for example if you've obtained a set of hashed passwords and are trying to crack them offline). </p>
<p>Offline isn't always possible (it can be difficult to obtain a set of hashed passwords), but it is much less noisy. This is because a security team will probably notice many, many failed login accounts from the same account, but if you can crack the password offline, you won't have a record of failed login attempts.</p>
<p>This is relatively easy with a short password. It becomes exponentially more difficult with a longer password because of the sheer number of possibilities. </p>
<p>For example, if you know that someone is using a 5 character long password, composed only of lowercase letters, the total number of possible passwords is 26^5 (26 possible letters to choose from for the first letter, 26 possible choices for the second letter, etc.), or 11,881,376 possible combinations. </p>
<p>But if someone is using an 11 character password, only of lowercase letters, the total number of possible passwords is 26 ^11, or 3,670,344,486,987,776 possible passwords. </p>
<p>When you add in uppercase letters, special characters, and numbers, this gets even more difficult and time consuming to crack. The more possible passwords there are, the harder it is for someone to successfully login with a brute force attack.</p>
<h3 id="heading-how-to-protect-yourself">How to protect yourself</h3>
<p>This type of attack can be defended against in a couple of different ways. First, you can use sufficiently long, complex passwords (at least 15 characters). You can also use unique passwords for each account (use a password manager!) to reduce the danger from data breaches.</p>
<p>A security team can lock out an account after a certain number of failed login attempts. They can also force a secondary method of verification like Captcha, or use 2 factor authentication (2FA) which requires a second code (SMS or email, app-based, or hardware key based).</p>
<p><a target="_blank" href="https://null-byte.wonderhowto.com/how-to/gain-ssh-access-servers-by-brute-forcing-credentials-0194263/">Here's</a> an article on how to execute a brute force attack.</p>
<h2 id="heading-how-can-you-crack-passwords-faster">How can you crack passwords faster?</h2>
<p>A dictionary attack involves trying to repeatedly login by trying a number of combinations included in a precompiled 'dictionary', or list of combinations. </p>
<p>This is usually faster than a brute force attack because the combinations of letters and numbers have already been computed, saving you time and computing power. </p>
<p>But if the password is sufficiently complex (for example 1098324ukjbfnsdfsnej) and doesn't appear in the 'dictionary' (the precompiled list of combinations you're working from), the attack won't work. </p>
<p>It is frequently successful because, often when people choose passwords, they choose common words or variations on those words (for example, 'password' or 'p@SSword'). </p>
<p>A hacker might also use this type of attack when they know or guess a part of the password (for example, a dog's name, children's birthdays, or an anniversary - information a hacker can find on social media pages or other open source resources). </p>
<p>Similar protection measures to those described above against brute force attacks can prevent these types of attacks from being successful.</p>
<h2 id="heading-what-if-you-already-have-a-list-of-hashed-passwords">What if you already have a list of hashed passwords?</h2>
<p>Passwords are stored in the /etc/shadow file for Linux and C:\Windows\System32\config file for Windows (which are not available while the operating system is booted up). </p>
<p>If you've managed to get this file, or if you've obtained a password hash in a different way such as sniffing traffic on the network, you can try 'offline' password cracking. </p>
<p>Whereas the attacks above require trying repeatedly to login, if you have a list of hashed passwords, you can try cracking them on your machine, without setting off alerts generated by repeated failed login attempts. Then you only try logging in once, after you've successfully cracked the password (and therefore there's no failed login attempt). </p>
<p>You can use brute force attacks or dictionary attacks against the hash files, and may be successful depending on how strong the hash is.</p>
<h3 id="heading-wait-a-minute-whats-hashing">Wait a minute - what's hashing?</h3>
<p>35D4FFEF6EF231D998C6046764BB935D</p>
<p>Recognize this message? It says 'Hi my name is megan'</p>
<p>7DBDA24A2D10DAF98F23B95CFAF1D3AB</p>
<p>This one is the first paragraph of this article. Yes, it looks like nonsense, but it's actually a 'hash'. </p>
<p>A hash function allows a computer to input a string (some combination of letters, numbers, and symbols), take that string, mix it up, and output a fixed length string. That's why both strings above are of the same length, even though the strings' inputs were very different lengths. </p>
<p>Hashes can be created from nearly any digital content. Basically all digital content can be reduced to binary, or a series of 0s and 1s. Therefore, all digital content (images, documents, etc.) can be hashed. </p>
<p>There are many different hashing functions, some of which are more secure than others. The hashes above were generated with MD5 (MD stands for "Message Digest"). Different functions also differ in the length of hash they produce. </p>
<p>The same content in the same hash function will always produce the same hash. However, even a small change will alter the hash entirely. For example, </p>
<p>2FF5E24F6735B7564CAE7020B41C80F1</p>
<p>Is the hash for 'Hi my name is Megan' Just capitalizing the M in Megan completely changed the hash from above.</p>
<p>Hashes are also one-way functions (meaning they can't be reversed). This means that hashes (unique and one-way) can be used as a type of digital fingerprint for content. </p>
<h3 id="heading-whats-an-example-of-how-hashes-are-used">What's an example of how hashes are used?</h3>
<p>Hashes can be used as verification that a message hasn't been changed. </p>
<p>When you send an email, for example, you can hash the entire email and send the hash as well. Then the recipient can run the received message through the same hash function to check if the message has been tampered with in transit. If the two hashes match, the message hasn’t been altered. If they don’t match, the message has been changed. </p>
<p>Also, passwords are usually hashed when they're stored. When a user enters their password, the computer computes the hash value and compares it to the stored hash value. This way the computer doesn’t store passwords in plaintext (so some nosy hacker can't steal them!).</p>
<p>If someone is able to steal the password file, the data is useless because the function can’t be reversed (though there are ways, like rainbow tables, to figure out what plaintext creates the known hash).</p>
<h3 id="heading-whats-the-problem-with-hashes">What's the problem with hashes?</h3>
<p>If a hash can take data of any length or content, there are unlimited possibilities for data which can be hashed. </p>
<p>Since a hash converts this text into a fixed length content (for example, 32 characters), there are a finite number of combinations for a hash. It is a very very large number of possibilities, but not an infinite one.</p>
<p>Eventually two different sets of data will yield the same hash value. This is called a collision. </p>
<p>If you have one hash and you're trying to go through every single possible plaintext value to find the plaintext which matches your hash, it will be a very long, very difficult process. </p>
<h3 id="heading-however-what-if-you-dont-care-which-two-hashes-collide">However, what if you don't care which two hashes collide?</h3>
<p>This is called the '<a target="_blank" href="https://en.wikipedia.org/wiki/Birthday_problem">birthday problem</a>' in mathematics. In a class of 23 students, the likelihood of someone having a birthday on a specific day is around 7%, but the probability that any two people share the same birthday is around 50%. </p>
<p>The same type of analysis can be applied to hash functions in order to find any two hashes which match (instead of a specific hash which matches the other). </p>
<p>To avoid this, you can use longer hash functions such as SHA3, where the possibility of collisions is lower.</p>
<p>You can try generating your own hash functions for SHA3 <a target="_blank" href="https://www.browserling.com/tools/sha3-hash">here</a> and MD5 <a target="_blank" href="http://onlinemd5.com/">here</a>.  </p>
<p>You can try to brute force hashes, but it takes a very long time. The faster way to do that, is to use pre-computed <a target="_blank" href="https://www.freecodecamp.org/news/p/ee82d358-9d43-49a8-84a6-8ffca9a3ee1f/www.freecodecamp.org/news/why-a-little-salt-can-be-great-for-your-passwords">rainbow tables</a> (which are similar to dictionary attacks).</p>
<h2 id="heading-it-seems-really-easy-to-get-hacked-should-i-be-concerned">It seems really easy to get hacked. Should I be concerned?</h2>
<p>The most important thing to remember about hacking is that no one wants to do more work than they have to do. For example, brute forcing hashes can be extremely time consuming and difficult. If there's an easier way to get your password, that's probably what a nefarious actor will try first. </p>
<p>That means that enabling basic cyber security best practices is probably the easiest way to prevent getting hacked. In fact, Microsoft <a target="_blank" href="https://www.zdnet.com/article/microsoft-using-multi-factor-authentication-blocks-99-9-of-account-hacks/">recently reported</a> that just enabling 2FA will end up blocking 99.9% of automated attacks. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/Screen-Shot-2019-08-27-at-1.18.47-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://xkcd.com/538/">https://xkcd.com/538/</a></em></p>
<p><strong>Additional Reading:</strong></p>
<p><a target="_blank" href="https://resources.infosecinstitute.com/10-popular-password-cracking-tools/#gref">Popular password cracking tools</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build historical price charts with D3.js ]]>
                </title>
                <description>
                    <![CDATA[ By Wen Tjun Chan A step by step approach towards visualizing financial datasets It is a challenge to communicate data and display these visualizations on multiple devices and platforms. “Data is just like crude. It’s valuable, but if unrefined it ca... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-historical-price-charts-with-d3-js-72214aaf6ba3/</link>
                <guid isPermaLink="false">66d46171768263422736e8c8</guid>
                
                    <category>
                        <![CDATA[ data visualization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fintech ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 24 Jan 2019 17:15:18 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*4xr6-FwevPj7MIL756bDwA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Wen Tjun Chan</p>
<h4 id="heading-a-step-by-step-approach-towards-visualizing-financial-datasets">A step by step approach towards visualizing financial datasets</h4>
<p>It is a challenge to communicate data and display these visualizations on multiple devices and platforms.</p>
<blockquote>
<p>“Data is just like crude. It’s valuable, but if unrefined it cannot really be used.” - <a target="_blank" href="https://ana.blogs.com/maestros/2006/11/data_is_the_new.html">Michael Palmer</a></p>
</blockquote>
<p>D3 (Data-Driven Documents) solves this age-old dilemma. It provides developers and analysts the ability to build customized visualizations for the Web with complete freedom. D3.js allows us to bind data to the DOM (Document Object Model). Then apply data-driven transformations to create refined visualizations of data.</p>
<p>In this tutorial, we will understand how we can make the D3.js library work for us.</p>
<h4 id="heading-getting-started">Getting started</h4>
<p>We will be building a chart that illustrates the movement of a financial instrument over a period of time. This visualization resembles the price charts provided by <a target="_blank" href="https://finance.yahoo.com">Yahoo Finance</a>. We will break down the various components required to render an interactive price chart that tracks a particular <a target="_blank" href="https://sg.finance.yahoo.com/quote/VIG/chart?p=VIG">stock</a>.</p>
<p>Required components:</p>
<ol>
<li>Loading and parsing of data</li>
<li>SVG element</li>
<li>X and Y axes</li>
<li>Close price line chart</li>
<li>Simple moving average curve chart with some calculations</li>
<li>Volume series bar chart</li>
<li>Mouseover crosshair and legend</li>
</ol>
<h4 id="heading-loading-and-parsing-of-data">Loading and Parsing of Data</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> loadData = d3.json(<span class="hljs-string">'sample-data.json'</span>).then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> chartResultsData = data[<span class="hljs-string">'chart'</span>][<span class="hljs-string">'result'</span>][<span class="hljs-number">0</span>];
  <span class="hljs-keyword">const</span> quoteData = chartResultsData[<span class="hljs-string">'indicators'</span>][<span class="hljs-string">'quote'</span>][<span class="hljs-number">0</span>];
  <span class="hljs-keyword">return</span> chartResultsData[<span class="hljs-string">'timestamp'</span>].map(<span class="hljs-function">(<span class="hljs-params">time, index</span>) =&gt;</span> ({
    <span class="hljs-attr">date</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(time * <span class="hljs-number">1000</span>),
    <span class="hljs-attr">high</span>: quoteData[<span class="hljs-string">'high'</span>][index],
    <span class="hljs-attr">low</span>: quoteData[<span class="hljs-string">'low'</span>][index],
    <span class="hljs-attr">open</span>: quoteData[<span class="hljs-string">'open'</span>][index],
    <span class="hljs-attr">close</span>: quoteData[<span class="hljs-string">'close'</span>][index],
    <span class="hljs-attr">volume</span>: quoteData[<span class="hljs-string">'volume'</span>][index]
  }));
});
</code></pre>
<p>First, we will use the <a target="_blank" href="https://github.com/d3/d3-fetch">fetch</a> module to load our sample data. D3-fetch also supports other formats such as TSV and CSV files. The data will then be further processed to return an array of objects. Each object contains the trade timestamp, high price, low price, open price, close price, and trade volume.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#00151c</span>;
}
<span class="hljs-selector-id">#chart</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#0e3040</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#67809f</span>;
}
</code></pre>
<p>Add the above base CSS properties to personalize the style of your chart for maximum visual appeal.</p>
<h4 id="heading-appending-the-svg-element">Appending the SVG Element</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> initialiseChart = <span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> margin = { <span class="hljs-attr">top</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">right</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">bottom</span>: <span class="hljs-number">50</span>, <span class="hljs-attr">left</span>: <span class="hljs-number">50</span> };
  <span class="hljs-keyword">const</span> width = <span class="hljs-built_in">window</span>.innerWidth - margin.left - margin.right;
  <span class="hljs-keyword">const</span> height = <span class="hljs-built_in">window</span>.innerHeight - margin.top - margin.bottom; 
  <span class="hljs-comment">// add SVG to the page</span>
  <span class="hljs-keyword">const</span> svg = d3
    .select(<span class="hljs-string">'#chart'</span>)
    .append(<span class="hljs-string">'svg'</span>)
    .attr(<span class="hljs-string">'width'</span>, width + margin[<span class="hljs-string">'left'</span>] + margin[<span class="hljs-string">'right'</span>])
    .attr(<span class="hljs-string">'height'</span>, height + margin[<span class="hljs-string">'top'</span>] + margin[<span class="hljs-string">'bottom'</span>])
    .call(responsivefy)
    .append(<span class="hljs-string">'g'</span>)
    .attr(<span class="hljs-string">'transform'</span>, <span class="hljs-string">`translate(<span class="hljs-subst">${margin[<span class="hljs-string">'left'</span>]}</span>,  <span class="hljs-subst">${margin[<span class="hljs-string">'top'</span>]}</span>)`</span>);
</code></pre>
<p>Subsequently, we can use the <code>append()</code> method to append the SVG element to the <code>&lt;d</code>iv&gt; element with th<code>e id,</code> chart. Next, we us<code>e the</code> attr() method to assign the width and height of the SVG element. We then cal<code>l the responsi</code>vefy() method (originally writt<a target="_blank" href="https://brendansudol.com/writing/responsive-d3">en by Brendan</a> Sudol). This allows the SVG element to have responsive capabilities by listening to window resize events.</p>
<p>Remember to append the SVG group element to the above SVG element before translating it using the values from the <code>margin</code> constant.</p>
<h4 id="heading-rendering-the-x-and-y-axes">Rendering the X and Y Axes</h4>
<p>Before rendering the axes component, we will need to define our domain and range, which will then be used to create our scales for the axes</p>
<pre><code class="lang-js"><span class="hljs-comment">// find data range</span>
<span class="hljs-keyword">const</span> xMin = d3.min(data, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> d[<span class="hljs-string">'date'</span>];
});
<span class="hljs-keyword">const</span> xMax = d3.max(data, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> d[<span class="hljs-string">'date'</span>];
});
<span class="hljs-keyword">const</span> yMin = d3.min(data, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> d[<span class="hljs-string">'close'</span>];
});
<span class="hljs-keyword">const</span> yMax = d3.max(data, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> d[<span class="hljs-string">'close'</span>];
});
<span class="hljs-comment">// scales for the charts</span>
<span class="hljs-keyword">const</span> xScale = d3
  .scaleTime()
  .domain([xMin, xMax])
  .range([<span class="hljs-number">0</span>, width]);
<span class="hljs-keyword">const</span> yScale = d3
  .scaleLinear()
  .domain([yMin - <span class="hljs-number">5</span>, yMax])
  .range([height, <span class="hljs-number">0</span>]);
</code></pre>
<p>The x and y axes for the close price line chart consist of the trade date and close price respectively. Therefore, we have to define the minimum and maximum x and y values, using <code>d3.max()</code> and <code>d3.min()</code>. We can then make use of <a target="_blank" href="https://github.com/d3/d3-scale">D3-scale</a>’s <code>scaleTime()</code> and <code>scaleLinear()</code> to create the time scale on the x-axis and the linear scale on the y-axis respectively. The range of the scales is defined by the width and height of our SVG element.</p>
<pre><code class="lang-js"><span class="hljs-comment">// create the axes component</span>
svg
  .append(<span class="hljs-string">'g'</span>)
  .attr(<span class="hljs-string">'id'</span>, <span class="hljs-string">'xAxis'</span>)
  .attr(<span class="hljs-string">'transform'</span>, <span class="hljs-string">`translate(0, <span class="hljs-subst">${height}</span>)`</span>)
  .call(d3.axisBottom(xScale));
svg
  .append(<span class="hljs-string">'g'</span>)
  .attr(<span class="hljs-string">'id'</span>, <span class="hljs-string">'yAxis'</span>)
  .attr(<span class="hljs-string">'transform'</span>, <span class="hljs-string">`translate(<span class="hljs-subst">${width}</span>, 0)`</span>)
  .call(d3.axisRight(yScale));
</code></pre>
<p>After this step, we need to append the first <code>g</code> element to the SVG element, which calls the <code>d3.axisBottom()</code> method, taking in <code>xScale</code> as the parameter to generate the x-axis. The x-axis is then translated to the bottom of the chart area. Similarly, the y-axis is generated by appending the <code>g</code> element, calling d3.axisRight() with <code>yScale</code> as the parameter, before translating the y-axis to the right of the chart area.</p>
<h4 id="heading-rendering-the-close-price-line-chart">Rendering the Close Price Line Chart</h4>
<pre><code><span class="hljs-comment">// generates close price line chart when called</span>
<span class="hljs-keyword">const</span> line = d3
  .line()
  .x(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> xScale(d[<span class="hljs-string">'date'</span>]);
  })
  .y(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> yScale(d[<span class="hljs-string">'close'</span>]);
  });
<span class="hljs-comment">// Append the path and bind data</span>
svg
 .append(<span class="hljs-string">'path'</span>)
 .data([data])
 .style(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'none'</span>)
 .attr(<span class="hljs-string">'id'</span>, <span class="hljs-string">'priceChart'</span>)
 .attr(<span class="hljs-string">'stroke'</span>, <span class="hljs-string">'steelblue'</span>)
 .attr(<span class="hljs-string">'stroke-width'</span>, <span class="hljs-string">'1.5'</span>)
 .attr(<span class="hljs-string">'d'</span>, line);
</code></pre><p>Now, we can append the <code>[path](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths)</code> element inside our main SVG element, followed by passing our parsed dataset,<code>data</code>. We set the attribute <code>d</code> with our helper function, <code>line</code>. which calls the <code>d3.line()</code> method. The <code>x</code> and <code>y</code> attributes of the line accept the anonymous functions and return the date and close price respectively.</p>
<p>By now, this is how your chart should look like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/fnbftLMqi8MQnIy8ZZBrqsKN8fXYVfodvgQ2" alt="Image" width="800" height="407" loading="lazy">
<em>Checkpoint #1: Close price line chart, with the X and Y Axes.</em></p>
<h4 id="heading-rendering-the-simple-moving-average-curve">Rendering the Simple Moving Average Curve</h4>
<p>Instead of relying purely on the close price as our only form of technical indicator, we use the <a target="_blank" href="https://www.investopedia.com/terms/s/sma.asp">Simple Moving Average</a>. This average identifies uptrends and downtrends for the particular security.</p>
<pre><code><span class="hljs-keyword">const</span> movingAverage = <span class="hljs-function">(<span class="hljs-params">data, numberOfPricePoints</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> data.map(<span class="hljs-function">(<span class="hljs-params">row, index, total</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> start = <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, index - numberOfPricePoints);
    <span class="hljs-keyword">const</span> end = index;
    <span class="hljs-keyword">const</span> subset = total.slice(start, end + <span class="hljs-number">1</span>);
    <span class="hljs-keyword">const</span> sum = subset.reduce(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> a + b[<span class="hljs-string">'close'</span>];
    }, <span class="hljs-number">0</span>);
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">date</span>: row[<span class="hljs-string">'date'</span>],
      <span class="hljs-attr">average</span>: sum / subset.length
    };
  });
};
</code></pre><p>We define our helper function, <code>movingAverage</code> to calculate the simple moving average. This function accepts two parameters, namely the dataset, and the number of price points, or periods. It then returns an array of objects, with each object containing the date and average for each data point.</p>
<pre><code class="lang-js"><span class="hljs-comment">// calculates simple moving average over 50 days</span>
<span class="hljs-keyword">const</span> movingAverageData = movingAverage(data, <span class="hljs-number">49</span>);
<span class="hljs-comment">// generates moving average curve when called</span>
<span class="hljs-keyword">const</span> movingAverageLine = d3
 .line()
 .x(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> xScale(d[<span class="hljs-string">'date'</span>]);
 })
 .y(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> yScale(d[<span class="hljs-string">'average'</span>]);
 })
  .curve(d3.curveBasis);
svg
  .append(<span class="hljs-string">'path'</span>)
  .data([movingAverageData])
  .style(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'none'</span>)
  .attr(<span class="hljs-string">'id'</span>, <span class="hljs-string">'movingAverageLine'</span>)
  .attr(<span class="hljs-string">'stroke'</span>, <span class="hljs-string">'#FF8900'</span>)
  .attr(<span class="hljs-string">'d'</span>, movingAverageLine);
</code></pre>
<p>For our current context, <code>movingAverage()</code> calculates the simple moving average over a period of 50 days. Similar to the close price line chart, we append the <code>path</code> element within our main SVG element, followed by passing our moving average dataset, and setting the attribute <code>d</code> with our helper function, <code>movingAverageLine</code>. The only difference from the above is that we passed <code>d3.curveBasis</code> to <code>d3.line().curve()</code> in order to achieve a curve.</p>
<p>This results in the simple moving average curve overlaid on top of our current chart:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XhcAf6lV84KJ5fOpcZ6reXZ4ovtPqA9Y07dM" alt="Image" width="800" height="412" loading="lazy">
<em>Checkpoint #2: Orange curve, which depicts the simple moving average. This gives us a better idea of the price movement.</em></p>
<h4 id="heading-rendering-the-volume-series-bar-chart">Rendering the Volume Series Bar Chart</h4>
<p>For this component, we will be rendering the trade <a target="_blank" href="https://commodity.com/technical-analysis/volume/">volume</a> in the form of a color-coded bar chart occupying the same SVG element. The bars are green when the stock closes higher than the previous day’s close price. They are red when the stock closes lower than the previous day’s close price. This illustrates the volume traded for each trade date. This can then be used alongside the above chart to analyze price movements.</p>
<pre><code class="lang-js"><span class="hljs-comment">/* Volume series bars */</span>
<span class="hljs-keyword">const</span> volData = data.filter(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> d[<span class="hljs-string">'volume'</span>] !== <span class="hljs-literal">null</span> &amp;&amp; d[<span class="hljs-string">'volume'</span>]   !== <span class="hljs-number">0</span>);
<span class="hljs-keyword">const</span> yMinVolume = d3.min(volData, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.min(d[<span class="hljs-string">'volume'</span>]);
});
<span class="hljs-keyword">const</span> yMaxVolume = d3.max(volData, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.max(d[<span class="hljs-string">'volume'</span>]);
});
<span class="hljs-keyword">const</span> yVolumeScale = d3
  .scaleLinear()
  .domain([yMinVolume, yMaxVolume])
  .range([height, <span class="hljs-number">0</span>]);
</code></pre>
<p>The x and y axes for the volume series bar chart consist of the trade date and volume respectively. Thus, we will need to redefine the minimum and maximum y values and make use of <code>scaleLinear()</code>on the y-axis. The range of these scales are defined by the width and height of our SVG element. We will be reusing <code>xScale</code> since the x-axis of the bar chart corresponds similarly to the trade date.</p>
<pre><code class="lang-js">svg
  .selectAll()
  .data(volData)
  .enter()
  .append(<span class="hljs-string">'rect'</span>)
  .attr(<span class="hljs-string">'x'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> xScale(d[<span class="hljs-string">'date'</span>]);
  })
  .attr(<span class="hljs-string">'y'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> yVolumeScale(d[<span class="hljs-string">'volume'</span>]);
  })
  .attr(<span class="hljs-string">'fill'</span>, <span class="hljs-function">(<span class="hljs-params">d, i</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (i === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-string">'#03a678'</span>;
    } <span class="hljs-keyword">else</span> {  
      <span class="hljs-keyword">return</span> volData[i - <span class="hljs-number">1</span>].close &gt; d.close ? <span class="hljs-string">'#c0392b'</span> : <span class="hljs-string">'#03a678'</span>; 
    }
  })
  .attr(<span class="hljs-string">'width'</span>, <span class="hljs-number">1</span>)
  .attr(<span class="hljs-string">'height'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> height - yVolumeScale(d[<span class="hljs-string">'volume'</span>]);
  });
</code></pre>
<p>This section relies on your understanding of how the<code>selectAll()</code> method works with the <code>enter()</code> and <code>append()</code> methods. You may wish to read <a target="_blank" href="https://bost.ocks.org/mike/join/">this</a> (written by <a target="_blank" href="https://bost.ocks.org/mike/">Mike Bostock</a> himself) if you are unfamiliar with those methods. This may be important as those methods are used as part of the <a target="_blank" href="https://bost.ocks.org/mike/join/">enter-update-exit</a> pattern, which I may cover in a subsequent tutorial.</p>
<p>To render the bars, we will first use <code>.selectAll()</code> to return an empty selection, or an empty array. Next, we pass <code>volData</code> to define the height of each bar. The <code>enter()</code> method compares the <code>volData</code> dataset with the selection from <code>selectAll()</code>, which is currently empty. Currently, the DOM does not contain any <code>&lt;re</code>ct&gt; element. Thus<code>, the ap</code>pend() method accepts an arg<code>ument</code> ‘rect’, which creates <code>a new</code>  element in the DOM for every singl<code>e objec</code>t in volData.</p>
<p>Here is a breakdown of the attributes of the bars. We will be using the following attributes: <code>x</code>, <code>y</code>, <code>fill</code>, <code>width</code>, and <code>height</code>.</p>
<pre><code>.attr(<span class="hljs-string">'x'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> xScale(d[<span class="hljs-string">'date'</span>]);
})
.attr(<span class="hljs-string">'y'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> yVolumeScale(d[<span class="hljs-string">'volume'</span>]);
})
</code></pre><p>The first <code>attr()</code> method defines the x-coordinate. It accepts an anonymous function which returns the date. Similarly, the second <code>attr()</code> method defines the y-coordinate. It accepts an anonymous function which returns the volume. These will define the position of each bar.</p>
<pre><code>.attr(<span class="hljs-string">'width'</span>, <span class="hljs-number">1</span>)
.attr(<span class="hljs-string">'height'</span>, <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> height - yVolumeScale(d[<span class="hljs-string">'volume'</span>]);
});
</code></pre><p>We assign a width of 1 pixel to each bar. To make the bar stretch from the top (defined by <code>y</code>)to the x-axis, simply deduct the height with the <code>y</code> value.</p>
<pre><code>.attr(<span class="hljs-string">'fill'</span>, <span class="hljs-function">(<span class="hljs-params">d, i</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (i === <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'#03a678'</span>;
  } <span class="hljs-keyword">else</span> {  
    <span class="hljs-keyword">return</span> volData[i - <span class="hljs-number">1</span>].close &gt; d.close ? <span class="hljs-string">'#c0392b'</span> : <span class="hljs-string">'#03a678'</span>; 
  }
})
</code></pre><p>Remember the way that the bars will be color coded? We will be using the <code>fill</code> attribute to define the colors of each bar. For stocks that closed higher than the previous day’s close price, the bar will be green in color. Otherwise, the bar will be red.</p>
<p>This is how your current chart should look like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/f3q6i4i1wTbBzHe4TXuLTR3Blcg4YbOYUsCW" alt="Image" width="800" height="403" loading="lazy">
<em>Checkpoint #3: Volume series chart, represented by red and green bars.</em></p>
<h4 id="heading-rendering-crosshair-and-legend-for-interactivity">Rendering Crosshair and Legend for interactivity</h4>
<p>We have reached the final step of this tutorial, whereby we will generate a mouseover crosshair that displays drop lines. Mousing over the various points in the chart will cause the legends to be updated. This provides us the full information (open price, close price, high price, low price, and volume) for each trade date.</p>
<p>The following section is referenced from <a target="_blank" href="https://bl.ocks.org/micahstubbs/e4f5c830c264d26621b80b754219ae1b">Micah Stubb’s excellent example</a>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// renders x and y crosshair</span>
<span class="hljs-keyword">const</span> focus = svg
  .append(<span class="hljs-string">'g'</span>)
  .attr(<span class="hljs-string">'class'</span>, <span class="hljs-string">'focus'</span>)
  .style(<span class="hljs-string">'display'</span>, <span class="hljs-string">'none'</span>);
focus.append(<span class="hljs-string">'circle'</span>).attr(<span class="hljs-string">'r'</span>, <span class="hljs-number">4.5</span>);
focus.append(<span class="hljs-string">'line'</span>).classed(<span class="hljs-string">'x'</span>, <span class="hljs-literal">true</span>);
focus.append(<span class="hljs-string">'line'</span>).classed(<span class="hljs-string">'y'</span>, <span class="hljs-literal">true</span>);
svg
  .append(<span class="hljs-string">'rect'</span>)
  .attr(<span class="hljs-string">'class'</span>, <span class="hljs-string">'overlay'</span>)
  .attr(<span class="hljs-string">'width'</span>, width)
  .attr(<span class="hljs-string">'height'</span>, height)
  .on(<span class="hljs-string">'mouseover'</span>, <span class="hljs-function">() =&gt;</span> focus.style(<span class="hljs-string">'display'</span>, <span class="hljs-literal">null</span>))
  .on(<span class="hljs-string">'mouseout'</span>, <span class="hljs-function">() =&gt;</span> focus.style(<span class="hljs-string">'display'</span>, <span class="hljs-string">'none'</span>))
  .on(<span class="hljs-string">'mousemove'</span>, generateCrosshair);
d3.select(<span class="hljs-string">'.overlay'</span>).style(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'none'</span>);
d3.select(<span class="hljs-string">'.overlay'</span>).style(<span class="hljs-string">'pointer-events'</span>, <span class="hljs-string">'all'</span>);
d3.selectAll(<span class="hljs-string">'.focus line'</span>).style(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'none'</span>);
d3.selectAll(<span class="hljs-string">'.focus line'</span>).style(<span class="hljs-string">'stroke'</span>, <span class="hljs-string">'#67809f'</span>);
d3.selectAll(<span class="hljs-string">'.focus line'</span>).style(<span class="hljs-string">'stroke-width'</span>, <span class="hljs-string">'1.5px'</span>);
d3.selectAll(<span class="hljs-string">'.focus line'</span>).style(<span class="hljs-string">'stroke-dasharray'</span>, <span class="hljs-string">'3 3'</span>);
</code></pre>
<p>The crosshair consists of a translucent circle with drop lines consisting of dashes. The above code block provides the styling of the individual elements. Upon mouseover, it will generate the crosshair based on the function below.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bisectDate = d3.bisector(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> d.date).left;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateCrosshair</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">//returns corresponding value from the domain</span>
  <span class="hljs-keyword">const</span> correspondingDate = xScale.invert(d3.mouse(<span class="hljs-built_in">this</span>)[<span class="hljs-number">0</span>]);
  <span class="hljs-comment">//gets insertion point</span>
  <span class="hljs-keyword">const</span> i = bisectDate(data, correspondingDate, <span class="hljs-number">1</span>);
  <span class="hljs-keyword">const</span> d0 = data[i - <span class="hljs-number">1</span>];
  <span class="hljs-keyword">const</span> d1 = data[i];
  <span class="hljs-keyword">const</span> currentPoint = correspondingDate - d0[<span class="hljs-string">'date'</span>] &gt; d1[<span class="hljs-string">'date'</span>] - correspondingDate ? d1 : d0;

  focus.attr(<span class="hljs-string">'transform'</span>,<span class="hljs-string">`translate(<span class="hljs-subst">${xScale(currentPoint[<span class="hljs-string">'date'</span>])}</span>,     <span class="hljs-subst">${yScale(currentPoint[<span class="hljs-string">'close'</span>])}</span>)`</span>);
focus
  .select(<span class="hljs-string">'line.x'</span>)
  .attr(<span class="hljs-string">'x1'</span>, <span class="hljs-number">0</span>)
  .attr(<span class="hljs-string">'x2'</span>, width - xScale(currentPoint[<span class="hljs-string">'date'</span>]))
  .attr(<span class="hljs-string">'y1'</span>, <span class="hljs-number">0</span>)
  .attr(<span class="hljs-string">'y2'</span>, <span class="hljs-number">0</span>);
focus
  .select(<span class="hljs-string">'line.y'</span>)
  .attr(<span class="hljs-string">'x1'</span>, <span class="hljs-number">0</span>)
  .attr(<span class="hljs-string">'x2'</span>, <span class="hljs-number">0</span>)
  .attr(<span class="hljs-string">'y1'</span>, <span class="hljs-number">0</span>)
  .attr(<span class="hljs-string">'y2'</span>, height - yScale(currentPoint[<span class="hljs-string">'close'</span>]));
 updateLegends(currentPoint);
}
</code></pre>
<p>We can then make use of the <a target="_blank" href="https://github.com/d3/d3-array#bisect">d3.bisector()</a> method to locate the insertion point, which will highlight the closest data point on the close price line graph. After determining the <code>currentPoint</code>, the drop lines will be updated. The <code>updateLegends()</code> method uses the <code>currentPoint</code> as the parameter.</p>
<pre><code><span class="hljs-keyword">const</span> updateLegends = <span class="hljs-function"><span class="hljs-params">currentData</span> =&gt;</span> {  d3.selectAll(<span class="hljs-string">'.lineLegend'</span>).remove();
</code></pre><pre><code><span class="hljs-keyword">const</span> updateLegends = <span class="hljs-function"><span class="hljs-params">currentData</span> =&gt;</span> {
  d3.selectAll(<span class="hljs-string">'.lineLegend'</span>).remove();
  <span class="hljs-keyword">const</span> legendKeys = <span class="hljs-built_in">Object</span>.keys(data[<span class="hljs-number">0</span>]);
  <span class="hljs-keyword">const</span> lineLegend = svg
    .selectAll(<span class="hljs-string">'.lineLegend'</span>)
    .data(legendKeys)
    .enter()
    .append(<span class="hljs-string">'g'</span>)
    .attr(<span class="hljs-string">'class'</span>, <span class="hljs-string">'lineLegend'</span>)
    .attr(<span class="hljs-string">'transform'</span>, <span class="hljs-function">(<span class="hljs-params">d, i</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-string">`translate(0, <span class="hljs-subst">${i * <span class="hljs-number">20</span>}</span>)`</span>;
    });
  lineLegend
    .append(<span class="hljs-string">'text'</span>)
    .text(<span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> {
      <span class="hljs-keyword">if</span> (d === <span class="hljs-string">'date'</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${d}</span>: <span class="hljs-subst">${currentData[d].toLocaleDateString()}</span>`</span>;
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( d === <span class="hljs-string">'high'</span> || d === <span class="hljs-string">'low'</span> || d === <span class="hljs-string">'open'</span> || d === <span class="hljs-string">'close'</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${d}</span>: <span class="hljs-subst">${currentData[d].toFixed(<span class="hljs-number">2</span>)}</span>`</span>;
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${d}</span>: <span class="hljs-subst">${currentData[d]}</span>`</span>;
      }
    })
    .style(<span class="hljs-string">'fill'</span>, <span class="hljs-string">'white'</span>)
    .attr(<span class="hljs-string">'transform'</span>, <span class="hljs-string">'translate(15,9)'</span>);
  };
</code></pre><p>The <code>updateLegends()</code> method updates the legend by displaying the date, open price, close price, high price, low price, and volume of the selected mouseover point on the close line graph. Similar to the Volume bar charts, we will make use of the <code>selectAll()</code> method with the <code>enter()</code> and <code>append()</code> methods.</p>
<p>To render the legends, we will use<code>.selectAll('.lineLegend')</code> to select the legends, followed by calling the <code>remove()</code> method to remove them. Next, we pass the keys of the legends, <code>legendKeys</code>, which will be used to define the height of each bar. The <code>enter()</code> method is called, which compares the <code>volData</code> dataset and at the selection from <code>selectAll()</code>, which is currently empty. Currently, the DOM does not contain any <code>&lt;re</code>ct&gt; element. Thus<code>, the ap</code>pend() method accepts an arg<code>ument</code> ‘rect’, which creates <code>a new</code>  element in the DOM for every singl<code>e objec</code>t in volData.</p>
<p>Next, append the legends with their respective properties. We further process the values by converting the prices to 2 decimal places. We also set the date object to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString">default locale</a> for readability.</p>
<p>This will be the end result:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/TdHsr5qhwh-KFRJHOeGi0RfqtYS8XD4QbCjG" alt="Image" width="800" height="399" loading="lazy">
<em>Checkpoint #4: Mouseover any part of the chart!</em></p>
<h4 id="heading-closing-thoughts">Closing Thoughts</h4>
<p>Congratulations! You have reached the end of this tutorial. As demonstrated above, D3.js is simple yet dynamic. It allows you to create custom visualizations for all your data sets. In the coming weeks, I will release the second part of this series which will deep dive into D3.js’s enter-update-exit pattern. Meanwhile, you may wish to check out the <a target="_blank" href="https://github.com/d3/d3/wiki">API documentation</a>, <a target="_blank" href="https://github.com/d3/d3/wiki/Tutorials">more tutorials</a>, and <a target="_blank" href="https://github.com/d3/d3/wiki/Gallery">other interesting visualizations built with D3.js</a>.</p>
<p>Feel free to check out the <a target="_blank" href="https://github.com/wentjun/d3-historical-price-chart-basic">source code</a> as well as the <a target="_blank" href="https://wentjun.com/d3-historical-price-chart-basic/">full demonstration</a> of this tutorial. Thank you, and I hope you have learned something new today!</p>
<p><em>Special thanks to Debbie Leong for reviewing this article.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Europe’s push for Open Banking is forcing banking apps to improve their UX ]]>
                </title>
                <description>
                    <![CDATA[ By Michael Gardner How you see and interact with your online bank accounts is about to change. That’s because Europe is forcing change into the financial market. Digital transformation is a thing this decade. “Digital disruption,” startups who want t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/sick-of-your-banks-lame-app-open-banking-promises-more-9770cad2448c/</link>
                <guid isPermaLink="false">66c35ec8ef766eb77cd787aa</guid>
                
                    <category>
                        <![CDATA[ banking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fintech ]]>
                    </category>
                
                    <category>
                        <![CDATA[ startup ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 13 Aug 2017 22:41:58 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*UD1aAtumz-BkvNNQE7DO-w.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Michael Gardner</p>
<p>How you see and interact with your online bank accounts is about to change. That’s because Europe is forcing change into the financial market.</p>
<p>Digital transformation is <a target="_blank" href="https://trends.google.co.uk/trends/explore?date=all&amp;q=digital%20transformation">a thing</a> this decade. “Digital disruption,” startups who want to be “the Uber of X” in their industry, and going “mobile first” are not new trends. But the banking industry has been slow to move with the times.</p>
<p>New businesses have started to push into the European banking market. Yet progress has been slow, due to both regulation and customer inertia. Even though companies who focus on the best customer experience <a target="_blank" href="https://www.linkedin.com/pulse/organisations-leverage-cx-more-successful-i-have-proof-adam-halvorsen">outperform the market</a>.</p>
<p>The pace of change in the banking industry will accelerate in 2018. Some new laws coming into effect are to thank.</p>
<h3 id="heading-why-are-things-changing">Why are things changing?</h3>
<p>European governments have decided that “traditional” banks are uncompetitive and slow. New banks find it very hard to break into the market. To do something about this, they have created some new legislation. This new legislation will force all banks to share a lot more digital information when their customers ask them to.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/osYuOCBZZK3D87rMNODedRknK7EoehJW5k0W" alt="Image" width="800" height="466" loading="lazy">
_Open Banking Model. Image Credit: [XMLdation](https://www.xmldation.com/en/2016/rapid-development-tools-for-api-and-json-flows-becoming-competitive-assets-to-meet-psd2/" rel="noopener" target="<em>blank" title=")</em></p>
<p>As the above diagram shows, current core banking services will have a new digital interface added. This is called an API, or Application Programming Interface. It will allow third party “fintech” (Financial Technology) apps and services to get information directly from your bank. It’ll also add a new layer of tools on top. These fintech apps may be provided by your bank, or by external companies.</p>
<p>All these changes must become law by January, 2018.</p>
<p>In addition to the European legislation (<a target="_blank" href="https://ec.europa.eu/info/law/payment-services-psd-2-directive-eu-2015-2366_en">PSD2</a>), the UK has its own version (<a target="_blank" href="https://www.openbanking.org.uk/">Open Banking</a>). So this change will affect the UK regardless of Brexit.</p>
<h3 id="heading-what-differences-will-it-make">What differences will it make?</h3>
<p>This piece will focus on three of the biggest, broadest changes and how they will affect consumers. I will also follow up with a deeper dive into each change. There, I’ll discuss possible side effects as well as business opportunities.</p>
<h3 id="heading-direct-bank-account-payments">Direct bank account payments</h3>
<h4 id="heading-what-are-they"><strong>What are they?</strong></h4>
<p>Right now, if you’re shopping online, you would most likely choose to pay with your debit card. The merchant (e.g. Amazon) has an acquirer (e.g. WorldPay) who coordinates with your debit card provider (e.g. Visa). They will then pull the payment out of your bank account (e.g. Barclays). That’s a lot of companies — and they’re all getting paid.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/u9iUuDB1ivsdMsbwCZsbhyHM6FUDF2nIIRSw" alt="Image" width="800" height="507" loading="lazy">
_The current payment model. Image Credit: [Mark Sherman, IBM](https://www.slideshare.net/msherman1001/mobile-money-p" rel="noopener" target="<em>blank" title=")</em></p>
<p>The idea is that you, the consumer, can instead “push” a bank transfer direct from your bank (Barclays) to the merchant (Amazon).</p>
<h4 id="heading-how-it-affects-you-the-consumer"><strong>How it affects you, the consumer</strong></h4>
<p>In the future, instead of entering all your card information, you’d grant Amazon permission to access your bank account. The user experience would be like logging into other websites with your Facebook account today. The first time, it will take you to your bank’s website and ask you to confirm your authorization. After that, the permission should stay active until you revoke it, so you can just click and buy.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MbQFqdopij3nDkTLFSfCjYfXDQQykMUlt0AH" alt="Image" width="633" height="649" loading="lazy">
_Login with Facebook example. Image Credit: [Facebook](https://newsroom.fb.com/news/2014/04/f8-introducing-anonymous-login-and-an-updated-facebook-login/" rel="noopener" target="<em>blank" title=")That’s going to be a bit easier than entering your card details every time. But if you have your card details saved somewhere, it’s not going to make a huge difference for your ease of purchase.</em></p>
<p>It will be interesting to see how this change affects all those other companies who were playing the middlemen. That will, of course, have an indirect effect on you. But it’s hard to say exactly what. Amazon’s costs should go down. Will they pass those savings on to you, or otherwise incentivize you to pay in the way that’s cheapest for them?</p>
<h3 id="heading-information-sharing-across-all-financial-institutions">Information sharing across all financial institutions</h3>
<h4 id="heading-what-is-it"><strong>What is it?</strong></h4>
<p>Currently, the only way to get your bank information online is to log on to the website. Or perhaps they have a clumsily ported mobile website, packaged as an “app.” If you wanted to let another organization see your bank account, you’d have to give them your login details. This breaks the bank’s T&amp;Cs, and would cause all kinds of issues in case of fraud or misuse.</p>
<h4 id="heading-how-it-affects-you"><strong>How it affects you</strong></h4>
<p>By the new regulations, banks must provide a secure way for third parties to access your banking information. You will be able to consolidate all your information in one place, and see your ‘actual’ balance across all banks, accounts, and cards. Furthermore, you’ll be able to use that information in useful services.</p>
<p>For example, some of the new “challenger banks” like <a target="_blank" href="https://monzo.com/blog/2016/11/14/spending-android/">Monzo</a> or <a target="_blank" href="https://www.starlingbank.com/spending-insights-feature/">Starling</a> can show you a breakdown of your spending. They can do it by category (e.g. restaurants), then by store (e.g. Nandos), then by transaction. They’ll even show you the location of that pub where you bought a round last night.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1BZ8su93FGSMSoW1hGVLDDEC2CJ-kdNZSjaw" alt="Image" width="800" height="712" loading="lazy">
_Monzo Spending Breakdown. Image Credit: [Monzo](https://monzo.com/blog/2016/11/14/spending-android/" rel="noopener" target="<em>blank" title=")</em></p>
<p>Now imagine if you didn’t have to switch current accounts or wait for your bank to bring out something similar. You could just plug in to a service that collates it for you, from all your accounts and credit cards. After these changes, that should be possible and even simple.</p>
<p>There are many possible applications for this type of information. Some examples include: personalized credit or budgeting advice; easier <a target="_blank" href="https://withplum.com/about/">savings</a>; easier current account switching (based on automated, personalized advice); better terms for loans or credit (in exchange for more access to your information for underwriting); easier personal tax returns, or small business accounting; third party fraud detection services you can use across all your cards and accounts; simpler and cheaper international transfers; and the list goes on.</p>
<p>Let’s look at an example of the possible, unexpected side effects of the improved customer service and transparency banks can provide. There’s a great story <a target="_blank" href="https://medium.com/@tristanwatson/bag-snatchers-monzo-and-a-night-of-adventure-in-london-d051a3eeb4cb">here</a> about how Monzo helped one customer get his stolen bag back the same night it was taken. There was even a bonus bottle of Jack Daniel’s included.</p>
<h3 id="heading-strong-authentication-for-online-payments">Strong authentication for online payments</h3>
<h4 id="heading-what-is-it-1"><strong>What is it?</strong></h4>
<p>Authentication is how the bank or payment provider knows that you are who you say you are. Given how much of your financial information they’ll be able to share, it’s critical that they use it securely. This is where authentication comes in. The new regulations will require multi-factor authentication in many areas. This will include every online purchase over <a target="_blank" href="https://www.finextra.com/newsarticle/30171/eba-to-relax-controversial-psd2-authentication-rules">€30</a>.</p>
<p>There are three commonly recognized methods of authentication:</p>
<ul>
<li>Something you know (e.g. a password or PIN number)</li>
<li>Something you have (e.g. a phone number, an app, or a physical dongle)</li>
<li>Something you are (e.g. biometrics like fingerprint, or facial recognition)</li>
</ul>
<p>Using more than one of these methods together is “2-factor” or “multi-factor” authentication.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XALfh3edh6jSl4ak74KmjBBr2Hojy0fBB8bV" alt="Image" width="800" height="239" loading="lazy">
_Multi-factor Authentication. Image Credit: [NIST](https://www.nist.gov/itl/tig/back-basics-multi-factor-authentication" rel="noopener" target="<em>blank" title=")Multi factor authentication is already common when creating new payees in your online bank account. You may have used a card reader, dongle or automated confirmation telephone call. However, this is often an awkward or off-putting user experience. The user must shift their attention away from the website, and it’s especially annoying if the user needs a physical object for the confirmation.</em></p>
<h4 id="heading-how-it-affects-you-1"><strong>How it affects you</strong></h4>
<p>The average online retail transaction in Europe was <a target="_blank" href="https://www.retailmenot.com/corp/static/filer_public/86/ed/86ed38d1-9cb9-461c-a683-ab8e7b4e1ffc/online_retailing_in_europe_us_and_canada.pdf">$85.63</a> in 2016. This means that the majority of your online payments will need multi-factor authentication.</p>
<p>Purchasing things online might become harder for consumers. So having a slick, multi-factor authentication method in their payment path is going to become critical for online retailers.</p>
<h3 id="heading-summary">Summary:</h3>
<blockquote>
<p>“Open Banking creates a clear motion towards customer-centricity in the UK’s financial services.” — <a target="_blank" href="https://www.starlingbank.com/open-banking/">Starling Bank</a></p>
</blockquote>
<p>Open Banking is going to speed up the pace of change in the finance and banking industry. It’s going to open doors to new and improved customer experiences — and perhaps some bad ones in authorization.</p>
<p>As an online consumer, you should keep your eyes open for some slick new financial services and personalized advice platforms. Watch out for new ways to pay, and for new security checks on your existing payment methods. Expect more from your banking services (which may no longer be provided directly by your bank).</p>
<p>For businesses in the finance industry, and anyone who takes online payments, there are opportunities and risks. These will be highlighted further in upcoming deeper dives. It’s going to be vital that businesses look at how these changes impact each customer’s experience so they can include it in their service design. If you want to talk to some experts in customer experience design and implementation, <a target="_blank" href="http://dminc.com/">drop us a line at DMI</a>.</p>
<h3 id="heading-further-reading">Further reading</h3>
<ul>
<li><a target="_blank" href="https://www.openbanking.org.uk/about/the-initiative-open-banking/">https://www.openbanking.org.uk/about/the-initiative-open-banking/</a></li>
<li><a target="_blank" href="https://www.starlingbank.com/explaining-psd2-without-tlas-tough/">https://www.starlingbank.com/explaining-psd2-without-tlas-tough/</a></li>
<li><a target="_blank" href="https://www.starlingbank.com/open-banking/">https://www.starlingbank.com/open-banking/</a></li>
<li><a target="_blank" href="https://transferwise.com/gb/blog/what-is-psd2">https://transferwise.com/gb/blog/what-is-psd2</a></li>
<li><a target="_blank" href="http://www.experian.co.uk/blogs/latest-thinking/psd2-and-open-banking/">http://www.experian.co.uk/blogs/latest-thinking/psd2-and-open-banking/</a></li>
<li><a target="_blank" href="https://www.finextra.com/blogposting/13651/angst-over-the-ebas-psd2-two-factor-authentication-directive">https://www.finextra.com/blogposting/13651/angst-over-the-ebas-psd2-two-factor-authentication-directive</a></li>
<li><a target="_blank" href="https://theodi.org/blog/comment-banking-uber-moment-continued-action">https://theodi.org/blog/comment-banking-uber-moment-continued-action</a></li>
<li><a target="_blank" href="https://www.home.barclays/content/dam/barclayspublic/docs/Citizenship/Research/Open%20Banking%20A%20Consumer%20Perspective%20Faith%20Reynolds%20January%202017.pdf">https://www.home.barclays/content/dam/barclayspublic/docs/Citizenship/Research/Open%20Banking%20A%20Consumer%20Perspective%20Faith%20Reynolds%20January%202017.pdf</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
