Skip to content

Commit

Permalink
Merge pull request #22 from Leasehold/feature/exchange_value_estimation
Browse files Browse the repository at this point in the history
Exchange Estimation
  • Loading branch information
jondubois authored May 15, 2020
2 parents 4ade16c + a39fc77 commit 55593bc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 37 deletions.
37 changes: 24 additions & 13 deletions lisk-dex-electron/src/PlaceOrder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import * as transactions from '@liskhq/lisk-transactions';
import axios from 'axios';
import BalanceDisplay from './BalanceDisplay';
import userContext from './context';
import { getCleanOrderBook, estimateBestReturnsForSeller, estimatedBestReturnsForBuyer } from './Utils';
import {
getCleanOrderBook, estimateBestReturnsForSeller, estimatedBestReturnsForBuyer, EstimationStatus,
} from './Utils';

export default class PlaceOrder extends React.Component {
static contextType = userContext;
Expand Down Expand Up @@ -43,19 +45,33 @@ export default class PlaceOrder extends React.Component {
const { asks } = orderBook;
const { bids } = orderBook;
let estimatedReturns = { };
let assetType = '';

let assetExchanged = '';
let assetExchangedAgainst = '';
const { price } = this.state;
const isMarketOrder = this.getOrderType() === 'market';

if (this.props.side === 'ask') {
estimatedReturns = estimateBestReturnsForSeller(amount, price, bids, isMarketOrder);
assetType = this.context.activeAssets[1].toUpperCase();
assetExchanged = this.context.activeAssets[1].toUpperCase();
assetExchangedAgainst = this.context.activeAssets[0].toUpperCase();
} else {
estimatedReturns = estimatedBestReturnsForBuyer(amount, price, asks, isMarketOrder);
assetType = this.context.activeAssets[0].toUpperCase();
assetExchanged = this.context.activeAssets[0].toUpperCase();
assetExchangedAgainst = this.context.activeAssets[1].toUpperCase();
}
return { ...estimatedReturns, assetExchanged, assetExchangedAgainst };
}

getEstimatedReturnsBreakDown(estimate) {
let verboseEstimation = `${estimate.estimatedReturns.toFixed(4)} ${estimate.assetExchanged}`;
if (estimate.status === EstimationStatus.PARTIAL_MATCH) {
verboseEstimation += ` + ${estimate.amountYetToBeSold.toFixed(4)} ${estimate.assetExchangedAgainst}`;
if (this.getOrderType() === 'market') {
verboseEstimation += ' (refund)';
} else {
verboseEstimation += ' (pending)';
}
}
return { ...estimatedReturns, assetType };
return verboseEstimation;
}

handleSubmit = (event) => {
Expand Down Expand Up @@ -297,12 +313,7 @@ export default class PlaceOrder extends React.Component {
(
<div style={{ color: 'grey', fontSize: '15px', marginBottom: '10px' }}>
{estimate.estimatedReturns.toFixed(4)}
{' '}
{estimate.assetType}
{' ('}
{estimate.status.replace('_', ' ')}
{')'}
{this.getEstimatedReturnsBreakDown(estimate)}
</div>
)
}
Expand Down
6 changes: 4 additions & 2 deletions lisk-dex-electron/src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const estimateBestReturnsForSeller = (amount, price, bids, isMarketOrder) => {
const bestBidReturns = amountYetToBeSold * bid.price;
if (bid.amount >= bestBidReturns) {
estimatedReturns += bestBidReturns;
amountYetToBeSold = 0;
status = EstimationStatus.MATCH;
break;
} else {
Expand All @@ -79,7 +80,7 @@ const estimateBestReturnsForSeller = (amount, price, bids, isMarketOrder) => {
}
}
}
return { estimatedReturns, status };
return { amountYetToBeSold, estimatedReturns, status };
};

const estimatedBestReturnsForBuyer = (amount, price, asks, isMarketOrder) => {
Expand All @@ -100,6 +101,7 @@ const estimatedBestReturnsForBuyer = (amount, price, asks, isMarketOrder) => {
const bestAskReturns = amountYetToBeSold / ask.price;
if (ask.amount >= bestAskReturns) {
estimatedReturns += bestAskReturns;
amountYetToBeSold = 0;
status = EstimationStatus.MATCH;
break;
} else {
Expand All @@ -110,7 +112,7 @@ const estimatedBestReturnsForBuyer = (amount, price, asks, isMarketOrder) => {
}
}
}
return { estimatedReturns, status };
return { amountYetToBeSold, estimatedReturns, status };
};

// todo - reuse the function in orderbook.js, make sure calculations are in one place
Expand Down
46 changes: 24 additions & 22 deletions lisk-dex-electron/src/tests/Utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,41 +41,43 @@ describe('Utils tests => ', () => {
});

test.each`
sellerAmountInLshForSell | marketPriceInLsk | estimatedReturnsInLsk | buyerOrders | estimatedStatus
${150} | ${0.78} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH}
${160} | ${0.40} | ${94.5792} | ${bids} | ${EstimationStatus.MATCH}
${142} | ${0.48} | ${85.2} | ${bids} | ${EstimationStatus.MATCH}
${739.130434783} | ${0.23} | ${178.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH}
${947.368421053} | ${0.19} | ${188.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH}
${818.181818182} | ${0.22} | ${178.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH}
${327.868852459} | ${0.61} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH}
${457.142857143} | ${0.35} | ${154.4369} | ${bids} | ${EstimationStatus.PARTIAL_MATCH}
${1495.0166113} | ${0.602} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH}
sellerAmountInLshForSell | marketPriceInLsk | estimatedReturnsInLsk | buyerOrders | estimatedStatus | amountYetToBeSold
${150} | ${0.78} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH} | ${150}
${160} | ${0.40} | ${94.5792} | ${bids} | ${EstimationStatus.MATCH} | ${0}
${142} | ${0.48} | ${85.2} | ${bids} | ${EstimationStatus.MATCH} | ${0}
${739.130434783} | ${0.23} | ${178.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH} | ${340.25151811633344}
${947.368421053} | ${0.19} | ${188.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH} | ${498.48950438633346}
${818.181818182} | ${0.22} | ${178.2073} | ${bids} | ${EstimationStatus.PARTIAL_MATCH} | ${419.3029015153333}
${327.868852459} | ${0.61} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH} | ${327.868852459}
${457.142857143} | ${0.35} | ${154.4369} | ${bids} | ${EstimationStatus.PARTIAL_MATCH} | ${147.49860714300002}
${1495.0166113} | ${0.602} | ${0} | ${bids} | ${EstimationStatus.NO_MATCH} | ${1495.0166113}
`('Should estimate best returns for {$sellerAmountInLshForSell} LSH based on {$marketPriceInLsk} LSK/LSH', ({
buyerOrders, sellerAmountInLshForSell, marketPriceInLsk, estimatedReturnsInLsk, estimatedStatus,
buyerOrders, sellerAmountInLshForSell, marketPriceInLsk, estimatedReturnsInLsk, estimatedStatus, amountYetToBeSold,
}) => {
const actualEstimatedReturnsInLsk = estimateBestReturnsForSeller(sellerAmountInLshForSell, marketPriceInLsk, buyerOrders);
expect(actualEstimatedReturnsInLsk.estimatedReturns.toFixed(4)).toBe(estimatedReturnsInLsk.toFixed(4));
expect(actualEstimatedReturnsInLsk.status).toBe(estimatedStatus);
expect(actualEstimatedReturnsInLsk.amountYetToBeSold).toBe(amountYetToBeSold);
});

test.each`
buyerAmountInLskForSell | marketPriceInLsk | estimatedLshCanBeBought | sellerOrders | estimatedStatus
${2000} | ${0.77} | ${3.1169} | ${asks} | ${EstimationStatus.PARTIAL_MATCH}
${2793.6} | ${0.96} | ${2997.1761} | ${asks} | ${EstimationStatus.MATCH}
${2821.5} | ${0.95} | ${2999.7445} | ${asks} | ${EstimationStatus.PARTIAL_MATCH}
${2845.25} | ${0.95} | ${2999.7445} | ${asks} | ${EstimationStatus.PARTIAL_MATCH}
${63.36} | ${0.88} | ${74.1392} | ${asks} | ${EstimationStatus.MATCH}
${79.2} | ${0.88} | ${86.3001} | ${asks} | ${EstimationStatus.PARTIAL_MATCH}
${76.244} | ${0.76} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH}
${78} | ${0.56} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH}
${974.86} | ${0.20} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH}
buyerAmountInLskForSell | marketPriceInLsk | estimatedLshCanBeBought | sellerOrders | estimatedStatus | amountYetToBeSold
${2000} | ${0.77} | ${3.1169} | ${asks} | ${EstimationStatus.PARTIAL_MATCH} | ${1997.599987}
${2793.6} | ${0.96} | ${2997.1761} | ${asks} | ${EstimationStatus.MATCH} | ${0}
${2821.5} | ${0.95} | ${2999.7445} | ${asks} | ${EstimationStatus.PARTIAL_MATCH} | ${25.46005500000001}
${2845.25} | ${0.95} | ${2999.7445} | ${asks} | ${EstimationStatus.PARTIAL_MATCH} | ${49.21005500000001}
${63.36} | ${0.88} | ${74.1392} | ${asks} | ${EstimationStatus.MATCH} | ${0}
${79.2} | ${0.88} | ${86.3001} | ${asks} | ${EstimationStatus.PARTIAL_MATCH} | ${5.260015000000003}
${76.244} | ${0.76} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH} | ${76.244}
${78} | ${0.56} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH} | ${78}
${974.86} | ${0.20} | ${0} | ${asks} | ${EstimationStatus.NO_MATCH} | ${974.86}
`('Should estimate best returns for {$buyerAmountInLskForSell} LSK based on {$marketPriceInLsk} LSK/LSH', ({
sellerOrders, buyerAmountInLskForSell, marketPriceInLsk, estimatedLshCanBeBought, estimatedStatus,
sellerOrders, buyerAmountInLskForSell, marketPriceInLsk, estimatedLshCanBeBought, estimatedStatus, amountYetToBeSold,
}) => {
const actualLshCanBeBought = estimatedBestReturnsForBuyer(buyerAmountInLskForSell, marketPriceInLsk, sellerOrders);
expect(actualLshCanBeBought.estimatedReturns.toFixed(4)).toBe(estimatedLshCanBeBought.toFixed(4));
expect(actualLshCanBeBought.status).toBe(estimatedStatus);
expect(actualLshCanBeBought.amountYetToBeSold).toBe(amountYetToBeSold);
});

it('Should Return UI Orderbook from context orderbook', () => {
Expand Down

0 comments on commit 55593bc

Please sign in to comment.