{
    "componentChunkName": "component---src-templates-post-page-js",
    "path": "/2018/cryptomate/critical-points",
    "result": {"data":{"site":{"siteMetadata":{"title":"Solid Abstractions","siteUrl":"https://solidabstractions.com","twitterId":291334023,"author":{"fullName":"Julien Hartmann","profileHtml":"I am an open-source de­vel­op­er, for­mer IT con­sul­tant with a pas­sion for new tech­nol­o­gies. I be­lieve the role of an en­gi­neer is to em­pow­er peo­ple, by as­sem­bling sim­ple, re­fined de­signs.\n","links":[{"url":"https://github.com/spectras/","name":"github","title":"GitHub"},{"url":"https://stackoverflow.com/users/3212865/spectras","name":"stackoverflow","title":"StackOverflow"},{"url":"https://www.linkedin.com/in/julienhartmann/","name":"linkedin","title":"LinkedIn"}],"profilePicNode":{"original":{"src":"/static/profile-pic-301a9cbe7b572c3e7910c9717d2b3bcd.jpg"}},"url":"https://etherdream.org/about"}}},"markdownRemark":{"id":"b5fcd5bf-bfb0-5807-b08a-343382dec69c","excerpt":"We detail critical parts of the architecture: relationships between main\ncomponents, strategy life-cycle and integration examples for both testing and production.","html":"<p>We detail critical parts of the architecture: relationships between main\ncomponents, strategy life-cycle and integration examples for both testing and production.</p>\n<p>--- excerpt ---</p>\n<p>This post is part of a 3-subseries in which we design the high-level architecture for Cryptomate.</p>\n<blockquote>\n<ol>\n<li><a href=\"modules\" class=\"internal\">Modules and components</a>.</li>\n<li><a href=\"exploring-patterns\" class=\"internal\">Exploring patterns</a>.</li>\n<li>Critical points <em>(this post)</em>.</li>\n</ol>\n</blockquote>\n<p>In this post, we detail critical parts of the architecture: relationships between main\ncomponents, strategy life-cycle and integration examples for both testing and production.</p>\n<h2 id=\"component-relations\">Component relations</h2>\n<h3 id=\"market-strategy\">Market – strategy</h3>\n<p>In the <a href=\"modules\" class=\"internal\">modules</a> post, we determined that:</p>\n<ul>\n<li>Multiple market adapters could coexist.</li>\n<li>The exact set of active adapters depended on running strategies.</li>\n</ul>\n<p>In order to encapsulate the complexity of dealing with multiple market adapters, we will break\nit down into several components:</p>\n<ul>\n<li>First, we rename the <strong>market adapter</strong> to <strong>market feed adapter</strong>, to make its purpose clearer.</li>\n<li>We introduce a <strong>market feed factory</strong> to keep track of loaded market adapter modules.\nIt can be queried with a feed description, and instantiates a corresponding market adapter.</li>\n<li>We introduce a <strong>market engine</strong> component that will act as a\n<a href=\"https://en.wikipedia.org/wiki/Facade_pattern\" class=\"external\" rel=\"external noopener noreferrer\">façade</a> to the whole market feed subsystem.</li>\n</ul>\n<p>We can now refine the relationship between the strategy and market modules, as a\nport/adapter-relationship using a simplified interface that the <strong>Market Engine</strong> implements.\nThis clean separation will make it easy to replace the component with a proxy when the\nmarket module is <a href=\"#split-market-recorder\" class=\"internal\">deployed as a micro-service</a>.</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-1\"><img src=\"/files/market-strategy-90d71cb7dc10e81439fad8e66e12f988.png\" alt=\"Detailed market-strategy relationship\" srcset=\"/files/market-strategy-1.5x-94d4d46519462b16bde0517b68814590.png 1.5x, /files/market-strategy-2x-c12570dd016cf109c39d1e3aba7656a4.png 2x\"><figcaption><div class=\"figcaption-wrapper\">Detailed market – strategy evaluator relationship. Teal trapezoids are <a href=\"exploring-patterns#hexagonal-architecture\" class=\"internal\">ports</a>.</div></figcaption></figure></div>\n<p>Other noteworthy points:</p>\n<ul>\n<li>I split the market history adapter in two related but separable adapters, because there are\nused  by different components. With this split, the strategy evaluator module no longer\ndepends on history writing functionality. It also makes it possible to feed data into the\nstrategy evaluator module without implementing write access, which will come in handy for\ntesting.</li>\n<li>The <strong>market engine</strong> manages the life-cycle of adapters according to subscriptions it receives\nfrom other modules, starting and stopping market feed adapters as needed.</li>\n<li>From <strong>market engine</strong>'s point of view, history adapter is a single component, which may provide\neither or both of reading and writing features.</li>\n</ul>\n<h3 id=\"trading-strategy\">Trading – strategy</h3>\n<p>As for the market adapters, multiple trading adapters can coexist. Unlike market adapters\nhowever, multiple uses of a trading adapter cannot be merged, as they are likely to use\ndifferent accounts on the trading platform.</p>\n<ul>\n<li>We introduce the concept of a <strong>trading account</strong>, tracking an open, in-use account. It\nis an abstract concept, the details of which are supplied by their owning <strong>trading adapter</strong>.</li>\n<li>We introduce a <strong>trading factory</strong> to keep track of loaded trading adapter modules.\nIt can be queried with a trading platform description to instantiate the matching\ntrading adapter module.</li>\n<li>We introduce a <strong>trading engine</strong> component, that will act as a façade to the whole trading\nsubsystem.</li>\n</ul>\n<div class=\"figure-wrapper\"><figure id=\"fig-2\"><img src=\"/files/trading-strategy-f29d999e101c6ebfda34b113ec1f55e4.png\" alt=\"Detailed market-strategy relationship\" srcset=\"/files/trading-strategy-1.5x-3e7bec9632fac3472fc0ad532e84e344.png 1.5x, /files/trading-strategy-2x-7335a6e5459bcb6594a4f9af78607378.png 2x\"><figcaption><div class=\"figcaption-wrapper\">Detailed trading module – strategy evaluator relationship. Teal trapezoids are <a href=\"exploring-patterns#hexagonal-architecture\" class=\"internal\">ports</a>.</div></figcaption></figure></div>\n<p>Noteworthy points:</p>\n<ul>\n<li>The new trading engine component is the root owner of other trading-related components,\nand manages their whole life-cycle.</li>\n<li>Account components are managed by their respective adapter (probably using some kind of\n<a href=\"https://en.wikipedia.org/wiki/Abstract_factory_pattern\" class=\"external\" rel=\"external noopener noreferrer\">abstract factory</a> pattern).</li>\n</ul>\n<h3 id=\"strategy-life-cycle\">Strategy life-cycle</h3>\n<p>The strategy evaluator module is at the core of the system. It revolves around running\nuser-supplied business logic in a controlled environment.\nIn turn, that user-supplied business logic and its configuration determine what components\nshould be instantiated and destroyed in other parts of the system.</p>\n<p>In order to abstract out the layout and complexity of Cryptomate, and control strategy's\nenvironment, we introduce a <strong>strategy host</strong> module as the single interlocutor for\nthe strategy.</p>\n<p>Also, we <a href=\"modules#component-allocations\" class=\"internal\">identified</a> the necessity of a <strong>strategy builder</strong> module\nto encapsulate the complexity of setting up a trading strategy. Here is an overview of the\nrequired steps:</p>\n<ul>\n<li>Strategy evaluator instantiates a strategy builder, passing it the strategy description.</li>\n<li>\n<p>The strategy builder then:</p>\n<ul>\n<li>locates the strategy evaluator plugin matching the description.</li>\n<li>instantiates a strategy host.</li>\n<li>delegates actual strategy construction to the strategy evaluator plugin.</li>\n<li>hands back built strategy to strategy evaluator.</li>\n</ul>\n</li>\n<li>The strategy evaluator takes ownership of the build strategy and its hots,\nand destroys the builder.</li>\n</ul>\n<p>Lastly, as the unique interlocutor of a strategy, its host can track allocated components\nand ensure they are disposed of when the strategy is shut down.</p>\n<h2 id=\"composition-roots\">Composition roots</h2>\n<blockquote>\n<p>In all software, components form a graph of interconnections as they are composed to\nbuild the system. Most often, this graph has a single component that stands at the root\nof the graph. Hence, “composition root”.</p>\n</blockquote>\n<p>As Cryptomate is modular and flexible composition was part of our requirements, we\nhave multiple composition graphs, with different roots.</p>\n<p>To ensure we do not forget important use cases, we will define a few reference scenarios\nto check against while we implement the system.</p>\n<h3 id=\"custom-use-as-api\">Custom use as API</h3>\n<p>In this scenario, Cryptomate is loaded as a library by a third-party program. That is,\nthe composition root is external. In that case, it offers a set of APIs for the\nthird-party developer to use, namely:</p>\n<ul>\n<li>The <strong>Strategy API</strong> allows instantiating and running strategies.</li>\n<li>The <strong>Market API</strong> allows subscribing to real-time market data, as well as querying market\nhistory.</li>\n<li>The <strong>Trading API</strong> allows placing trading orders and querying basic accounting data.</li>\n</ul>\n<p>In addition, all ports are exposed to the third party, so it can provide custom adapters.\nFor adapters that are loaded automatically by Cryptomate, an adapter registry is exposed\nso custom adapters can be added.</p>\n<h3 id=\"integrated-service\">Integrated service</h3>\n<p>In this scenario, Cryptomate runs as a standalone, integrated service. This is the typical\nsetup for an end-user that runs it on his desktop, or a server dedicated to Cryptomate, for\na single user.</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-3\"><img src=\"/files/deployment-lightweight-c50b95b0e7648e5d625f4978a753a3d2.png\" alt=\"Cryptomate example deployment: integrated service\" srcset=\"/files/deployment-lightweight-1.5x-fc348eb01f5d5e83e52a42b4d8bbe9a5.png 1.5x, /files/deployment-lightweight-2x-031bb0dc2908b50f250982111757b5ff.png 2x\"><figcaption><div class=\"figcaption-wrapper\">Cryptomate example deployment: lightweight integrated service. Teal elements are external to Cryptomate.</div></figcaption></figure></div>\n<p>The (external) user interface can connect and disconnect to the control endpoint to query\nthe state and start/stop strategies.</p>\n<p>All components run within Cryptomate, making deployment and administration easy. This means,\nhowever, that market history recording, if enabled, stops when the system is shut down.</p>\n<h3 id=\"split-market-recorder\">Split market recorder</h3>\n<p>In this scenario, we split market recording, so it can keep recording while the core of the\nsystem is updated or restarted. This is a typical setup for a power user that needs consistent\nhistory to run back-tests on detailed historical data (ticks). Such a setup would normally\ndeploy Cryptomate alongside the market service.</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-4\"><img src=\"/files/deployment-market-cb9e27d7e14c0fc0058c74e47387caab.png\" alt=\"Cryptomate example deployment: with standalone market service\" srcset=\"/files/deployment-market-1.5x-b02d971f195f26ab8df422524c52fa40.png 1.5x, /files/deployment-market-2x-a9bf09afaa050536b7be2215eeb45beb.png 2x\"><figcaption><div class=\"figcaption-wrapper\">Cryptomate example deployment: with standalone market service.</div></figcaption></figure></div>\n<p>Since such a setup puts a special focus on recording market history, it would probably use\nspecialized high-volume NoSQL database such as <a href=\"https://hbase.apache.org/\" class=\"external\" rel=\"external noopener noreferrer\">HBase™</a>.</p>\n<h3 id=\"full-cluster-deployment\">Full cluster deployment</h3>\n<p>In this scenario, Cryptomate is deployed on a larger scale, handling hundreds or thousands\nof concurrent strategies for many users. The typical use is to provide a hosted trading\nautomation platform.</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-5\"><img src=\"/files/deployment-clustered-05135daffeca0a825d33c217396ee1b6.png\" alt=\"Cryptomate example deployment: clustered service for multi-user web-app\" srcset=\"/files/deployment-clustered-1.5x-7b3d878fff73c457432b58929521cf92.png 1.5x, /files/deployment-clustered-2x-72b435856e94146c242b437795a8441e.png 2x\"><figcaption><div class=\"figcaption-wrapper\">Cryptomate example deployment: clustered service for multi-user webapp.</div></figcaption></figure></div>\n<p>The user interface is replaced with a full-blown web application, and most adapters are\nconnected to other infrastructure. For instance, notifications are forwarded to third party\nnotification systems, possibly sending text messages or emails to users, or simply\nupdating their web-page through websockets.</p>\n<p>The key point here is horizontal scaling and redundancy at those levels:</p>\n<ul>\n<li>Several instances of the Cryptomate engine can coexist and share external services.</li>\n<li>Several instances of the market service can coexist, possibly fetching duplicate data to\nallow for overlap during an upgrade.</li>\n<li>Distributed strategy persistence servers allows recovering strategies in case a\nCryptomate node goes down.</li>\n</ul>\n<p>Note that Cryptomate itself does not cover service supervision. Still, it must be\nsupervisable, so we will be mindful of how it can be run under standard supervision.</p>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>This concludes our upfront architecture series. We will do a short recap in the\n<a href=\"the-story-so-far\" class=\"internal\">next post</a>.</p>","fields":{"isPage":false,"slug":"/2018/cryptomate/critical-points"},"frontmatter":{"title":"Critical Points","classname":null,"date":"2018-09-09T00:00:00.000Z","formattedDate":"September 09, 2018","isoDate":"2018-09-09T00:00:00+00:00"},"headings":[{"value":"Component relations","depth":1},{"value":"Market – strategy","depth":2},{"value":"Trading – strategy","depth":2},{"value":"Strategy life-cycle","depth":2},{"value":"Composition roots","depth":1},{"value":"Custom use as API","depth":2},{"value":"Integrated service","depth":2},{"value":"Split market recorder","depth":2},{"value":"Full cluster deployment","depth":2},{"value":"Conclusion","depth":1}],"image":null,"series":{"name":"cryptomate","fullName":null,"fields":{"slug":"/cryptomate"}},"tags":[{"name":"architecture","slug":"/tag/architecture"}]}},"pageContext":{"series":"cryptomate","slug":"/2018/cryptomate/critical-points","previous":{"fields":{"slug":"/2018/cryptomate/exploring-patterns"},"frontmatter":{"title":"Exploring Patterns","series":"cryptomate"},"tags":[{"name":"architecture","slug":"/tag/architecture"},{"name":"pattern","slug":"/tag/pattern"}]},"next":{"fields":{"slug":"/2018/cryptomate/the-story-so-far"},"frontmatter":{"title":"The Story So Far","series":"cryptomate"},"tags":[{"name":"architecture","slug":"/tag/architecture"}]},"seriesPrevious":{"fields":{"slug":"/2018/cryptomate/exploring-patterns"},"frontmatter":{"title":"Exploring Patterns","series":"cryptomate"},"tags":[{"name":"architecture","slug":"/tag/architecture"},{"name":"pattern","slug":"/tag/pattern"}]},"seriesNext":{"fields":{"slug":"/2018/cryptomate/the-story-so-far"},"frontmatter":{"title":"The Story So Far","series":"cryptomate"},"tags":[{"name":"architecture","slug":"/tag/architecture"}]}}},
    "staticQueryHashes": ["1733002695","4006707078"]}