{"action":"created","comment":{"url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/comments/46974080","id":46974080,"diff_hunk":"@@ -15,24 +15,208 @@ limitations under the License.\n */\n package markets.clearing.engines\n \n-import java.util.UUID\n-\n-import markets.clearing.strategies.BestLimitPriceFormationStrategy\n-import markets.orders.orderings.PriceOrdering\n+import markets.clearing.engines.matches.{Match, PartialMatch, TotalMatch}\n+import markets.orders.limit.{LimitBidOrder, LimitAskOrder, LimitOrderLike}\n+import markets.orders.market.{MarketOrderLike, MarketAskOrder, MarketBidOrder}\n import markets.orders.{AskOrder, BidOrder, Order}\n+import markets.orders.orderings.PriceOrdering\n+\n+import scala.annotation.tailrec\n+import scala.collection.{immutable, mutable}\n \n-import scala.collection.immutable\n \n+/** Continuous Double Auction (CDA) Matching Engine. */\n+class CDAMatchingEngine(askOrdering: PriceOrdering[AskOrder],\n+                        bidOrdering: PriceOrdering[BidOrder],\n+                        initialPrice: Long) extends MutableMatchingEngine {\n \n-class CDAMatchingEngine(val askOrdering: PriceOrdering[AskOrder],\n-                        val bidOrdering: PriceOrdering[BidOrder],\n-                        initialPrice: Long)\n-  extends CDAMatchingEngineLike\n-  with BestLimitPriceFormationStrategy {\n+  /* Mutable collection of ask orders for internal use only! */\n+  protected val _askOrderBook = mutable.TreeSet.empty[AskOrder](askOrdering)\n \n-  protected var orderBook = immutable.Set.empty[Order]\n+  /* Mutable collection of bid orders for internal use only! */\n+  protected val _bidOrderBook = mutable.TreeSet.empty[BidOrder](bidOrdering)\n \n-  protected var mostRecentPrice = initialPrice\n+  /* Cached value of most recent transaction price for internal use only. */\n+  private var _mostRecentPrice = initialPrice\n+\n+  protected def crosses(incomingOrder: Order, existingOrder: Order): Boolean = {\n+    (incomingOrder, existingOrder) match {\n+      case (ask: AskOrder, bid: BidOrder) => ask.price <= bid.price\n+      case (bid: BidOrder, ask: AskOrder) => bid.price >= ask.price\n+    }\n+  }\n+\n+  /** A sorted collection of ask orders.\n+    * @note This is an immutable view into a mutable private collection.\n+    */\n+  def askOrderBook: immutable.TreeSet[AskOrder] = {\n+    immutable.TreeSet.empty[AskOrder](askOrdering) ++ _askOrderBook\n+  }\n+\n+  /** A sorted collection of bid orders.\n+    * @note This is an immutable view into a mutable private collection.\n+    */\n+  def bidOrderBook: immutable.TreeSet[BidOrder] = {\n+    immutable.TreeSet.empty[BidOrder](bidOrdering) ++ _bidOrderBook\n+  }\n+\n+  def findMatch(incomingOrder: Order): Option[immutable.Iterable[Match]] = {\n+\n+    incomingOrder match {\n+      case order: AskOrder =>\n+        val matches = findMatchingBidOrders(order, immutable.Queue.empty[Match])\n+        if (matches.isEmpty) None else Some(matches)\n+      case order: BidOrder =>\n+        val matches = findMatchingAskOrders(order, immutable.Queue.empty[Match])\n+        if (matches.isEmpty) None else Some(matches)\n+    }\n+\n+  }\n+\n+  @tailrec\n+  private def findMatchingAskOrders(incoming: BidOrder,\n+                                    matches: immutable.Queue[Match]): immutable.Queue[Match] = {\n+    _askOrderBook.headOption match {\n+      case Some(askOrder) if crosses(incoming, askOrder) =>\n+\n+        _askOrderBook -= askOrder  // SIDE EFFECT!\n+        val residualQuantity = incoming.quantity - askOrder.quantity\n+        val price = formPrice(incoming, askOrder)\n+\n+        if (residualQuantity < 0) {","path":"src/main/scala-2.11/markets/clearing/engines/CDAMatchingEngine.scala","position":84,"original_position":84,"commit_id":"f4f1a846a83b819e7eb34352c5791080546062bc","original_commit_id":"f4f1a846a83b819e7eb34352c5791080546062bc","user":{"login":"davidrpugh","id":2219562,"avatar_url":"https://avatars.githubusercontent.com/u/2219562?v=3","gravatar_id":"","url":"https://api.github.com/users/davidrpugh","html_url":"https://github.com/davidrpugh","followers_url":"https://api.github.com/users/davidrpugh/followers","following_url":"https://api.github.com/users/davidrpugh/following{/other_user}","gists_url":"https://api.github.com/users/davidrpugh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidrpugh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidrpugh/subscriptions","organizations_url":"https://api.github.com/users/davidrpugh/orgs","repos_url":"https://api.github.com/users/davidrpugh/repos","events_url":"https://api.github.com/users/davidrpugh/events{/privacy}","received_events_url":"https://api.github.com/users/davidrpugh/received_events","type":"User","site_admin":false},"body":"![Codacy](https://www.codacy.com/versioned/images/favicon.png) Issue found: [Consider using case matching instead of else if blocks](https://www.codacy.com/app/davidrpugh/markets-sandbox/file/1519375750/issues/source?bid=2921361&fileBranchId=3008855#l86)","created_at":"2015-12-08T16:16:14Z","updated_at":"2015-12-08T16:16:14Z","html_url":"https://github.com/ScalABM/markets-sandbox/pull/91#discussion_r46974080","pull_request_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91","_links":{"self":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/comments/46974080"},"html":{"href":"https://github.com/ScalABM/markets-sandbox/pull/91#discussion_r46974080"},"pull_request":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91"}}},"pull_request":{"url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91","id":52986921,"html_url":"https://github.com/ScalABM/markets-sandbox/pull/91","diff_url":"https://github.com/ScalABM/markets-sandbox/pull/91.diff","patch_url":"https://github.com/ScalABM/markets-sandbox/pull/91.patch","issue_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/91","number":91,"state":"open","locked":false,"title":"Refactor matching engine","user":{"login":"davidrpugh","id":2219562,"avatar_url":"https://avatars.githubusercontent.com/u/2219562?v=3","gravatar_id":"","url":"https://api.github.com/users/davidrpugh","html_url":"https://github.com/davidrpugh","followers_url":"https://api.github.com/users/davidrpugh/followers","following_url":"https://api.github.com/users/davidrpugh/following{/other_user}","gists_url":"https://api.github.com/users/davidrpugh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidrpugh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidrpugh/subscriptions","organizations_url":"https://api.github.com/users/davidrpugh/orgs","repos_url":"https://api.github.com/users/davidrpugh/repos","events_url":"https://api.github.com/users/davidrpugh/events{/privacy}","received_events_url":"https://api.github.com/users/davidrpugh/received_events","type":"User","site_admin":false},"body":"PR refactors matching engines...","created_at":"2015-12-08T14:29:25Z","updated_at":"2015-12-08T16:16:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4b6eb004a66fb66a35b0c99c6b70d995ab2d02fc","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91/commits","review_comments_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91/comments","review_comment_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/91/comments","statuses_url":"https://api.github.com/repos/ScalABM/markets-sandbox/statuses/f4f1a846a83b819e7eb34352c5791080546062bc","head":{"label":"ScalABM:refactor-matching-engine","ref":"refactor-matching-engine","sha":"f4f1a846a83b819e7eb34352c5791080546062bc","user":{"login":"ScalABM","id":12729421,"avatar_url":"https://avatars.githubusercontent.com/u/12729421?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalABM","html_url":"https://github.com/ScalABM","followers_url":"https://api.github.com/users/ScalABM/followers","following_url":"https://api.github.com/users/ScalABM/following{/other_user}","gists_url":"https://api.github.com/users/ScalABM/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalABM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalABM/subscriptions","organizations_url":"https://api.github.com/users/ScalABM/orgs","repos_url":"https://api.github.com/users/ScalABM/repos","events_url":"https://api.github.com/users/ScalABM/events{/privacy}","received_events_url":"https://api.github.com/users/ScalABM/received_events","type":"Organization","site_admin":false},"repo":{"id":44811632,"name":"markets-sandbox","full_name":"ScalABM/markets-sandbox","owner":{"login":"ScalABM","id":12729421,"avatar_url":"https://avatars.githubusercontent.com/u/12729421?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalABM","html_url":"https://github.com/ScalABM","followers_url":"https://api.github.com/users/ScalABM/followers","following_url":"https://api.github.com/users/ScalABM/following{/other_user}","gists_url":"https://api.github.com/users/ScalABM/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalABM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalABM/subscriptions","organizations_url":"https://api.github.com/users/ScalABM/orgs","repos_url":"https://api.github.com/users/ScalABM/repos","events_url":"https://api.github.com/users/ScalABM/events{/privacy}","received_events_url":"https://api.github.com/users/ScalABM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ScalABM/markets-sandbox","description":"A sandbox for building and testing scalable implementations of various market micro-structures.","fork":false,"url":"https://api.github.com/repos/ScalABM/markets-sandbox","forks_url":"https://api.github.com/repos/ScalABM/markets-sandbox/forks","keys_url":"https://api.github.com/repos/ScalABM/markets-sandbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ScalABM/markets-sandbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ScalABM/markets-sandbox/teams","hooks_url":"https://api.github.com/repos/ScalABM/markets-sandbox/hooks","issue_events_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/events{/number}","events_url":"https://api.github.com/repos/ScalABM/markets-sandbox/events","assignees_url":"https://api.github.com/repos/ScalABM/markets-sandbox/assignees{/user}","branches_url":"https://api.github.com/repos/ScalABM/markets-sandbox/branches{/branch}","tags_url":"https://api.github.com/repos/ScalABM/markets-sandbox/tags","blobs_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ScalABM/markets-sandbox/statuses/{sha}","languages_url":"https://api.github.com/repos/ScalABM/markets-sandbox/languages","stargazers_url":"https://api.github.com/repos/ScalABM/markets-sandbox/stargazers","contributors_url":"https://api.github.com/repos/ScalABM/markets-sandbox/contributors","subscribers_url":"https://api.github.com/repos/ScalABM/markets-sandbox/subscribers","subscription_url":"https://api.github.com/repos/ScalABM/markets-sandbox/subscription","commits_url":"https://api.github.com/repos/ScalABM/markets-sandbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/ScalABM/markets-sandbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/ScalABM/markets-sandbox/contents/{+path}","compare_url":"https://api.github.com/repos/ScalABM/markets-sandbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ScalABM/markets-sandbox/merges","archive_url":"https://api.github.com/repos/ScalABM/markets-sandbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ScalABM/markets-sandbox/downloads","issues_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues{/number}","pulls_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls{/number}","milestones_url":"https://api.github.com/repos/ScalABM/markets-sandbox/milestones{/number}","notifications_url":"https://api.github.com/repos/ScalABM/markets-sandbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ScalABM/markets-sandbox/labels{/name}","releases_url":"https://api.github.com/repos/ScalABM/markets-sandbox/releases{/id}","created_at":"2015-10-23T12:25:31Z","updated_at":"2015-11-04T14:24:23Z","pushed_at":"2015-12-08T14:29:26Z","git_url":"git://github.com/ScalABM/markets-sandbox.git","ssh_url":"git@github.com:ScalABM/markets-sandbox.git","clone_url":"https://github.com/ScalABM/markets-sandbox.git","svn_url":"https://github.com/ScalABM/markets-sandbox","homepage":null,"size":453,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":15,"forks":1,"open_issues":15,"watchers":0,"default_branch":"master"}},"base":{"label":"ScalABM:develop","ref":"develop","sha":"90e70289b439e5a7446509aebe951bde9c5ccbd6","user":{"login":"ScalABM","id":12729421,"avatar_url":"https://avatars.githubusercontent.com/u/12729421?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalABM","html_url":"https://github.com/ScalABM","followers_url":"https://api.github.com/users/ScalABM/followers","following_url":"https://api.github.com/users/ScalABM/following{/other_user}","gists_url":"https://api.github.com/users/ScalABM/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalABM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalABM/subscriptions","organizations_url":"https://api.github.com/users/ScalABM/orgs","repos_url":"https://api.github.com/users/ScalABM/repos","events_url":"https://api.github.com/users/ScalABM/events{/privacy}","received_events_url":"https://api.github.com/users/ScalABM/received_events","type":"Organization","site_admin":false},"repo":{"id":44811632,"name":"markets-sandbox","full_name":"ScalABM/markets-sandbox","owner":{"login":"ScalABM","id":12729421,"avatar_url":"https://avatars.githubusercontent.com/u/12729421?v=3","gravatar_id":"","url":"https://api.github.com/users/ScalABM","html_url":"https://github.com/ScalABM","followers_url":"https://api.github.com/users/ScalABM/followers","following_url":"https://api.github.com/users/ScalABM/following{/other_user}","gists_url":"https://api.github.com/users/ScalABM/gists{/gist_id}","starred_url":"https://api.github.com/users/ScalABM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ScalABM/subscriptions","organizations_url":"https://api.github.com/users/ScalABM/orgs","repos_url":"https://api.github.com/users/ScalABM/repos","events_url":"https://api.github.com/users/ScalABM/events{/privacy}","received_events_url":"https://api.github.com/users/ScalABM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ScalABM/markets-sandbox","description":"A sandbox for building and testing scalable implementations of various market micro-structures.","fork":false,"url":"https://api.github.com/repos/ScalABM/markets-sandbox","forks_url":"https://api.github.com/repos/ScalABM/markets-sandbox/forks","keys_url":"https://api.github.com/repos/ScalABM/markets-sandbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ScalABM/markets-sandbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ScalABM/markets-sandbox/teams","hooks_url":"https://api.github.com/repos/ScalABM/markets-sandbox/hooks","issue_events_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/events{/number}","events_url":"https://api.github.com/repos/ScalABM/markets-sandbox/events","assignees_url":"https://api.github.com/repos/ScalABM/markets-sandbox/assignees{/user}","branches_url":"https://api.github.com/repos/ScalABM/markets-sandbox/branches{/branch}","tags_url":"https://api.github.com/repos/ScalABM/markets-sandbox/tags","blobs_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ScalABM/markets-sandbox/statuses/{sha}","languages_url":"https://api.github.com/repos/ScalABM/markets-sandbox/languages","stargazers_url":"https://api.github.com/repos/ScalABM/markets-sandbox/stargazers","contributors_url":"https://api.github.com/repos/ScalABM/markets-sandbox/contributors","subscribers_url":"https://api.github.com/repos/ScalABM/markets-sandbox/subscribers","subscription_url":"https://api.github.com/repos/ScalABM/markets-sandbox/subscription","commits_url":"https://api.github.com/repos/ScalABM/markets-sandbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/ScalABM/markets-sandbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/ScalABM/markets-sandbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/ScalABM/markets-sandbox/contents/{+path}","compare_url":"https://api.github.com/repos/ScalABM/markets-sandbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ScalABM/markets-sandbox/merges","archive_url":"https://api.github.com/repos/ScalABM/markets-sandbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ScalABM/markets-sandbox/downloads","issues_url":"https://api.github.com/repos/ScalABM/markets-sandbox/issues{/number}","pulls_url":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls{/number}","milestones_url":"https://api.github.com/repos/ScalABM/markets-sandbox/milestones{/number}","notifications_url":"https://api.github.com/repos/ScalABM/markets-sandbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ScalABM/markets-sandbox/labels{/name}","releases_url":"https://api.github.com/repos/ScalABM/markets-sandbox/releases{/id}","created_at":"2015-10-23T12:25:31Z","updated_at":"2015-11-04T14:24:23Z","pushed_at":"2015-12-08T14:29:26Z","git_url":"git://github.com/ScalABM/markets-sandbox.git","ssh_url":"git@github.com:ScalABM/markets-sandbox.git","clone_url":"https://github.com/ScalABM/markets-sandbox.git","svn_url":"https://github.com/ScalABM/markets-sandbox","homepage":null,"size":453,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":15,"forks":1,"open_issues":15,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91"},"html":{"href":"https://github.com/ScalABM/markets-sandbox/pull/91"},"issue":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/91"},"comments":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/issues/91/comments"},"review_comments":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91/comments"},"review_comment":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/pulls/91/commits"},"statuses":{"href":"https://api.github.com/repos/ScalABM/markets-sandbox/statuses/f4f1a846a83b819e7eb34352c5791080546062bc"}}}}