@@ -2449,6 +2449,8 @@ module.exports = (() => {
24492449 types.futures.options.short = /^([A-Z][A-Z0-9\$\-!\.]?)([A-Z])([0-9]{1,4})([A-Z])$/i;
24502450 types.futures.options.long = /^([A-Z][A-Z0-9\$\-!\.]{0,2})([A-Z])([0-9]{1,4})\|(\-?[0-9]{1,5})(C|P)$/i;
24512451 types.futures.options.historical = /^([A-Z][A-Z0-9\$\-!\.]{0,2})([A-Z])([0-9]{2})([0-9]{1,5})(C|P)$/i;
2452+ types.equities = {};
2453+ types.equities.options = /^([A-Z\$][A-Z\.\-]{0,})([0-9]?)\|([[0-9]{4})([[0-9]{2})([[0-9]{2})\|([0-9]+\.[0-9]+)[P|W]?(C|P)/i;
24522454 types.indicies = {};
24532455 types.indicies.external = /^\$(.*)$/i;
24542456 types.indicies.sector = /^\-(.*)$/i;
@@ -2507,6 +2509,25 @@ module.exports = (() => {
25072509
25082510 return definition;
25092511 });
2512+ parsers.push(symbol => {
2513+ let definition = null;
2514+ const match = symbol.match(types.equities.options);
2515+
2516+ if (match !== null) {
2517+ definition = {};
2518+ definition.symbol = symbol;
2519+ definition.type = 'equity_option';
2520+ definition.option_type = match[7] === 'C' ? 'call' : 'put';
2521+ definition.strike = parseFloat(match[6]);
2522+ definition.root = match[1];
2523+ definition.month = parseInt(match[4]);
2524+ definition.day = parseInt(match[5]);
2525+ definition.year = parseInt(match[3]);
2526+ definition.adjusted = match[2] !== '';
2527+ }
2528+
2529+ return definition;
2530+ });
25102531 parsers.push(symbol => {
25112532 let definition = null;
25122533
@@ -2877,6 +2898,20 @@ module.exports = (() => {
28772898 static getIsBats(symbol) {
28782899 return is.string(symbol) && predicates.bats.test(symbol);
28792900 }
2901+ /**
2902+ * Returns true if the symbol represents an option on an equity or index; false
2903+ * otherwise.
2904+ *
2905+ * @public
2906+ * @static
2907+ * @param {String} symbol
2908+ * @returns {Boolean}
2909+ */
2910+
2911+
2912+ static getIsEquityOption(symbol) {
2913+ return is.string(symbol) && types.equities.options.test(symbol);
2914+ }
28802915 /**
28812916 * Returns true if the symbol has an expiration and the symbol appears
28822917 * to be expired (e.g. a future for a past year).
@@ -15548,6 +15583,78 @@ describe('When parsing a symbol for instrument type', () => {
1554815583 expect(instrumentType.type).toEqual('future_spread');
1554915584 });
1555015585 });
15586+ describe('and the symbol is AAPL1|20200515|250.00C', () => {
15587+ let instrumentType;
15588+ beforeEach(() => {
15589+ instrumentType = SymbolParser.parseInstrumentType('AAPL1|20200515|250.00C');
15590+ });
15591+ it('the result should not be null', () => {
15592+ expect(instrumentType).not.toBe(null);
15593+ });
15594+ it('the "symbol" should be "AAPL1|20200515|250.00C"', () => {
15595+ expect(instrumentType.symbol).toEqual('AAPL1|20200515|250.00C');
15596+ });
15597+ it('the "type" should be "equity_option"', () => {
15598+ expect(instrumentType.type).toEqual('equity_option');
15599+ });
15600+ it('the "root" should be "AAPL"', () => {
15601+ expect(instrumentType.root).toEqual('AAPL');
15602+ });
15603+ it('the "month" should be 5', () => {
15604+ expect(instrumentType.month).toEqual(5);
15605+ });
15606+ it('the "day" should be 15', () => {
15607+ expect(instrumentType.day).toEqual(15);
15608+ });
15609+ it('the "year" should be 2020', () => {
15610+ expect(instrumentType.year).toEqual(2020);
15611+ });
15612+ it('the "strike" should be 250', () => {
15613+ expect(instrumentType.strike).toEqual(250);
15614+ });
15615+ it('the "option_type" should be "call"', () => {
15616+ expect(instrumentType.option_type).toEqual('call');
15617+ });
15618+ it('the "adjusted" flag should be true', () => {
15619+ expect(instrumentType.adjusted).toEqual(true);
15620+ });
15621+ });
15622+ describe('and the symbol is $VIX|20200422|20.00WP', () => {
15623+ let instrumentType;
15624+ beforeEach(() => {
15625+ instrumentType = SymbolParser.parseInstrumentType('$VIX|20200422|20.00WP');
15626+ });
15627+ it('the result should not be null', () => {
15628+ expect(instrumentType).not.toBe(null);
15629+ });
15630+ it('the "symbol" should be "$VIX|20200422|20.00WP"', () => {
15631+ expect(instrumentType.symbol).toEqual('$VIX|20200422|20.00WP');
15632+ });
15633+ it('the "type" should be "equity_option"', () => {
15634+ expect(instrumentType.type).toEqual('equity_option');
15635+ });
15636+ it('the "root" should be "$VIX"', () => {
15637+ expect(instrumentType.root).toEqual('$VIX');
15638+ });
15639+ it('the "month" should be 4', () => {
15640+ expect(instrumentType.month).toEqual(4);
15641+ });
15642+ it('the "day" should be 22', () => {
15643+ expect(instrumentType.day).toEqual(22);
15644+ });
15645+ it('the "year" should be 2020', () => {
15646+ expect(instrumentType.year).toEqual(2020);
15647+ });
15648+ it('the "strike" should be 20', () => {
15649+ expect(instrumentType.strike).toEqual(20);
15650+ });
15651+ it('the "option_type" should be "put"', () => {
15652+ expect(instrumentType.option_type).toEqual('put');
15653+ });
15654+ it('the "adjusted" flag should be false', () => {
15655+ expect(instrumentType.adjusted).toEqual(false);
15656+ });
15657+ });
1555115658});
1555215659describe('When checking to see if a symbol is a future', () => {
1555315660 it('the symbol "ES*1" should return true', () => {
@@ -15610,6 +15717,12 @@ describe('When checking to see if a symbol is a future', () => {
1561015717 it('the symbol "ZCPAUS.CM" should return false', () => {
1561115718 expect(SymbolParser.getIsFuture('ZCPAUS.CM')).toEqual(false);
1561215719 });
15720+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
15721+ expect(SymbolParser.getIsFuture('AAPL|20200515|250.00C')).toEqual(false);
15722+ });
15723+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
15724+ expect(SymbolParser.getIsFuture('$VIX|20200422|20.00WP')).toEqual(false);
15725+ });
1561315726});
1561415727describe('When checking to see if a symbol is a "concrete" future', () => {
1561515728 it('the symbol "ESZ6" should return true', () => {
@@ -15715,6 +15828,12 @@ describe('When checking to see if a symbol is sector', () => {
1571515828 it('the symbol "ZCPAUS.CM" should return false', () => {
1571615829 expect(SymbolParser.getIsSector('ZCPAUS.CM')).toEqual(false);
1571715830 });
15831+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
15832+ expect(SymbolParser.getIsSector('AAPL|20200515|250.00C')).toEqual(false);
15833+ });
15834+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
15835+ expect(SymbolParser.getIsSector('$VIX|20200422|20.00WP')).toEqual(false);
15836+ });
1571815837});
1571915838describe('When checking to see if a symbol is forex', () => {
1572015839 it('the symbol "ES*1" should return false', () => {
@@ -15783,6 +15902,12 @@ describe('When checking to see if a symbol is forex', () => {
1578315902 it('the symbol "ZCPAUS.CM" should return false', () => {
1578415903 expect(SymbolParser.getIsForex('ZCPAUS.CM')).toEqual(false);
1578515904 });
15905+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
15906+ expect(SymbolParser.getIsForex('AAPL|20200515|250.00C')).toEqual(false);
15907+ });
15908+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
15909+ expect(SymbolParser.getIsForex('$VIX|20200422|20.00WP')).toEqual(false);
15910+ });
1578615911});
1578715912describe('When checking to see if a symbol is a future spread', () => {
1578815913 it('the symbol "ES*1" should return false', () => {
@@ -15851,6 +15976,12 @@ describe('When checking to see if a symbol is a future spread', () => {
1585115976 it('the symbol "ZCPAUS.CM" should return false', () => {
1585215977 expect(SymbolParser.getIsFutureSpread('ZCPAUS.CM')).toEqual(false);
1585315978 });
15979+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
15980+ expect(SymbolParser.getIsFutureSpread('AAPL|20200515|250.00C')).toEqual(false);
15981+ });
15982+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
15983+ expect(SymbolParser.getIsFutureSpread('$VIX|20200422|20.00WP')).toEqual(false);
15984+ });
1585415985});
1585515986describe('When checking to see if a symbol is a future option', () => {
1585615987 it('the symbol "ES*1" should return false', () => {
@@ -15919,6 +16050,12 @@ describe('When checking to see if a symbol is a future option', () => {
1591916050 it('the symbol "ZCPAUS.CM" should return false', () => {
1592016051 expect(SymbolParser.getIsFutureOption('ZCPAUS.CM')).toEqual(false);
1592116052 });
16053+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
16054+ expect(SymbolParser.getIsFutureOption('AAPL|20200515|250.00C')).toEqual(false);
16055+ });
16056+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
16057+ expect(SymbolParser.getIsFutureOption('$VIX|20200422|20.00WP')).toEqual(false);
16058+ });
1592216059});
1592316060describe('When checking to see if a symbol is a cmdty index option', () => {
1592416061 it('the symbol "ES*1" should return false', () => {
@@ -15987,6 +16124,86 @@ describe('When checking to see if a symbol is a cmdty index option', () => {
1598716124 it('the symbol "ZCPAUS.CM" should return true', () => {
1598816125 expect(SymbolParser.getIsCmdty('ZCPAUS.CM')).toEqual(true);
1598916126 });
16127+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
16128+ expect(SymbolParser.getIsCmdty('AAPL|20200515|250.00C')).toEqual(false);
16129+ });
16130+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
16131+ expect(SymbolParser.getIsCmdty('$VIX|20200422|20.00WP')).toEqual(false);
16132+ });
16133+ });
16134+ describe('When checking to see if a symbol is a equity option', () => {
16135+ it('the symbol "ES*1" should return false', () => {
16136+ expect(SymbolParser.getIsEquityOption('ES*1')).toEqual(false);
16137+ });
16138+ it('the symbol "NG*13" should return false', () => {
16139+ expect(SymbolParser.getIsEquityOption('NG*13')).toEqual(false);
16140+ });
16141+ it('the symbol "ESZ6" should return false', () => {
16142+ expect(SymbolParser.getIsEquityOption('ESZ6')).toEqual(false);
16143+ });
16144+ it('the symbol "ESZ16" should return false', () => {
16145+ expect(SymbolParser.getIsEquityOption('ESZ16')).toEqual(false);
16146+ });
16147+ it('the symbol "ESZ2016" should return false', () => {
16148+ expect(SymbolParser.getIsEquityOption('ESZ2016')).toEqual(false);
16149+ });
16150+ it('the symbol "ESZ016" should return false', () => {
16151+ expect(SymbolParser.getIsEquityOption('ESZ016')).toEqual(false);
16152+ });
16153+ it('the symbol "O!H7" should return false', () => {
16154+ expect(SymbolParser.getIsEquityOption('O!H7')).toEqual(false);
16155+ });
16156+ it('the symbol "O!H17" should return false', () => {
16157+ expect(SymbolParser.getIsEquityOption('O!H17')).toEqual(false);
16158+ });
16159+ it('the symbol "O!H2017" should return false', () => {
16160+ expect(SymbolParser.getIsEquityOption('O!H2017')).toEqual(false);
16161+ });
16162+ it('the symbol "IBM" should return false', () => {
16163+ expect(SymbolParser.getIsEquityOption('IBM')).toEqual(false);
16164+ });
16165+ it('the symbol "^EURUSD" should return false', () => {
16166+ expect(SymbolParser.getIsEquityOption('^EURUSD')).toEqual(false);
16167+ });
16168+ it('the symbol "-001A" should return false', () => {
16169+ expect(SymbolParser.getIsEquityOption('-001A')).toEqual(false);
16170+ });
16171+ it('the symbol "$DOWI" should return false', () => {
16172+ expect(SymbolParser.getIsEquityOption('$DOWI')).toEqual(false);
16173+ });
16174+ it('the symbol "$S1GE" should return false', () => {
16175+ expect(SymbolParser.getIsEquityOption('$S1GE')).toEqual(false);
16176+ });
16177+ it('the symbol "_S_SP_ZCH7_ZCK7" should return false', () => {
16178+ expect(SymbolParser.getIsEquityOption('_S_SP_ZCH7_ZCK7')).toEqual(false);
16179+ });
16180+ it('the symbol "ESZ2660Q" should return false', () => {
16181+ expect(SymbolParser.getIsEquityOption('ESZ2660Q')).toEqual(false);
16182+ });
16183+ it('the symbol "ZWH9|470C" should return false', () => {
16184+ expect(SymbolParser.getIsEquityOption('ZWH9|470C')).toEqual(false);
16185+ });
16186+ it('the symbol "BB1F8|12050C" should return false', () => {
16187+ expect(SymbolParser.getIsEquityOption('BB1F8|12050C')).toEqual(false);
16188+ });
16189+ it('the symbol "ZWK18465C" should return false', () => {
16190+ expect(SymbolParser.getIsEquityOption('ZWK18465C')).toEqual(false);
16191+ });
16192+ it('the symbol "PLATTS:AAVSV00C" should return false', () => {
16193+ expect(SymbolParser.getIsEquityOption('PLATTS:AAVSV00C')).toEqual(false);
16194+ });
16195+ it('the symbol "PLATTS:AAVSV00" should return false', () => {
16196+ expect(SymbolParser.getIsEquityOption('PLATTS:AAVSV00')).toEqual(false);
16197+ });
16198+ it('the symbol "ZCPAUS.CM" should return true', () => {
16199+ expect(SymbolParser.getIsEquityOption('ZCPAUS.CM')).toEqual(false);
16200+ });
16201+ it('the symbol "AAPL|20200515|250.00C" should return false', () => {
16202+ expect(SymbolParser.getIsEquityOption('AAPL|20200515|250.00C')).toEqual(true);
16203+ });
16204+ it('the symbol "$VIX|20200422|20.00WP" should return false', () => {
16205+ expect(SymbolParser.getIsEquityOption('$VIX|20200422|20.00WP')).toEqual(true);
16206+ });
1599016207});
1599116208describe('When checking to see if a symbol is a BATS listing', () => {
1599216209 it('the symbol "IBM" should return false', () => {
0 commit comments