Resolve double auction orders
Formatting

It's common to see let-bindings vertically aligned, one per line. You've done that further down in resolve-auction, but even with just two name-value pairs it can be easier to see the logical parts vertically. The closing brackets (any kind) are also usually on the last line of the form, as opposed to indented back out. So

(defn as-trade-result 
  [ask bid]
  (let [bid-price (:price bid) ask-price (:price ask)]
    {:traded (&lt;= ask-price bid-price) :bid bid :ask ask}
    )
)


would more idiomatically be formatted as

(defn as-trade-result
  [ask bid]
  (let [bid-price (:price bid)
        ask-price (:price ask)]
    {:traded (&lt;= ask-price bid-price)
     :ask ask
     :bid bid}))


Semantic indentation

Also, the indentation here with (first (partition-by ending the line:

(let [best-asks (sort-by :price asks) 
      best-bids (reverse (sort-by :price bids))
      succesful-trades (first (partition-by 
          :traded 
          (map as-trade-result
               best-asks 
               best-bids)))


would more commonly be written in a way that reads left-to-right, top-to-bottom, in terms of expressions. Here are some examples:

(let [best-asks (sort-by :price asks)
      best-bids (sort-by (comp - :price) bids) ; negated :price gives you (reverse) in a single pass
      successful-trades
      (first
        (partition-by :traded (map as-trade-result best-asks best-bids)))]

      ; or

      successful-trades
      (-&gt;&gt; (map as-trade-result best-asks best-bids)
           (partition-by :traded)
           first)


The point here is that the indentation is not just a continuation, but actually shows the code structure. Something in the (bottom) right is expected to flow towards the (top) left.

When you get used to this it makes reading code much faster because it's easy to see what is dependent on what, structure-wise.

Side note: since you only want the first group the partition-by is overkill. Consider take-while:

      successful-trades
      (-&gt;&gt; (map as-trade-result best-asks best-bids)
           (take-while :traded))




Expose more of the data

There is a balance here between encapsulating complex logic and making things clear. Someone familiar with Clojure knows instantly what assoc, merge, and so on mean. It's less clear exactly what a trade-price-tagger does until one looks it up. For relatively simple cases like that, using an inline function is idiomatic and arguably more clear. Compare:

(defn trade-price-tagger
  [price]
    (fn [trade] (merge trade {:price price}))
  )
...
(map (trade-price-tagger breakeven-price) succesful-trades)


with

(map #(assoc % :price breakeven-price) succesful-trades)


Similarly, accessors like

(defn bid-price
  [trade]
  (-&gt; trade :bid :price))

(bid-price breakeven-successful-trade)


can be useful for deep objects or large programs, but in something short like this (get-in) could be fine:

(get-in breakeven-successful-trade [:bid :price])




In general I think this is readable and reasonably structured. Nice work as someone new to Clojure/Lisp!

My only other suggestion would be potentially to split up resolve-auction. The first half could be a function (defn get-successful-trades [asks bids]), and resolve-auction could just do the tagging of the breakeven point.