{"data":{"markdownRemark":{"html":"<h1 id=\"building-a-synthetic-market\"><a href=\"#building-a-synthetic-market\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Building a Synthetic Market</h1>\n<p><em>Before beginning this assignment it is recommended that you build or at the least review, the Synthetic Market Tutorial</em></p>\n<a href=\"https://simudynecontent.blob.core.windows.net/$web/trading-challenge-base.zip\" class=\"ui button primary\" download>\n\tDownload Challenge Base Model</a>\n<a href=\"https://simudynecontent.blob.core.windows.net/$web/trading-challenge-answers.zip\" class=\"ui button primary\" download>\n\tDownload Answer Key</a>\n<p>Agent-Based models are a powerful tool in understanding the dynamics of complex adaptive systems. When building an agent-based simulation we want to focus on implementing real-world behaviors that we inject into our agents. Because we are able to create agents with heterogenous attributes and behaviors, we are able to capture some of the complex interactions of the real-world.</p>\n<p>The purpose of this assignment is to get you familiar with both the Simudyne SDK and the fundamentals of building an agent-based simulation.</p>\n<p>A production-level system will be subject to levels of scrutiny and scientific rigor that we will not hold ourselves to in this exercise. Instead, the objective of this exercise is to familiarize yourself with the SDK and learn how to extend an existing model with new behaviors, agents and complexity.</p>\n<p>The goal is for you to complete this challenge with a deeper understanding of how agent-based systems are developed and the kinds of questions that can be answered using this approach.</p>\n<p>This exercise should only take you 0.5-1 day of work to complete.</p>\n<p>Assignment overview:</p>\n<ol>\n<li>Section I: Understand the base model</li>\n<li>Section II: Learn how to add new traders</li>\n<li>Section III: Adding momentum traders</li>\n<li>Section IV: Adding fundamental traders</li>\n<li>*Section V: Adding your own trader type</li>\n</ol>\n<p>*Part V is an additional section should you complete Sections I-IV with significant time remaining. For more advanced users, this is an opportunity to implement your own trading strategies.</p>\n<h2 id=\"section-i-what-is-a-synthetic-market\"><a href=\"#section-i-what-is-a-synthetic-market\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Section I: What is a synthetic market?</h2>\n<p>For this portion of the assignment our goal is to understand how our base model works and decide what we want to accomplish in this challenge. More on that in a second!</p>\n<p>A synthetic market is a simulation of a market and its market participants. This means that we have 2 main types of agents, Traders and Markets. Traders can consist of a diverse population of agents with their own trading strategies, aggressiveness, risk aversion, capital, etc. Our Markets can equally contain market structure that is representative of real-world mechanics. For example, we might want to model NYSE and create a continuous double auction trading environment. We could even implement the exact rules of the exchange we're interested in and create a limit order book for all the symbols traded at the exchange.</p>\n<p>Our market simulator won't be as complex as a real exchange, however it will reproduce some interesting market behavior. The model you will build will be an extension of the  <a href=\"https://portal.simudyne.com/tutorials/trader\">Synthetic Market Tutorial</a>.\nDownload the project files and walk through the code to get an idea of how noise traders function. Once you've walked through the code, run the model and open the console to run the simulation.</p>\n<p>Notice that the price formation process is effectively random.</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.23423944476576%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABvElEQVQoz4WTS2/TQBSF8wOAtPFjZuyxJzYlLVLFBhUWfSSkKG1ap04c+pDoopX6e1ghUWDDjp95ODPOswix+HSv79w5c+bhhmn/gM720RJHaAZH8KI+RFJAtSv40cgRxBeL3GeuzIQ9JRlDmjECXTJOELLW0OkvJJ0HCEOSc0Tt0gnIpGLj+G/ikqLr2LpMKagnaCTmN94efsXu3hfkO5+Rbd/QyRnC6BSeHJCTGcvcfxrVCUTMOfqCDpNHOnvPLXe55R42xQd+jxDZBjWAYHPoGMziEjHDjsl4SJeVFfxO5QMKfXSCnjqG0AU80ccz/wDPg8Ml/pPcX9Zsb0sO54L72Aj7pEdqh4ZnKaPhCmcOoU4XuYpr7HjatpdFh6n5yYvoUujYCdZbLvFm9wG5ma7wCRm39Lpzh05+jTytaw7Wt7du+Vqu0IjiRzTDdysOe7zJEfTWNTzGVlQs2FTnUNkUYTpmXqyN+do+o8oKfsOLYM8JNoOuw76rMLmESK/WkGRelys1uei5rB3OBTeCmUO3Gp1wxf/CtxfoyhFyzrogxZzDuECU3XHFW/4B/8aOx/k9zKt7vNyxZzjFH3FLS3bIz6+tAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-8e416.webp 173w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-0b506.webp 345w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-58be5.webp 690w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-59b8d.webp 1035w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-4a474.webp 1380w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-bc809.webp 2070w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-799d1.webp 3458w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-7e3fa.png 173w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-7f1d4.png 345w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-13856.png 690w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-045bb.png 1035w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-f46ab.png 1380w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-ea5f6.png 2070w,\n/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-fc883.png 3458w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-13856.png\"\n          alt=\"priceFormationRandom\"\n          title=\"\"\n          src=\"/static/priceFormationRandom-8a0640e5b3903fbaa07eb0c4c9f8c08a-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>Also have a look at the network view, notice that we have a single market agent and a population of traders surrounding it.</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.34428118697782%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACiUlEQVQoz2WSy08TYRTF2ehGpMV2Hu1Mp8NDkUdMfCQqyqMNEqG8p1SgtCTUSBRTjbhwo6h0SgsaMFCLQnkoxJW6dGEwvoKGCBgVjX/N8c43ghoXJzOZ+83vnnvul6XmpyCplbCJFbBwlbA7veCl06R6cJIPnMNH7z5YhTrssNQy7bTWItteBzmvBaKrkc41wOFuBi83IMulZuDa2wte6aEP9VRoZEV3YQByQQBu9Qysooai4k5c7YkiGryIC5398HkjyObbICrt4F2G/OxJwAUcqpjGgWNp5O/vJnXC5mwGR0VR8WO30IaSsi68vHcTXx8nsLmUxPLkED48jKHpVAQ5VBfd7RAUQ34CutP040kauQpWvhq5ggec3EyHArBJGkpKu/BibBA/lhJ4/0DH6oyO74sJfHk0jM8LcVQc74FFNKGGyyxZSdOoHuwRayjDatgcXgZ0qAHs4loR0c7j55Mk1ufjWJsfxVxyAm+m7zK3n2bjSEQHCKhtu2RAwVVN7jx/HEom0Mioo+EcA36c1vF0fAxXBlewNJ7BxpyOV6kYc2/m6DeBinsKUl4Nwbz/jGwCWxFu6cPyxG28vh/DyswoMok0no/dwcb8ML7R6COXBrZHZkCnnCLQiW2HhjipiWWY69Bw9EgI79JDWJ+LM63N6ng7pWOTYKszMZZhzt8ZOqUUZVcOK+dhGVq4KgYUlAA7ZCXo4YPdeJa4TkBjEUmKYIQtpc7Ty/JzUHNzy4ZDadIE/na4BeRdGsnorJGDFpSWdeBGXxSLt65B77+MqvIQNWul/NsoIkPalsP/gXanD1J+L8HCTE41TFcohGwhCLscIldBgnVTzmG6/Geh7ougsDgEpaAdvwAiZZlBiR0KzwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-8e416.webp 173w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-0b506.webp 345w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-58be5.webp 690w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-59b8d.webp 1035w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-4a474.webp 1380w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-bc809.webp 2070w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-3c406.webp 3471w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-7e3fa.png 173w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-7f1d4.png 345w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-13856.png 690w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-045bb.png 1035w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-f46ab.png 1380w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-ea5f6.png 2070w,\n/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-cd19f.png 3471w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-13856.png\"\n          alt=\"networkViewNoiseTraders\"\n          title=\"\"\n          src=\"/static/networkViewNoiseTraders-0a3d46e750847f35b4d0b07e182e29da-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>Once you have a good understanding of the behavior and how the model works move on to the next section.</p>\n<h2 id=\"section-ii-adding-new-traders\"><a href=\"#section-ii-adding-new-traders\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Section II: Adding new traders</h2>\n<p>The first thing we will do is learn how to add new agents to our system. We will walk through how to complete each of the below steps.</p>\n<p>When adding a new agent to our simulation there are a few base steps applicable to any new agents:</p>\n<ol>\n<li>Create a new agent class</li>\n<li>Connect the agent class to the simulation via the GlobalState</li>\n<li>Register the agent in the <code class=\"language-text\">init()</code> function</li>\n</ol>\n<p> Create a new Java class with your agents name, this can either be an entirely new agent defined like so:</p>\n<blockquote>\n<p>NewAgent.java</p>\n</blockquote>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">NewAgent</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Agent</span><span class=\"token generics function\"><span class=\"token punctuation\">&lt;</span>MyModel<span class=\"token punctuation\">.</span>Globals<span class=\"token punctuation\">></span></span> <span class=\"token punctuation\">{</span> \n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>or, for more advanced Java users, this could extend a base agent if some of your agents have shared functionality:</p>\n<blockquote>\n<p>NewAgent.java</p>\n</blockquote>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">NewAgent</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">BaseAgent</span> <span class=\"token punctuation\">{</span> \n\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We have now created our new agent and have connected it to the Global State. The last thing we need to do is register our agent in the <code class=\"language-text\">init()</code> function in your model class.</p>\n<blockquote>\n<p>MyModel.java</p>\n</blockquote>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">MyModel</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">AgentBasedModel</span><span class=\"token generics function\"><span class=\"token punctuation\">&lt;</span>MyModel<span class=\"token punctuation\">.</span>Globals<span class=\"token punctuation\">></span></span> <span class=\"token punctuation\">{</span> \n\n\t<span class=\"token annotation punctuation\">@Override</span>  \n\t<span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">init</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>  \n\t\t<span class=\"token function\">registerAgentTypes</span><span class=\"token punctuation\">(</span>NewAgent<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  \n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now your agent has been connected to the <code class=\"language-text\">GlobalState</code> and has been registered at the model class. You are now ready to connect your agent to other agents and add in behavior.</p>\n<h2 id=\"section-iii-adding-momentum-traders\"><a href=\"#section-iii-adding-momentum-traders\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Section III: Adding momentum traders</h2>\n<p>Our goal is to create a more realistic price formation process. Momentum traders will react to trends they see in the market.</p>\n<p>This section consists of 4 steps:</p>\n<ol>\n<li>Add a new agent called <code class=\"language-text\">MomentumTrader.java</code></li>\n<li>Connect your new trader to the exchange</li>\n<li>Add a moving average trading strategy</li>\n<li>Test that your agent is sending orders and trading properly</li>\n</ol>\n<h3 id=\"step-1-adding-your-new-trader\"><a href=\"#step-1-adding-your-new-trader\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: adding your new trader</h3>\n<p>Add your new agent using the instructions from the previous section. Name your agent <code class=\"language-text\">MomentumTrader.java</code>.</p>\n<p>Now that you have a new trader agent it is time to connect that trader to the exchange.</p>\n<h3 id=\"step-2-connect-your-trader-to-the-exchange\"><a href=\"#step-2-connect-your-trader-to-the-exchange\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 2: Connect your trader to the exchange</h3>\n<p>To generate your traders you will need to generate a new group and add new links in the <code class=\"language-text\">setup()</code> function. Follow the structure of the existing agents being generated to define your agents.</p>\n<p>Once you have generated your group of new Momentum Agents and connected them to the exchange, your network view in the console should look like the graph below:</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.38239538239538%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACnUlEQVQoz1WTy08TYRTFuyFRgrbQznSm82h5KSyICxdGw6spWLCU0tJW6guJgGkqRtm4oCL0QUuJBQSESiSCRYOGxBCJxmiUhUg0xrjRpcZ/5HhnWqsuTiaT7+b3nXvu/TSWyiUIlnqUcY3QMk0wmGxghXaSAwxJL3SAFTtQyjtQpLNjn64NRVo7ig2nIJS7wcmdVOcEb+6iOic0cvkDSNV9YOVeOmijgg6YzC6Yq/wQK09DqOqBTvKj/ngvIsFhBH0hDF+8iu72AWg5D4yyTxUreUk+BbiOow0Z1B2bR+2RQdIl6E0u9dAoe6E1enCopgdr4yN4v5zAj83b2F2ewPZsFF32AZSwHjLhy4O90EjmDDjpBPRcE7XdSi5PUoGLDv1gRC+qawNYDI/g8+ok3tyNkybw8+kkdhZjeLsQxQXXZRygSzlzzqVGJCArNqKUa8FBA2XIWykPF8mPYsaNG/3X8etZGjuZBF4upLCensPSuAJP4NV8HE/i4QJMcakR5TzQaIOOtZJLq+qQt/ix3+DGtfND2F1JYSsdxcbMHG4mP2EuuYbnM1EVupEYVVv9D8jJTTBKdnXCBaA5BwydCeHbo0l8vJ/A3uo04rcINn8H39eT2EyN43EsDJPlH4eS6rCBQHmHxuYCsIR1I+AcpNZi2JqJYW+FsruXwJfsFL5mU9iejiAUCNFKdRcGoxGkJXJWXwCyoo3c5oaiZKMUO1r6sZ0ew4vZCF4vJvEuk8SHlSSunB3KDaQwZaVlAjJ5h1qmmXbQTv+5tfnTho6g/d4gHkbC2JwaQzY+imBPCAbaAkbsVuuUr0Hw/AUyQisNxgo9b6MbnRArfLROneoL4CmCMr4zH4WLXlYX7adT/RcrvJShBxU153C4rg+/AZrUm9F8/7EVAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-8e416.webp 173w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-0b506.webp 345w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-58be5.webp 690w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-59b8d.webp 1035w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-4a474.webp 1380w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-bc809.webp 2070w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-ef3bb.webp 3465w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-7e3fa.png 173w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-7f1d4.png 345w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-13856.png 690w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-045bb.png 1035w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-f46ab.png 1380w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-ea5f6.png 2070w,\n/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-9eb53.png 3465w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-13856.png\"\n          alt=\"networkWithMomentum\"\n          title=\"\"\n          src=\"/static/networkWithMomentum-e7c538a1765565b8572741efd9c9ff74-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>*Note that if you added a new type of <code class=\"language-text\">Link</code> for your trader to be connected to the exchange you will need to register that in the <code class=\"language-text\">init()</code> function in your model class as well.</p>\n<h3 id=\"step-3-add-a-moving-average-trading-strategy\"><a href=\"#step-3-add-a-moving-average-trading-strategy\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 3: Add a moving average trading strategy</h3>\n<p>There is some shared functionality between the noise traders and your new momentum trader that you can pull into your <code class=\"language-text\">MomentumTrader.java</code> agent.</p>\n<p>Go ahead and move the <code class=\"language-text\">buy()</code> and <code class=\"language-text\">sell()</code> functions into your <code class=\"language-text\">MomentumTrader.java</code> class. If you'd like to, you can also copy the 2 actions in the <code class=\"language-text\">NoiseTrader.java</code> class into your new class. These can be used as a template for your new momentum behaviors.</p>\n<p>Traders in our system in general do 2 things: </p>\n<ol>\n<li>Send orders to the exchange</li>\n<li>Receive information from the exchange about the market</li>\n</ol>\n<p>These are the 2 behaviors that need to be defined in our new class.</p>\n<p><em>Implementing a moving average strategy</em>\nIn short, the moving average strategy we will use in our simulation will follow a simple rule:\nIf the short-term moving average crosses the long-term moving average in an upward direction (i.e. from below to above), we buy. If the short-term moving average crosses the long-term moving average in a downward direction (i.e. from above to below), we sell.</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 625px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 58.58343337334934%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABcklEQVQoz6VTaWvCQBDd//9//CQJeEVEEUSJBoMniRo1XkmM5ytvykoMbaHtwpDdud+biULuPJ9P/Oeox+MBSj5Rs9nE6XTC4XBAkiTyPh6PCMMQ9/tdfGg/n88YDoeYz+efCVutFtrtNvr9PlzXlaA4juE4DnzPx3a7xXq9Frvv+1JgtVohCAIRFphMJhJ7u92g6LzZbER2ux3SNH11wM551292Op1OBQ112q7R8au+4+IrLi+Xi3T7k78qFosoFAqoVCowTVOgak71V4s+eX1WFDlbLpfCC/kg0b892WJqNpu9eBuPx5KcJFPPybEQ74TKtx4AJ0veOeU3yHTQq8GEnudJwGAwQL1ex2KxED0TcNIcSq/XEx2LMS7bqdLYoyiSihw9nbg61+tV+CINpIZIaNc8Moa6/X7/SiyQ2SE763Q6qNVqMAwDjUYD3NHRaCR627ZhWRaq1aroSqWSIOh2uyiXy2KXhH/59bg+lLw/7x+FdZVzdFpbAwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-3ace9.webp 173w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-bbc01.webp 345w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-18ac5.webp 690w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-d883a.webp 833w\"\n          sizes=\"(max-width: 625px) 100vw, 625px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-390bb.png 173w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-fcaba.png 345w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-f2533.png 690w,\n/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-bfee9.png 833w\"\n          sizes=\"(max-width: 625px) 100vw, 625px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-f2533.png\"\n          alt=\"movingAverageFormula\"\n          title=\"\"\n          src=\"/static/movingAverageFormula-f8a5ed43bf0181727b3a212772b49b92-f2533.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>For more information on the theory behind the moving average strategy, check out this useful link <a href=\"https://www.investopedia.com/terms/m/movingaverage.asp#:~:text=In%20statistics%2C%20a%20moving%20average,commonly%20used%20in%20technical%20analysis.\">Moving Average</a>. </p>\n<p>For our moving average strategy to work we must gather historical prices and compute a long term and short term moving average at each step.</p>\n<p>Variables and data structures your strategy will need:</p>\n<ul>\n<li><strong>Short-Term Moving Average Look Back Period</strong> - This is the number of days of market price data you will use to calculate your short-term moving average (default = 7)</li>\n<li><strong>Long-Term Moving Average Look Back Period</strong> - This is the number of days of market price data you will use to calculate your long-term moving average (default = 21)</li>\n<li><strong>Historical Prices</strong> - This will contain the information on the step and price at that step (it is recommended you create a <code class=\"language-text\">HashMap&lt;Long, Double&gt;</code> to store your data where the key is the tick and the value is the price. At each step you will need to have the market price returned to the trader and stored in your map.</li>\n<li><strong>Short-Term Moving Average</strong> - This will be our short-term moving average calculated from historical prices. It is recommended that you place this field on your agent and tag it with an <code class=\"language-text\">@Variable</code> annotation so it automatically generates a tile in the console.</li>\n<li><strong>Long-Term Moving Average</strong> - This will be our long-term moving average calculated from historical prices. It is recommended that you place this field on your agent and tag it with an <code class=\"language-text\">@Variable</code> annotation so it automatically generates a tile in the console.</li>\n</ul>\n<p>Things to take into consideration as you implement:</p>\n<ol>\n<li>This trading behavior can only begin once enough trading days have passed, set a condition to check the the current tick is greater than the <em>Long-Term Moving Average Look Back Period</em> before engaging in trading.</li>\n<li>Because there is no tracking of assets or cash in our traders they have no indication as to whether they have run out of cash. This is important because we need to control their behavior so they don't continuously buy or sell and tank the market (though they might anyways depending on how other traders behave). Add in a stochastic decision process like a random probability for whether they will actually buy or sell when the Moving Average conditions are met. If you expose this to the console via placing it in the <code class=\"language-text\">Globals.java</code> and tag it with an <code class=\"language-text\">@Input</code> annotation you can modify the activity of the traders by adjusting this parameter (can be 0-1, larger number means a higher probability to trade in step).</li>\n<li>The current implementation of the message <code class=\"language-text\">MarketPriceMessage</code> used by the exchange to return market information does not support the current price, make sure to extend this message with a new field so the exchange also passes back the market price for recording the historical data. It is <strong>NOT</strong> recommended to place this in the <code class=\"language-text\">GlobalState</code> as your agents will be simultaneously accessing this information and could cause issues due to parallelization.</li>\n</ol>\n<div class=\"ui segment warning message\">\n\t<h4>Executing Actions in Parallel</h4>  \n\t<p>Actions can be called simultaneously which allows different types of agents to send messages in parallel using the\n\t\t<code class=\"language-text\">split.create()</code>\n\t\tmethod. More on how this works can be found here\n\t\t<a href=\":version/reference/agents/actions-and-sequencing#executing-action-in-parallel\">Parallel Actions</a>\n\t</p>\n</div>\n<p>Your actions sequence should be structured similar to the below:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token function\">run</span><span class=\"token punctuation\">(</span>  \n    Split<span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>  \n        NoiseTrader<span class=\"token punctuation\">.</span><span class=\"token function\">processInformation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n        MomentumTrader<span class=\"token punctuation\">.</span><span class=\"token function\">processInformation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        FundamentalTrader<span class=\"token punctuation\">.</span><span class=\"token function\">processInformation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n    Market<span class=\"token punctuation\">.</span><span class=\"token function\">calcPriceImpact</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n    Split<span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>  \n        NoiseTrader<span class=\"token punctuation\">.</span><span class=\"token function\">updateThreshold</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n        MomentumTrader<span class=\"token punctuation\">.</span><span class=\"token function\">updateMarketData</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>  \n        FundamentalTrader<span class=\"token punctuation\">.</span><span class=\"token function\">updateMarketData</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>  \n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The above bit of code that you will implement should be contained in your <code class=\"language-text\">Action</code> that sends trades to the market. This behavior will have to be added to the <code class=\"language-text\">step()</code> method in your model class. You will need to use the <code class=\"language-text\">Split.create()</code> functionality in your run sequence to make it so that all your trader agents send orders to the exchange simultaneously.</p>\n<p>Once you have created a new field on the <code class=\"language-text\">MarketPriceMessage</code> for market price, you will need to adjust the exchange behavior to include market price and set up the reception of that message on the momentum trader side. Follow the structure of the <code class=\"language-text\">NoiseTrader</code> and replicate the <code class=\"language-text\">Action</code>. (Make sure to record the market price and tick at each step in this step.)</p>\n<p>Now compile your code and pull up the simulation in the console, it should look something like this:</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.71923743500867%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACFklEQVQoz4VSy3LTQBD0B/CwrNdKuyutLRJCmZw4UIAdbAx+P2IrrlCm7AD5IW5UOFDc+Mymd2VS3Dh07U5r1NM7MzXT/IbUvIIfd/A47CBI3yJWYyT5HEEyhk8E6fh4H7kzyebMmSJSMwg9QyinEOQiNUFN57+gTz4h1Dt+mFBogUAuGZeIshIxEak1Ir1xsYO9W6gNQn6ziLU9NxQ0v/Hi4ifOX35H8WyP1tmOjljVrBAW/IlORW5/XCKwrlkw0lMWJ09OpHSaTiAzy19SMLvjE17DFz3Uoz4a4h1dLeDrCTwxgJd+YOKC3CUaauRiny2JWUSRk3xuagWVLVyipvQdq3Xhxe/Zwx7dDZCYBeqCsd/FI7+DejhwDussZjmLBnsp1AIPgw7RxQPm+cmsEoyzCwoOjg77ro9JsYInRwhz9tWsIYi4NafDIeImh5KvoclJOxwx5J3PzzaVoKBgrO0kB5VgtoR5/hmyfYA+v4E63XETSuS8y/YNuQPS4iNM6xrtp19wdrJ3SM2WgtkPPvkNGs5hj2efBZbQrS2kYZ+adpor9nGN/EnFJeydnaodVtIsIYsrTr/KcQ4DK8ieeRQLUg5Fc8J6y4QrnjZ56xAq3h1fxfd35sSMLaqhqI7roefcDRmvqiTuokV0hN3Jf7nq/LuPpfvnXjDkOtiV8dnHiNOTra980uE/2EMVtzCnt26HFdv0B2TSTwG42sHFAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-8e416.webp 173w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-0b506.webp 345w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-58be5.webp 690w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-59b8d.webp 1035w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-4a474.webp 1380w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-bc809.webp 2070w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-17fa1.webp 3462w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-7e3fa.png 173w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-7f1d4.png 345w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-13856.png 690w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-045bb.png 1035w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-f46ab.png 1380w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-ea5f6.png 2070w,\n/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-e5fa0.png 3462w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-13856.png\"\n          alt=\"movingAverageGraph\"\n          title=\"\"\n          src=\"/static/movingAverageGraph-9fa5bc0e3180f0f28130339e2461e038-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>The market should now show momentum behavior in the price formation process.</p>\n<p><em>Optional</em>: Once you have implemented your moving average strategy you have the option to create a <code class=\"language-text\">Boolean</code> flag in the console to turn them on and off but this is a nice to have and not necessary to complete the assignment.</p>\n<h2 id=\"section-iv-adding-fundamental-traders\"><a href=\"#section-iv-adding-fundamental-traders\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Section IV: Adding fundamental traders</h2>\n<p>The steps in the previous section for adding the trader and connected that new trader to the exchange should be followed before we implement the trading behavior.</p>\n<p>This behavior will be slightly more complex than the behavior in our momentum trader.</p>\n<p>Our <code class=\"language-text\">FundamentalTrader</code> will use a Relative Strength Index strategy, which we will refer to as RSI. The RSI strategy can be both adapted to a momentum or fundamental strategy. For our purposes we will use this as a fundamental strategy in our simulation. </p>\n<p>The RSI will be a value between 0 and 100. If the RSI goes above the upper threshold, or the overbought threshold, then the asset has exceeded the range of it's perceived fundamental value and the trader will sell. On the contrary if the RSI dips below the lower threshold, or the oversold threshold, then our trader will buy. It will behave like an oscillator.</p>\n<p>For more information on the theory behind RSI, take a look at this helpful link which is the source for the formulas and information below  <a href=\"https://www.investopedia.com/terms/r/rsi.asp\">Relative Strength Index</a>. </p>\n<p>For our RSI indicator we will need to keep track of a couple variables: </p>\n<ul>\n<li><strong>Look Back Period</strong> - This is the number of days of historical prices used to calculate average gains and losses (default = 14)</li>\n<li><strong>Historical Prices</strong> - This will contain the information on the step and price at that step (it is recommended you create a <code class=\"language-text\">HashMap&lt;Long, Double&gt;</code> to store your data where the key is the tick and the value is the price. At each step you will need to have the market price returned to the trader and stored in your map.</li>\n<li><strong>Overbought Threshold</strong> - If the RSI oscillator exceeds this value the the trader should sell. (default = 70)</li>\n<li><strong>Oversold Threshold</strong> - If the RSI oscillator dips below this value the the trader should buy. (default = 30)</li>\n</ul>\n<h3 id=\"the-rsi-calculation-is-separated-into-2-steps\"><a href=\"#the-rsi-calculation-is-separated-into-2-steps\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The RSI calculation is separated into 2 steps:</h3>\n<p>*Make sure to use the historical prices implementation from the momentum trader you implemented in the previous section.</p>\n<p>The first part of our formula requires calculating the average gain and loss over a lookback period. The formula is below: </p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 32.020725388601036%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAuUlEQVQY05VRywqEMAz0//9MvLkiFUTsYRdbakUr+HbWZOml9LIDQ5qkeSf3feO6Lia9Y/Q+j9gfjwR/4DgOOOeivmmauHCyrivKskRd1xjHEed5Yt935rIssNYiz3MO2LYNxvScYJ4dXkXxyJl1rTXHJmQQQqBpGsi2hZSSaYcBVMwYwwmHR6cCWit8Pm+OSdMUWZZBVBVM3/8Shq2HOwlHpo5JUsdKKXRdx8WIPHJ4lNjiw4PF4O1ffPvSJddg5nEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-8e416.webp 173w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-0b506.webp 345w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-58be5.webp 690w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-414b2.webp 965w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-7e3fa.png 173w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-7f1d4.png 345w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-13856.png 690w,\n/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-8f2e0.png 965w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-13856.png\"\n          alt=\"rsiStep1\"\n          title=\"\"\n          src=\"/static/rsiStep1-c217f443a726d29ec17da5029c2c9e33-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>The average gain or loss used in the calculation is the average percentage gain or loss during a look-back period. The formula uses a positive value for the average loss.</p>\n<p>Once there are 14 periods of data available, the second part of the RSI formula can be calculated. The second step of the calculation smooths the results.</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 24.753867791842474%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAlklEQVQY051PywrEIAz0/7+uFy3Wi5dCpXZRpNRXnSWCe9sHOzCQTJJJwvABrTXUWvELRi8zxmBdV8QYkVJCKQXe+67lnBFC6M0UU+2+b2zbBufcSyej67pwnieYtRZkSnwcRy+QCeW0ZN/3bsA5x7JISCkxTRNmIaC1hlIK8yy63g2/vTGuoisGKR/aiMcHjIbe8R88AXWehVPGmiFGAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-8e416.webp 173w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-0b506.webp 345w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-58be5.webp 690w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-59b8d.webp 1035w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-4a474.webp 1380w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-e1a98.webp 1422w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-7e3fa.png 173w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-7f1d4.png 345w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-13856.png 690w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-045bb.png 1035w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-f46ab.png 1380w,\n/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-28eef.png 1422w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-13856.png\"\n          alt=\"rsiStep2\"\n          title=\"\"\n          src=\"/static/rsiStep2-b538ef0f791adf4d0744e37a7425a756-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>This calculation can be a bit tricky to implement correctly. If you're having any issues or want to validate your results, compare your implementation to the answer key. </p>\n<p>Once you've implemented your RSI logic, make sure to create a field on your <code class=\"language-text\">FundamentalTrader.java</code> class called <code class=\"language-text\">rsi</code>. Use an <code class=\"language-text\">@Variable</code> annotation to create a tile in the console.</p>\n<p>Once you've completed these steps and implemented your Fundamental Trader with it's RSI strategy, you're console view should look something like this:</p>\n<p>\n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block; padding: 20px; max-width: 690px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 55.520231213872826%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACQElEQVQoz2VSyW4TQRT0lYu38UzP2uMNJ8hYHJAQItix8Ta2Z8ZxbIc4ASeIE0IsEgd+BKEkJ258ZlHddqRIHEqv13r1Xr1MWP4Nr/wKRdFBzuzAcN9ABDM44QlKzgwGUXJ3MJwpTC/Rd6Yfw5ZzCD/h+5T3MTr9T8j48g/8x1tYAeFP+ZiXXgorPIXYwwoWBGO4giWXu72/gKnPlnyzRF4owi/IBOFfPD++Q+vFL9SevEPlYEPCmJ8mKIghM4+paqaVGZJKpbpTSlOtshQmsMopiqzgePCVCoMbSn8Jw+4ib3VRtFkyH3oHxLMZ7MMxVcxJMkfRH6PgjmCQ0CmvUGIseEMUnQFy1hDd4TdFeEv5r6mGh2aXivosO4aoT+A2I7hPIzi1hKoT5JksZ7SRJXRPSZgttZFn7x9lj9Duf35I2KfCHs3pwSahW4313pIj2OU5FS0gKjEVjmFXUwh5ykQ0Tk5JPIEpk/uSb1lym05FdLHPkkkoU1SaFwibb4k1vNpalxi2ruE1t5CtD0y6RNC4QNC60nAalyRUpsg7NveIRHuFmjBBpbEhzhHWz5hsoRWptV9ewqXzpncCr7JGUF1pGHaC3ug7Mp5/w35wDu2BNsV0ByRIYDosWURsR8zPytk1E690VBBSxRVHh+vwjP1dYBz/3JV8r1CZYstIEwr2yvVoDKPHQRZypWdRBGoOl7u53EfB2cxaKUYPCU2OgxoZBZuEYfWKn8+5JsJLYku8/w9+7SOqh9eQ9Q2i+Af+AYguU5gdztvaAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n    >\n      <picture>\n        <source\n          srcset=\"/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-8e416.webp 173w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-0b506.webp 345w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-58be5.webp 690w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-59b8d.webp 1035w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-4a474.webp 1380w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-bc809.webp 2070w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-d3bd0.webp 3460w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-7e3fa.png 173w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-7f1d4.png 345w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-13856.png 690w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-045bb.png 1035w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-f46ab.png 1380w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-ea5f6.png 2070w,\n/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-bfc85.png 3460w\"\n          sizes=\"(max-width: 690px) 100vw, 690px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n          src=\"/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-13856.png\"\n          alt=\"rsiGraph\"\n          title=\"\"\n          src=\"/static/rsiGraph-293bae4ffda379451eacb1f4cc18a3ba-13856.png\"\n        />\n      </picture>\n      </span>\n  </span>\n  </p>\n<p>Your trader should use this RSI oscillator to determine whether the asset is overbought or oversold and trade based on the thresholds you defined above.</p>\n<p><em>Optional</em>: Implement a Boolean switch that will allow you to turn the traders on and off at your discretion</p>\n<h2 id=\"section-v-adding-your-own-trader-optional\"><a href=\"#section-v-adding-your-own-trader-optional\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Section V: Adding your own trader (OPTIONAL)</h2>\n<p>Now that you've learned to add new trader agents to your simulation, you are all set up to implement your own trader into the system. </p>\n<p>Use the guidance provided in the previous sections and your own knowledge / financial experience to either implement an entirely bespoke trading strategy or choose a well-known strategy and see how it affects the price formation process.</p>\n<h2 id=\"conclusion\"><a href=\"#conclusion\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>You have learned how to use the Simudyne SDK to create a more realistic synthetic market full of momentum, fundamental and noise traders.</p>\n<p>This framework can be applied to a whole host of different problems that might be amenable to an agent-based approach. Financial markets are great examples of complex adaptive systems driven by human (sometimes machine) behavior. We could apply the approach of agent-based simulations to modelling credit card acquisition, lending portfolios that might be impacted by macro-economic factors, and even the spread of contagion like misinformation in a social network.</p>\n<p>More of these introductory assignments will be added in the very near future so stay tuned for more exciting modelling challenges!</p>","headings":[{"value":"Building a Synthetic Market","depth":1},{"value":"Section I: What is a synthetic market?","depth":2},{"value":"Section II: Adding new traders","depth":2},{"value":"Section III: Adding momentum traders","depth":2},{"value":"Step 1: adding your new trader","depth":3},{"value":"Step 2: Connect your trader to the exchange","depth":3},{"value":"Step 3: Add a moving average trading strategy","depth":3},{"value":"Section IV: Adding fundamental traders","depth":2},{"value":"The RSI calculation is separated into 2 steps:","depth":3},{"value":"Section V: Adding your own trader (OPTIONAL)","depth":2},{"value":"Conclusion","depth":2}],"frontmatter":{"title":"Synthetic Market Challenge","toc":true,"experimental":null}},"site":{"siteMetadata":{"title":"Simudyne Docs","latestVersion":"2.6"}}},"pageContext":{"absolutePath":"/home/vsts/work/1/s/content/2.4/docs/challenges/synthetic_market.md","versioned":true,"version":"2.4","kind":"docs","pagePath":"/challenges/synthetic_market","chronology":{"prev":{"name":"Challenges","path":"/challenges"},"next":{"name":"Best Practices","path":"/practices"}},"lastUpdated":"2026-04-21T13:56:54.846Z"}}