Skip to content

Commit

Permalink
Add ValuationCalcultor utility, update PositionItem to use ValuationC…
Browse files Browse the repository at this point in the history
…alculator.
  • Loading branch information
bryaningl3 committed Aug 31, 2023
1 parent 8853d73 commit 208c480
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 81 deletions.
84 changes: 84 additions & 0 deletions lib/calculators/ValuationCalculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const Decimal = require('@barchart/common-js/lang/Decimal'),
is = require('@barchart/common-js/lang/is');

const InstrumentType = require('./../data/InstrumentType');

module.exports = (() => {
'use strict';

class ValuationCalculator {
constructor() {

}

static calculate(instrument, price, quantity) {
let priceToUse = null;

if (is.number(price)) {
priceToUse = new Decimal(price);
} else if (price instanceof Decimal) {
priceToUse = price;
}

if (priceToUse === null) {
return null;
}

const calculator = calculators.get(instrument.type);

return calculator(instrument, priceToUse, quantity);
}

toString() {
return `[ValuationCalculator]`;
}
}

function calculateForCash(instrument, price, quantity) {
return new Decimal(quantity);
}

function calculateForEquity(instrument, price, quantity) {
return price.multiply(quantity);
}

function calculateForEquityOption(instrument, price, quantity) {
const priceMultiplier = instrument.option.multiplier;

return price.multiply(priceMultiplier).multiply(quantity);
}

function calculateForFund(instrument, price, quantity) {
return price.multiply(quantity);
}

function calculateForFuture(instrument, price, quantity) {
const minimumTick = instrument.future.tick;
const minimumTickValue = instrument.future.value;

return price.divide(minimumTick).multiply(minimumTickValue).multiply(quantity);
}

function calculateForFutureOption(instrument, price, quantity) {
const minimumTick = instrument.option.tick;
const minimumTickValue = instrument.option.value;

return price.divide(minimumTick).multiply(minimumTickValue).multiply(quantity);
}

function calculateForOther(instrument, price, quantity) {
return price.multiply(quantity);
}

const calculators = new Map();

calculators.set(InstrumentType.CASH, calculateForCash);
calculators.set(InstrumentType.EQUITY, calculateForEquity);
calculators.set(InstrumentType.EQUITY_OPTION, calculateForEquityOption);
calculators.set(InstrumentType.FUND, calculateForFund);
calculators.set(InstrumentType.FUTURE, calculateForFuture);
calculators.set(InstrumentType.FUTURE_OPTION, calculateForFutureOption);
calculators.set(InstrumentType.OTHER, calculateForOther);

return ValuationCalculator;
})();
87 changes: 6 additions & 81 deletions lib/processing/PositionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const assert = require('@barchart/common-js/lang/assert'),
const InstrumentType = require('./../data/InstrumentType'),
PositionDirection = require('./../data/PositionDirection');

const ValuationCalculator = require('./../calculators/ValuationCalculator');

module.exports = (() => {
'use strict';

Expand Down Expand Up @@ -514,18 +516,8 @@ module.exports = (() => {
market = snapshot.value;
} else if (position.instrument.type === InstrumentType.CASH) {
market = snapshot.open;
} else if (position.instrument.type === InstrumentType.FUTURE) {
market = getFuturesValue(position.instrument, snapshot.open, price) || snapshot.value;
} else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
market = getFuturesOptionValue(position.instrument, snapshot.open, price) || snapshot.value;
} else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
market = getEquityOptionValue(position.instrument, snapshot.open, price) || snapshot.value;
} else {
if (price) {
market = snapshot.open.multiply(price);
} else {
market = snapshot.value;
}
market = ValuationCalculator.calculate(position.instrument, price, snapshot.open) || snapshot.value;
}

let marketChange;
Expand Down Expand Up @@ -555,17 +547,7 @@ module.exports = (() => {
let unrealizedTodayChange;

if (data.previousPrice && price) {
let unrealizedTodayBase;

if (position.instrument.type === InstrumentType.FUTURE) {
unrealizedTodayBase = getFuturesValue(position.instrument, snapshot.open, data.previousPrice);
} else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
unrealizedTodayBase = getFuturesOptionValue(position.instrument, snapshot.open, data.previousPrice);
} else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
unrealizedTodayBase = getEquityOptionValue(position.instrument, snapshot.open, data.previousPrice);
} else {
unrealizedTodayBase = snapshot.open.multiply(data.previousPrice);
}
const unrealizedTodayBase = ValuationCalculator.calculate(position.instrument, data.previousPrice, snapshot.open);

unrealizedToday = market.subtract(unrealizedTodayBase);

Expand Down Expand Up @@ -599,17 +581,7 @@ module.exports = (() => {
}

if (priceToUse !== null) {
let unrealized;

if (position.instrument.type === InstrumentType.FUTURE) {
unrealized = getFuturesValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
} else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
unrealized = getFuturesOptionValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
} else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
unrealized = getEquityOptionValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
} else {
unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
}
const unrealized = ValuationCalculator.calculate(position.instrument, priceToUse, currentSummary.end.open).add(currentSummary.end.basis);

let unrealizedChange;

Expand Down Expand Up @@ -694,15 +666,7 @@ module.exports = (() => {
let endValue;

if (overridePrice) {
if (type === InstrumentType.FUTURE) {
endValue = getFuturesValue(instrument, currentSummary.end.open, overridePrice);
} else if (type === InstrumentType.FUTURE_OPTION) {
endValue = getFuturesOptionValue(instrument, currentSummary.end.open, overridePrice);
} else if (type === InstrumentType.EQUITY_OPTION) {
endValue = getEquityOptionValue(instrument, currentSummary.end.open, overridePrice);
} else {
endValue = currentSummary.end.open.multiply(overridePrice);
}
endValue = ValuationCalculator.calculate(instrument, overridePrice, currentSummary.end.open);
} else {
endValue = currentSummary.end.value;
}
Expand Down Expand Up @@ -823,44 +787,5 @@ module.exports = (() => {
return snapshot;
}

function getFuturesValue(instrument, contracts, price) {
if (price || price === 0) {
const priceDecimal = new Decimal(price);

const minimumTick = instrument.future.tick;
const minimumTickValue = instrument.future.value;

return priceDecimal.divide(minimumTick).multiply(minimumTickValue).multiply(contracts);
} else {
return null;
}
}

function getFuturesOptionValue(instrument, contracts, price) {
if (price || price === 0) {
const priceDecimal = new Decimal(price);

const minimumTick = instrument.option.tick;
const minimumTickValue = instrument.option.value;

const multiplier = instrument.option.multiplier;

return priceDecimal.divide(minimumTick).multiply(minimumTickValue).multiply(multiplier).multiply(contracts);
} else {
return null;
}
}

function getEquityOptionValue(instrument, contracts, price) {
if (price || price === 0) {
const priceDecimal = new Decimal(price);
const multiplier = instrument.option.multiplier;

return priceDecimal.multiply(contracts).multiply(multiplier);
} else {
return null;
}
}

return PositionItem;
})();
Loading

0 comments on commit 208c480

Please sign in to comment.