From c5cafe3ef91b6d44a7d9d42f057805dcf9ba4473 Mon Sep 17 00:00:00 2001 From: Akiomi Kamakura Date: Fri, 10 Dec 2021 16:13:57 +0900 Subject: [PATCH 1/2] Add YYYYLQ and LYQn support to quarter params --- src/fiscal-periods/period-parser.test.ts | 4 +-- src/fiscal-periods/year-quarter-param.test.ts | 29 ++++++++++++------- src/fiscal-periods/year-quarter-param.ts | 10 ------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/fiscal-periods/period-parser.test.ts b/src/fiscal-periods/period-parser.test.ts index fbda466..b480a31 100644 --- a/src/fiscal-periods/period-parser.test.ts +++ b/src/fiscal-periods/period-parser.test.ts @@ -5,13 +5,13 @@ import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' test('parse', () => { expect(PeriodParser.parse('2020Q3')).toEqual(new YearQuarterParam(2020, 3)) + expect(PeriodParser.parse('2020LQ')).toEqual(new YearQuarterParam(2020, 'LQ')) + expect(PeriodParser.parse('LYQ3')).toEqual(new YearQuarterParam('LY', 3)) expect(PeriodParser.parse('LYLQ')).toEqual(new YearQuarterParam('LY', 'LQ')) expect(PeriodParser.parse('2020-09-06')).toEqual( new DateParam(new Date(2020, 9, 6)) ) expect(() => PeriodParser.parse('foo')).toThrow(ParseError) - expect(() => PeriodParser.parse('2020LQ')).toThrow(ParseError) - expect(() => PeriodParser.parse('LYQ3')).toThrow(ParseError) expect(() => PeriodParser.parse('2020/09/06')).toThrow(ParseError) expect(() => PeriodParser.parse('latest')).toThrow(ParseError) }) diff --git a/src/fiscal-periods/year-quarter-param.test.ts b/src/fiscal-periods/year-quarter-param.test.ts index d6e5ea2..7282f19 100644 --- a/src/fiscal-periods/year-quarter-param.test.ts +++ b/src/fiscal-periods/year-quarter-param.test.ts @@ -1,5 +1,4 @@ import { - InvalidLYLQError, InvalidYearError, InvalidQuarterError, ParseError @@ -10,15 +9,16 @@ import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' test('constructor', () => { expect(() => new YearQuarterParam(0, 3)).toThrow(InvalidYearError) expect(() => new YearQuarterParam(1, 3)).not.toThrow(Error) - expect(() => new YearQuarterParam('LY', 3)).toThrow(InvalidLYLQError) expect(() => new YearQuarterParam(2018, 0)).toThrow(InvalidQuarterError) expect(() => new YearQuarterParam(2018, 1)).not.toThrow(Error) expect(() => new YearQuarterParam(2018, 4)).not.toThrow(Error) expect(() => new YearQuarterParam(2018, 5)).toThrow(InvalidQuarterError) - expect(() => new YearQuarterParam('LY', 0)).toThrow(InvalidLYLQError) - expect(() => new YearQuarterParam('LY', 1)).toThrow(InvalidLYLQError) - expect(() => new YearQuarterParam('LY', 4)).toThrow(InvalidLYLQError) - expect(() => new YearQuarterParam('LY', 5)).toThrow(InvalidLYLQError) + expect(() => new YearQuarterParam('LY', 0)).toThrow(InvalidQuarterError) + expect(() => new YearQuarterParam('LY', 1)).not.toThrow(Error) + expect(() => new YearQuarterParam('LY', 4)).not.toThrow(Error) + expect(() => new YearQuarterParam('LY', 5)).toThrow(InvalidQuarterError) + expect(() => new YearQuarterParam(0, 'LQ')).toThrow(InvalidYearError) + expect(() => new YearQuarterParam(2018, 'LQ')).not.toThrow(Error) expect(() => new YearQuarterParam('LY', 'LQ')).not.toThrow(Error) }) @@ -26,6 +26,10 @@ test('convertibleToYearQuarter', () => { expect( new YearQuarterParam('LY', 'LQ').convertibleToYearQuarter() ).toBeFalsy() + expect( + new YearQuarterParam(2020, 'LQ').convertibleToYearQuarter() + ).toBeFalsy() + expect(new YearQuarterParam('LY', 3).convertibleToYearQuarter()).toBeFalsy() expect(new YearQuarterParam(2020, 3).convertibleToYearQuarter()).toBeTruthy() }) @@ -37,13 +41,13 @@ test('toYearQuarter', () => { }) test('isLatestYear', () => { - expect(new YearQuarterParam('LY', 'LQ').isLatestYear()).toBeTruthy() + expect(new YearQuarterParam('LY', 3).isLatestYear()).toBeTruthy() expect(new YearQuarterParam(2020, 3).isLatestYear()).toBeFalsy() }) test('isLatestQuarter', () => { - expect(new YearQuarterParam('LY', 'LQ').isLatestYear()).toBeTruthy() - expect(new YearQuarterParam(2020, 3).isLatestYear()).toBeFalsy() + expect(new YearQuarterParam(2020, 'LQ').isLatestQuarter()).toBeTruthy() + expect(new YearQuarterParam(2020, 3).isLatestQuarter()).toBeFalsy() }) test('fromYearQuarter', () => { @@ -59,14 +63,17 @@ test('parse', () => { expect(YearQuarterParam.parse('2020q3')).toEqual( new YearQuarterParam(2020, 3) ) + expect(YearQuarterParam.parse('2020LQ')).toEqual( + new YearQuarterParam(2020, 'LQ') + ) + expect(YearQuarterParam.parse('LYQ3')).toEqual(new YearQuarterParam('LY', 3)) expect(YearQuarterParam.parse('LYLQ')).toEqual( new YearQuarterParam('LY', 'LQ') ) expect(YearQuarterParam.parse('lylq')).toEqual( new YearQuarterParam('LY', 'LQ') ) + expect(() => YearQuarterParam.parse('20Q3')).toThrow(ParseError) - expect(() => YearQuarterParam.parse('LYQ3')).toThrow(InvalidLYLQError) - expect(() => YearQuarterParam.parse('2020LQ')).toThrow(InvalidLYLQError) expect(() => YearQuarterParam.parse('foo')).toThrow(ParseError) }) diff --git a/src/fiscal-periods/year-quarter-param.ts b/src/fiscal-periods/year-quarter-param.ts index d319380..70ad52e 100644 --- a/src/fiscal-periods/year-quarter-param.ts +++ b/src/fiscal-periods/year-quarter-param.ts @@ -1,5 +1,4 @@ import { - InvalidLYLQError, InvalidYearError, InvalidQuarterError, ParseError @@ -8,14 +7,6 @@ import { YearQuarter } from '~/fiscal-periods/year-quarter' export class YearQuarterParam { constructor(public year: number | 'LY', public quarter: number | 'LQ') { - if ( - (!this.isLatestYear() && this.isLatestQuarter()) || - (this.isLatestYear() && !this.isLatestQuarter()) - ) { - // NOTE: 現状ではLY/LQの同時指定しかサポートしない - throw new InvalidLYLQError() - } - if (!this.isLatestYear() && year < 1) { throw new InvalidYearError() } @@ -45,7 +36,6 @@ export class YearQuarterParam { return this.quarter === 'LQ' } - // XXX: LYLQの同時指定や-1などの相対値指定をどうするか確認する static parse(str: string): YearQuarterParam { str = str.toUpperCase() const matches = str.match(/^(\d{4}|LY)(Q\d|LQ)$/) From 0e62dac04c2e7684c06fee429ebf6fa980e83ab2 Mon Sep 17 00:00:00 2001 From: Akiomi Kamakura Date: Wed, 15 Dec 2021 15:55:09 +0900 Subject: [PATCH 2/2] Add advanced LY/LQ support --- src/api/company-service.test.ts | 24 ++++++++++++++++++++++++ src/api/company-service.ts | 22 ++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/api/company-service.test.ts b/src/api/company-service.test.ts index 8625d3a..636d07e 100644 --- a/src/api/company-service.test.ts +++ b/src/api/company-service.test.ts @@ -21,6 +21,24 @@ test('isSupportedTicker', () => { expect(new CompanyService('9999', client).isSupportedTicker()).toBe(false) }) +test('convertYearQuarterParamToYearQuarter', () => { + const client = new CachingBuffettCodeApiClientV2('token') + const service = new CompanyService('2371', client) + expect( + service.convertYearQuarterParamToYearQuarter(new YearQuarterParam('LY', 3)) + ).toEqual(new YearQuarter(2021, 3)) + expect( + service.convertYearQuarterParamToYearQuarter( + new YearQuarterParam(2016, 'LQ') + ) + ).toEqual(new YearQuarter(2016, 2)) + expect( + service.convertYearQuarterParamToYearQuarter( + new YearQuarterParam('LY', 'LQ') + ) + ).toEqual(new YearQuarter(2021, 2)) +}) + test('isOndemandQuarterApiPeriod', () => { const client = new CachingBuffettCodeApiClientV2('token') const service = new CompanyService('2371', client) @@ -34,6 +52,12 @@ test('isOndemandQuarterApiPeriod', () => { expect(service.isOndemandQuarterApiPeriod(new YearQuarter(2016, 3))).toBe( false ) + expect( + service.isOndemandQuarterApiPeriod(new YearQuarterParam('LY', 3)) + ).toBe(false) + expect( + service.isOndemandQuarterApiPeriod(new YearQuarterParam(2016, 'LQ')) + ).toBe(true) expect( service.isOndemandQuarterApiPeriod(new YearQuarterParam('LY', 'LQ')) ).toBe(false) diff --git a/src/api/company-service.ts b/src/api/company-service.ts index 1c5bbf6..e4853aa 100644 --- a/src/api/company-service.ts +++ b/src/api/company-service.ts @@ -19,6 +19,20 @@ export class CompanyService { return !!this.company } + public convertYearQuarterParamToYearQuarter( + period: YearQuarterParam + ): YearQuarter { + if (period.isLatestYear()) { + period.year = this.company['latest_fiscal_year'] + } + + if (period.isLatestQuarter()) { + period.quarter = this.company['latest_fiscal_quarter'] + } + + return period.toYearQuarter() + } + public isOndemandQuarterApiPeriod( _period: YearQuarter | YearQuarterParam ): boolean { @@ -26,13 +40,9 @@ export class CompanyService { throw new Error('unsupported ticker') } - let period + let period: YearQuarter if (_period instanceof YearQuarterParam) { - if (_period.isLatestYear() && _period.isLatestQuarter()) { - return false - } - - period = _period.toYearQuarter() + period = this.convertYearQuarterParamToYearQuarter(_period) } else { period = _period }