Skip to content

Commit

Permalink
Adjust inference logic for two-digit expirations of futures (and opti…
Browse files Browse the repository at this point in the history
…ons)
  • Loading branch information
bryaningl3 committed May 24, 2022
1 parent 35feb21 commit f17431b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 9 deletions.
3 changes: 3 additions & 0 deletions docs/content/releases/5.19.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Breaking Changes**

* Adjusted the logic used by the `SymbolParser.parseInstrumentType` function to infer the expiration year of futures contracts and futures options based solely on a symbol (e.g. ZCZ19). In previous versions, given a two-digit number (e.g. 19), a year in the current century or the next century would be returned (e.g. 2019 or 2119). In this version, a 100-year window is used, interpreting a two-digit number as a year up to 25 years in the future, or alternatively up to 75 years in the past. Assuming the current year is 2022, the 100-year window will range from 1948 to 2047.
8 changes: 2 additions & 6 deletions lib/utilities/parsers/SymbolParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,8 @@ module.exports = (() => {
} else if (year < 100) {
year = Math.floor(currentYear / 100) * 100 + year;

if (year < currentYear) {
const alternateYear = year + 100;

if (currentYear - year > alternateYear - currentYear) {
year = alternateYear;
}
if (currentYear + 25 < year) {
year = year - 100;
}
}

Expand Down
89 changes: 86 additions & 3 deletions test/specs/utilities/parsers/SymbolParserSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,90 @@ describe('When parsing a symbol for instrument type', () => {
});
});

describe('When parsing a symbol for a futures contract', () => {
describe('and the year is 2022', () => {
let getFullYear;

beforeEach(() => {
getFullYear = Date.prototype.getFullYear;

Date.prototype.getFullYear = () => { return 2022; };
});

it('the expiration year of "ZCN19" should parse to 2019', () => {
expect(SymbolParser.parseInstrumentType('ZCN19').year).toEqual(2019);
});

it('the expiration year of "ZCN21" should parse to 2021', () => {
expect(SymbolParser.parseInstrumentType('ZCN21').year).toEqual(2021);
});

it('the expiration year of "ZCN22" should parse to 2022', () => {
expect(SymbolParser.parseInstrumentType('ZCN22').year).toEqual(2022);
});

it('the expiration year of "ZCN32" should parse to 2032', () => {
expect(SymbolParser.parseInstrumentType('ZCN32').year).toEqual(2032);
});

it('the expiration year of "ZCN42" should parse to 2042', () => {
expect(SymbolParser.parseInstrumentType('ZCN42').year).toEqual(2042);
});

it('the expiration year of "ZCN47" should parse to 2047', () => {
expect(SymbolParser.parseInstrumentType('ZCN47').year).toEqual(2047);
});

it('the expiration year of "ZCN48" should parse to 1948', () => {
expect(SymbolParser.parseInstrumentType('ZCN48').year).toEqual(1948);
});

it('the expiration year of "ZCN49" should parse to 1949', () => {
expect(SymbolParser.parseInstrumentType('ZCN49').year).toEqual(1949);
});

it('the expiration year of "ZCN99" should parse to 1999', () => {
expect(SymbolParser.parseInstrumentType('ZCM99').year).toEqual(1999);
});

afterEach(() => {
Date.prototype.getFullYear = getFullYear;
});
});
});

describe('When parsing a symbol for a futures option', () => {
describe('and the year is 2022', () => {
let getFullYear;

beforeEach(() => {
getFullYear = Date.prototype.getFullYear;

Date.prototype.getFullYear = () => { return 2022; };
});

it('the expiration year of "ZWK18465C" should parse to 2018', () => {
expect(SymbolParser.parseInstrumentType('ZWK18465C').year).toEqual(2018);
});

it('the expiration year of "ZWK22465C" should parse to 2022', () => {
expect(SymbolParser.parseInstrumentType('ZWK22465C').year).toEqual(2022);
});

it('the expiration year of "ZWK47465C" should parse to 2047', () => {
expect(SymbolParser.parseInstrumentType('ZWK47465C').year).toEqual(2047);
});

it('the expiration year of "ZWK48465C" should parse to 2048', () => {
expect(SymbolParser.parseInstrumentType('ZWK48465C').year).toEqual(1948);
});

afterEach(() => {
Date.prototype.getFullYear = getFullYear;
});
});
});

describe('When checking to see if a symbol is a future', () => {
it('the symbol "ES*1" should return true', () => {
expect(SymbolParser.getIsFuture('ES*1')).toEqual(true);
Expand Down Expand Up @@ -1332,7 +1416,6 @@ describe('When checking to see if a symbol is forex', () => {
});
});


describe('When checking to see if a symbol is crypto', () => {
it('the symbol "ES*1" should return false', () => {
expect(SymbolParser.getIsCrypto('ES*1')).toEqual(false);
Expand Down Expand Up @@ -1479,7 +1562,7 @@ describe('When checking to see if a symbol is crypto', () => {
});
});

describe('When checking to see if a symbol is a future spread', () => {
describe('When checking to see if a symbol is a futures spread', () => {
it('the symbol "ES*1" should return false', () => {
expect(SymbolParser.getIsFutureSpread('ES*1')).toEqual(false);
});
Expand Down Expand Up @@ -1625,7 +1708,7 @@ describe('When checking to see if a symbol is a future spread', () => {
});
});

describe('When checking to see if a symbol is a future option', () => {
describe('When checking to see if a symbol is a futures option', () => {
it('the symbol "ES*1" should return false', () => {
expect(SymbolParser.getIsFutureOption('ES*1')).toEqual(false);
});
Expand Down

0 comments on commit f17431b

Please sign in to comment.