         (is (= expected actual)
             "The entity settings are updated with default account ids")))))
 
+(deftest sell-a-commodity-for-a-loss
+  (let [context (serialization/realize (env :db) sale-context)
+        commodity (find-commodity context "AAPL")
+        attr (assoc (sale-attributes context) :value 200M) ; 25 shares, $50 loss
+        {:keys [lots transaction price]} (trading/sell (env :db) attr)
+        ira (find-account context "IRA")
+        lot (lots/find-by (env :db) {:commodity-id (:id commodity)
+                                     :account-id (:id ira)
+                                     :purchase-date (t/local-date 2016 3 2)})]
+    (is (= 8M (:price price))
+        "The result contains the correct price")
+    (is (empty? (validation/error-messages price))
+        "The price is valid")
+    (is lots "The result contains the lots affected")
+    (doseq [lot lots]
+      (is (empty? (validation/error-messages lot))
+          "Each lot is valid"))
+    (is (= 75M (:shares-owned lot))
+        "The shares-owned value of the original lot is updated")
+    (is transaction "The result contains the transaction record")
+    (is (empty? (validation/error-messages transaction))
+        "The transaction is valid")
+    (if-let [item (->> (:items transaction)
+                (filter #(= (:lt-capital-loss-account-id attr)
+                           (:account-id %)))
+                first)]
+      (is (selective= {:action :debit
+                       :quantity 50M}
+                      item)
+          "The correct capital loss is recored")
+      (is false "A capital loss item is created"))))
+
 (deftest sell-a-commodity-with-a-fee
-  (let [context (sell-context)
+  (let [context (serialization/realize (env :db) sale-context)
         ira (find-account context "IRA")
         inv-exp (->> context
                      :accounts
                      (filter #(= "Investment Expenses" (:name %)))
-                     first)
-        result (trading/sell storage-spec
-                             (-> context
-                                 sale-attributes
-                                 (assoc :fee 5M
-                                        :fee-account-id (:id inv-exp))))]
-    (is (= 1370M (:quantity (accounts/reload storage-spec ira)))
+                     first)]
+    (trading/sell (env :db)
+                  (-> context
+                      sale-attributes
+                      (assoc :fee 5M
+                             :fee-account-id (:id inv-exp))))
+    (is (= 1370M (:quantity (accounts/reload (env :db) ira)))
         "The investment account balance reflects the fee")
-    (is (= 5M (:quantity (accounts/reload storage-spec inv-exp)))
+    (is (= 5M (:quantity (accounts/reload (env :db) inv-exp)))
         "The investment fee account balance reflects the fee")))
 
 (deftest sales-requires-a-trade-date
-  (let [context (sell-context)
-        result (trading/sell storage-spec (-> context
+  (let [context (serialization/realize (env :db) sale-context)
+        result (trading/sell (env :db) (-> context
                                               sale-attributes
                                               (dissoc :trade-date)))]
     (is (= ["Trade date is required"]

         ira-2-commodity-account] (->> [ira ira-2]
                                       (map :id)
                                       (map #(accounts/search
                                               storage-spec
                                               {:parent-id %
                                                :commodity-id (:id commodity)}))
                                       (map first))
        entity (find-entity context "Personal")
        actual-lots (map #(dissoc % :created-at :updated-at :id)
                         (lots/search storage-spec {:commodity-id (:id commodity)}))
        expected-lots [{:commodity-id (:id commodity)
                        :account-id (:id ira-2)
                        :shares-owned 100M

        "The correct validation error is present")))

(deftest selling-a-commodity-for-a-profit-increases-the-balance-of-the-account
  (let [context (serialization/realize (env :db) purchase-context)
        [ira] (:accounts context)
        commodity (find-commodity context "AAPL")
        _ (trading/buy (env :db) {:commodity-id (:id commodity)
                                     :account-id (:id ira)
                                     :trade-date (t/local-date 2016 1 2)
                                     :shares 100M
                                     :value 1000M})
        _ (trading/sell (env :db) (-> context
                                              sale-attributes
                                              (assoc :shares 50M :value 560M)))
        new-balance (:quantity (accounts/reload (env :db) ira))]
    (is (= 1560M new-balance) "The account balance decreases by the amount of the purchase")))

(deftest selling-a-commodity-updates-a-lot-record
  (let [context (serialization/realize (env :db) sale-context)
        ira (find-account context "IRA")
        commodity (find-commodity context "AAPL")
        _ (trading/sell (env :db) (-> context
                                         sale-attributes
                                         (assoc :shares 25M :value 375M)))
        lots (map #(dissoc % :id :created-at :updated-at)
                  (lots/search (env :db) {:account-id (:id ira)
                                             :commodity-id (:id commodity)}))
        expected [{:purchase-date (t/local-date 2016 3 2)
                   :account-id (:id ira)
