src/modules/markets/selectors/user-markets.js
import { createBigNumber } from "utils/create-big-number";
import { createSelector } from "reselect";
import memoize from "memoizee";
import store from "src/store";
import {
selectLoginAccountAddress,
selectPriceHistoryState,
selectMarketCreatorFeesState
} from "src/select-state";
import selectAllMarkets from "modules/markets/selectors/markets-all";
import { ZERO } from "modules/trades/constants/numbers";
import { formatNumber, formatEther } from "utils/format-number";
import { orderBy } from "lodash";
export default function() {
return selectLoginAccountMarkets(store.getState());
}
export const selectAuthorOwnedMarkets = createSelector(
selectAllMarkets,
selectLoginAccountAddress,
(allMarkets, authorId) => {
if (!allMarkets || !authorId) return null;
return allMarkets.filter(market => market.author === authorId);
}
);
export const selectLoginAccountMarkets = createSelector(
selectAuthorOwnedMarkets,
selectPriceHistoryState,
selectMarketCreatorFeesState,
(authorOwnedMarkets, priceHistory, marketCreatorFees) => {
if (!authorOwnedMarkets) return [];
const markets = [];
authorOwnedMarkets.forEach(market => {
const fees = formatEther(marketCreatorFees[market.id] || 0);
const numberOfTrades = formatNumber(
selectNumberOfTrades(priceHistory[market.id])
);
const averageTradeSize = formatNumber(
selectAverageTradeSize(priceHistory[market.id])
);
const openVolume = formatNumber(selectOpenVolume(market));
markets.push({
...market, // TODO -- cleanup this object
id: market.id,
description: market.description,
endTime: market.endTime,
volume: market.volume,
repBalance: market.repBalance,
fees,
numberOfTrades,
averageTradeSize,
openVolume
});
});
return orderBy(markets, ["endTime.timestamp"], ["desc"]);
}
);
export const selectNumberOfTrades = memoize(
trades => {
if (!trades) return 0;
return Object.keys(trades).reduce(
(p, outcome) => p + trades[outcome].length,
0
);
},
{ max: 1 }
);
export const selectOpenVolume = market => {
let openVolume = ZERO;
market.outcomes.forEach(outcome => {
Object.keys(outcome.orderBook).forEach(orderType => {
outcome.orderBook[orderType].forEach(type => {
openVolume = openVolume.plus(createBigNumber(type.shares.value, 10));
});
});
});
return openVolume;
};
export const selectAverageTradeSize = memoize(
marketPriceHistory => {
if (!marketPriceHistory) return 0;
const initialState = {
shares: ZERO,
trades: 0
};
const priceHistoryTotals = Object.keys(marketPriceHistory).reduce(
(historyTotals, currentOutcome) => {
const outcomeTotals = marketPriceHistory[currentOutcome].reduce(
(outcomeTotals, trade) => ({
shares: createBigNumber(outcomeTotals.shares, 10).plus(
createBigNumber(trade.amount, 10)
),
trades: outcomeTotals.trades + 1
}),
initialState
);
return {
shares: historyTotals.shares.plus(outcomeTotals.shares),
trades: historyTotals.trades + outcomeTotals.trades
};
},
initialState
);
return priceHistoryTotals.shares.dividedBy(
createBigNumber(priceHistoryTotals.trades, 10)
);
},
{ max: 1 }
);