diff --git a/.eslintrc b/.eslintrc
index ec0d68b9b851aecd5fed5b8c2c7b6c87f52f46f9..15eefba00ead3e95099b0064fe507a5cdc2e93e8 100755
--- a/.eslintrc
+++ b/.eslintrc
@@ -4,6 +4,9 @@
     "browser": true,
     "jquery": true,
   },
+  "parserOptions": {
+    "sourceType": "module",
+  },
   "rules": {
     "no-await-in-loop": "warn",
     "no-compare-neg-zero": "warn",
diff --git a/js/buy.js b/js/buy.js
index 18f7ca64dd92ff27e80c7f7d347d68ef1bf98d67..d22dd937ceb42b5317ea84fc0c2bae19a9dc351f 100644
--- a/js/buy.js
+++ b/js/buy.js
@@ -1,5 +1,3 @@
-/* exported determineBuyPrice */
-
 function descendsThenAscends(prices) {
   let previous = Infinity;
   let recovering = false;
@@ -16,7 +14,7 @@ function descendsThenAscends(prices) {
   return true;
 }
 
-function determineBuyPrice(forecastPrices) {
+export function determineBuyPrice(forecastPrices) {
   console.assert(forecastPrices.length > 0, 'Tried to find a buy price with an empty forecast.');
   console.assert(descendsThenAscends(forecastPrices), 'Tried to find a buy price with a forecast that does something other than descend and then ascend.');
   if (forecastPrices.length === 1) {
diff --git a/js/buy_sell.js b/js/buy_sell.js
index 6934242fae42d35cf421914ae0826378ef78541c..0c9d3795eb3704fe50dbae08d58ed59fad6f4d1b 100644
--- a/js/buy_sell.js
+++ b/js/buy_sell.js
@@ -1,6 +1,4 @@
-/* exported BuySellPlan determineBuyAndSellPrices */
-
-class BuySellPlan {
+export class BuySellPlan {
   constructor(buyPrice, sellPrice, minimumPrice, maximumPrice) {
     this.buyPrice = buyPrice;
     this.sellPrice = sellPrice;
@@ -24,7 +22,7 @@ function combineBuySellPlans(firstPlan, secondPlan) {
   return result;
 }
 
-function determineBuyAndSellPrices(forecastPrices) {
+export function determineBuyAndSellPrices(forecastPrices) {
   console.assert(forecastPrices.length > 0, 'Tried to find buy and sell prices with an empty forecast.');
   if (forecastPrices.length === 1) {
     return new BuySellPlan(forecastPrices[0], forecastPrices[0], forecastPrices[0], forecastPrices[0]);
diff --git a/js/sell.js b/js/sell.js
index 03496b20506cb15af6928990b501b60682dd708a..7277c483acf53c874f166ccab7f3a3729f1687f2 100644
--- a/js/sell.js
+++ b/js/sell.js
@@ -1,6 +1,4 @@
-/* exported SellPlan determineSellChange */
-
-class SellPlan {
+export class SellPlan {
   constructor(sellChange, totalChange) {
     this.sellChange = sellChange;
     this.totalChange = totalChange;
@@ -14,7 +12,7 @@ function combineSellPlans(firstPlan, secondPlan) {
   );
 }
 
-function determineSellChange(forecastChanges) {
+export function determineSellChange(forecastChanges) {
   if (forecastChanges.length === 0) {
     return new SellPlan(0, 0);
   }
diff --git a/unit_tests/test_buy.js b/unit_tests/test_buy.js
index 3b9a1ecfc78ac8870d39efdefc9893e7c9a937f5..85eb689dec42793fcdf7c0af1a26809dbd31971d 100644
--- a/unit_tests/test_buy.js
+++ b/unit_tests/test_buy.js
@@ -1,5 +1,7 @@
-QUnit.module('buy.js');
-/* globals QUnit determineBuyPrice */
+import {determineBuyPrice} from '../js/buy.js';
+
+/* globals QUnit */
+QUnit.module('test_buy.js');
 /* eslint-disable no-magic-numbers */
 
 QUnit.test('find a buy price for a one-element forecast', (assert) => {
diff --git a/unit_tests/test_buy_sell.js b/unit_tests/test_buy_sell.js
index b07a249fa309d3edda75aa02c9de8b02f88a0b80..89e125166942aac7bdc63e0cc2741095a38ba295 100644
--- a/unit_tests/test_buy_sell.js
+++ b/unit_tests/test_buy_sell.js
@@ -1,5 +1,7 @@
-QUnit.module('buy_sell.js');
-/* globals QUnit BuySellPlan determineBuyAndSellPrices */
+import {BuySellPlan, determineBuyAndSellPrices} from '../js/buy_sell.js';
+
+/* globals QUnit */
+QUnit.module('test_buy_sell.js');
 /* eslint-disable no-magic-numbers */
 
 QUnit.test('find buy and sell prices for a one-element forecast', (assert) => {
@@ -42,6 +44,14 @@ QUnit.test('find buy and sell prices for a four-element invereted zig-zag foreca
   assert.deepEqual(determineBuyAndSellPrices([102, 103, 100, 101]), new BuySellPlan(102, 103, 100, 103));
 });
 
+QUnit.test('find buy and sell prices for a six-element leveling forecast', (assert) => {
+  assert.deepEqual(determineBuyAndSellPrices([101, 102, 100, 101, 101, 101]), new BuySellPlan(101, 102, 100, 102));
+});
+
+QUnit.test('find buy and sell prices for a six-element rotated leveling forecast', (assert) => {
+  assert.deepEqual(determineBuyAndSellPrices([101, 101, 101, 102, 100, 101]), new BuySellPlan(101, 102, 100, 102));
+});
+
 QUnit.test('find buy and sell prices for random forecast #0', (assert) => {
   assert.deepEqual(determineBuyAndSellPrices([900, 865, 691, 580, 967, 480, 740, 936, 153, 371, 606, 901]), new BuySellPlan(153, 901, 153, 967));
 });
diff --git a/unit_tests/test_sell.js b/unit_tests/test_sell.js
index 3094f4cf5711b26b10d26a3aea2bb74aac34bc9c..4b1eaa10f3849b3249de007989f2a24354509951 100644
--- a/unit_tests/test_sell.js
+++ b/unit_tests/test_sell.js
@@ -1,5 +1,7 @@
-QUnit.module('sell.js');
-/* globals QUnit SellPlan determineSellChange */
+import {SellPlan, determineSellChange} from '../js/sell.js';
+
+/* globals QUnit */
+QUnit.module('test_sell.js');
 /* eslint-disable no-magic-numbers */
 
 QUnit.test('find cumulative change at which to sell for a zero-element forecast', (assert) => {
diff --git a/unit_tests/unit_tests.html b/unit_tests/unit_tests.html
index e905e96c5164f76e852670f514b52eabf5f92b9c..271fc01db0ba4a5ce2208048e2d8ffe4d6453527 100644
--- a/unit_tests/unit_tests.html
+++ b/unit_tests/unit_tests.html
@@ -13,14 +13,9 @@
   <script src="../libraries/qunit/qunit.js"></script>
   <script src="overrides.js"></script>
 
-  <script src="../js/sell.js"></script>
-  <script src="test_sell.js"></script>
-
-  <script src="../js/buy_sell.js"></script>
-  <script src="test_buy_sell.js"></script>
-
-  <script src="../js/buy.js"></script>
-  <script src="test_buy.js"></script>
+  <script type="module" src="test_sell.js"></script>
+  <script type="module" src="test_buy_sell.js"></script>
+  <script type="module" src="test_buy.js"></script>
 </body>
 
 </html>