@oanda/labs-crowd-view-widget 1.0.52 → 1.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +216 -0
- package/dist/main/CrowdViewWidget/Main.js +1 -5
- package/dist/main/CrowdViewWidget/Main.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js +16 -6
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js +15 -6
- package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js +69 -29
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js +49 -26
- package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js +9 -10
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/index.js +0 -33
- package/dist/main/CrowdViewWidget/components/Chart/utils/index.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +54 -12
- package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +49 -27
- package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/processSentiments.js +32 -17
- package/dist/main/CrowdViewWidget/components/Chart/utils/processSentiments.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js +8 -2
- package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js +2 -3
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js +2 -2
- package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
- package/dist/main/CrowdViewWidget/constants.js +2 -6
- package/dist/main/CrowdViewWidget/constants.js.map +1 -1
- package/dist/main/gql/getOrderPositionBooks.js +1 -1
- package/dist/main/gql/getOrderPositionBooks.js.map +1 -1
- package/dist/main/gql/getPriceCandles.js +1 -1
- package/dist/main/gql/getPriceCandles.js.map +1 -1
- package/dist/main/gql/types/gql.js +2 -2
- package/dist/main/gql/types/gql.js.map +1 -1
- package/dist/main/gql/types/graphql.js +111 -18
- package/dist/main/gql/types/graphql.js.map +1 -1
- package/dist/module/CrowdViewWidget/Main.js +2 -6
- package/dist/module/CrowdViewWidget/Main.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js +17 -7
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js +15 -6
- package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js +70 -30
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js +50 -27
- package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js +10 -11
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/index.js +0 -3
- package/dist/module/CrowdViewWidget/components/Chart/utils/index.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +54 -12
- package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +49 -27
- package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/processSentiments.js +32 -17
- package/dist/module/CrowdViewWidget/components/Chart/utils/processSentiments.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js +8 -2
- package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js +2 -3
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js +2 -2
- package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
- package/dist/module/CrowdViewWidget/constants.js +1 -5
- package/dist/module/CrowdViewWidget/constants.js.map +1 -1
- package/dist/module/gql/getOrderPositionBooks.js +1 -1
- package/dist/module/gql/getOrderPositionBooks.js.map +1 -1
- package/dist/module/gql/getPriceCandles.js +1 -1
- package/dist/module/gql/getPriceCandles.js.map +1 -1
- package/dist/module/gql/types/gql.js +2 -2
- package/dist/module/gql/types/gql.js.map +1 -1
- package/dist/module/gql/types/graphql.js +111 -18
- package/dist/module/gql/types/graphql.js.map +1 -1
- package/dist/types/CrowdViewWidget/components/Chart/Chart.d.ts +1 -1
- package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +28 -11
- package/dist/types/CrowdViewWidget/components/Chart/utils/chartUtils.d.ts +3 -4
- package/dist/types/CrowdViewWidget/components/Chart/utils/index.d.ts +0 -3
- package/dist/types/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.d.ts +10 -7
- package/dist/types/CrowdViewWidget/components/Chart/utils/processPriceCandles.d.ts +6 -21
- package/dist/types/CrowdViewWidget/components/Chart/utils/processSentiments.d.ts +5 -2
- package/dist/types/CrowdViewWidget/components/Chart/utils/validateData.d.ts +1 -1
- package/dist/types/CrowdViewWidget/components/Legend/Legend.d.ts +2 -2
- package/dist/types/CrowdViewWidget/components/Legend/LegendBar.d.ts +1 -1
- package/dist/types/CrowdViewWidget/constants.d.ts +1 -5
- package/dist/types/gql/types/gql.d.ts +6 -4
- package/dist/types/gql/types/graphql.d.ts +30 -11
- package/package.json +3 -3
- package/src/CrowdViewWidget/Main.tsx +2 -4
- package/src/CrowdViewWidget/components/Chart/Chart.tsx +15 -6
- package/src/CrowdViewWidget/components/Chart/ChartWithData.tsx +21 -4
- package/src/CrowdViewWidget/components/Chart/chartOptions.ts +78 -30
- package/src/CrowdViewWidget/components/Chart/types.ts +30 -19
- package/src/CrowdViewWidget/components/Chart/useCrowdViewData.ts +82 -65
- package/src/CrowdViewWidget/components/Chart/utils/chartUtils.ts +32 -20
- package/src/CrowdViewWidget/components/Chart/utils/index.ts +0 -3
- package/src/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.ts +84 -22
- package/src/CrowdViewWidget/components/Chart/utils/processPriceCandles.ts +52 -38
- package/src/CrowdViewWidget/components/Chart/utils/processSentiments.ts +45 -32
- package/src/CrowdViewWidget/components/Chart/utils/validateData.ts +10 -2
- package/src/CrowdViewWidget/components/Legend/Legend.tsx +4 -5
- package/src/CrowdViewWidget/components/Legend/LegendBar.tsx +3 -3
- package/src/CrowdViewWidget/constants.ts +1 -6
- package/src/gql/getOrderPositionBooks.ts +13 -5
- package/src/gql/getPriceCandles.ts +1 -0
- package/src/gql/types/gql.ts +6 -6
- package/src/gql/types/graphql.ts +98 -16
- package/test/components/Chart/utils/chartUtils.test.ts +32 -14
- package/test/components/Chart/utils/processSentiments.test.ts +137 -29
- package/test/utils/processOrderPositionBooks.test.ts +201 -84
- package/test/utils/processPriceCandles.test.ts +93 -67
- package/test/utils/validateData.test.ts +136 -38
- package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +0 -37
- package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +0 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +0 -14
- package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +0 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js +0 -29
- package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +0 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +0 -29
- package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +0 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +0 -7
- package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +0 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js +0 -22
- package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +0 -1
- package/dist/types/CrowdViewWidget/components/Chart/utils/aggregateBuckets.d.ts +0 -2
- package/dist/types/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.d.ts +0 -3
- package/dist/types/CrowdViewWidget/components/Chart/utils/processBuckets.d.ts +0 -3
- package/src/CrowdViewWidget/components/Chart/utils/aggregateBuckets.ts +0 -44
- package/src/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.ts +0 -13
- package/src/CrowdViewWidget/components/Chart/utils/processBuckets.ts +0 -43
- package/test/utils/aggregateBuckets.test.ts +0 -82
- package/test/utils/getTargetBucketWidth.test.ts +0 -37
- package/test/utils/processBuckets.test.ts +0 -153
package/src/gql/types/graphql.ts
CHANGED
|
@@ -42,6 +42,7 @@ export enum AssetClassName {
|
|
|
42
42
|
EquityShares = 'EQUITY_SHARES',
|
|
43
43
|
Etfs = 'ETFS',
|
|
44
44
|
Indices = 'INDICES',
|
|
45
|
+
Metals = 'METALS',
|
|
45
46
|
Rates = 'RATES',
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -211,6 +212,15 @@ export enum OrderBookDataSource {
|
|
|
211
212
|
Ty3 = 'TY3',
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
export type OrderPositionBooksData = {
|
|
216
|
+
__typename?: 'OrderPositionBooksData';
|
|
217
|
+
books?: Maybe<Array<OrderPositionData>>;
|
|
218
|
+
bucketWidth: Scalars['Float']['output'];
|
|
219
|
+
displayPrecision: Scalars['Int']['output'];
|
|
220
|
+
sentimentThresholdMax: Scalars['Float']['output'];
|
|
221
|
+
sentimentThresholdMin: Scalars['Float']['output'];
|
|
222
|
+
};
|
|
223
|
+
|
|
214
224
|
export type OrderPositionBucket = {
|
|
215
225
|
__typename?: 'OrderPositionBucket';
|
|
216
226
|
longCountPercent?: Maybe<Scalars['Float']['output']>;
|
|
@@ -242,7 +252,7 @@ export type Query = {
|
|
|
242
252
|
mapInstrumentNames?: Maybe<Array<Maybe<Instrument>>>;
|
|
243
253
|
marginRates?: Maybe<Array<MarginRate>>;
|
|
244
254
|
orderPositionBook: Array<Maybe<OrderPositionData>>;
|
|
245
|
-
orderPositionBooks:
|
|
255
|
+
orderPositionBooks: OrderPositionBooksData;
|
|
246
256
|
priceCandles: CandlesData;
|
|
247
257
|
resolveInstrumentsByDivision?: Maybe<Array<Instrument>>;
|
|
248
258
|
resolveInstrumentsWithFilters?: Maybe<InstrumentTableResult>;
|
|
@@ -302,6 +312,8 @@ export type QueryOrderPositionBookArgs = {
|
|
|
302
312
|
|
|
303
313
|
export type QueryOrderPositionBooksArgs = {
|
|
304
314
|
bookType: BookType;
|
|
315
|
+
bucketMargin?: Scalars['Int']['input'];
|
|
316
|
+
bucketMultiplier?: Scalars['Int']['input'];
|
|
305
317
|
granularity: Granularity;
|
|
306
318
|
instrument: Scalars['String']['input'];
|
|
307
319
|
maxBookPrice?: InputMaybe<Scalars['Float']['input']>;
|
|
@@ -550,21 +562,28 @@ export type GetOrderPositionBooksQueryVariables = Exact<{
|
|
|
550
562
|
granularity: Granularity;
|
|
551
563
|
maxBookPrice?: InputMaybe<Scalars['Float']['input']>;
|
|
552
564
|
minBookPrice?: InputMaybe<Scalars['Float']['input']>;
|
|
565
|
+
bucketMultiplier: Scalars['Int']['input'];
|
|
566
|
+
bucketMargin: Scalars['Int']['input'];
|
|
553
567
|
}>;
|
|
554
568
|
|
|
555
569
|
export type GetOrderPositionBooksQuery = {
|
|
556
570
|
__typename?: 'Query';
|
|
557
|
-
orderPositionBooks:
|
|
558
|
-
__typename?: '
|
|
571
|
+
orderPositionBooks: {
|
|
572
|
+
__typename?: 'OrderPositionBooksData';
|
|
559
573
|
bucketWidth: number;
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
__typename?: '
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
574
|
+
sentimentThresholdMax: number;
|
|
575
|
+
sentimentThresholdMin: number;
|
|
576
|
+
books?: Array<{
|
|
577
|
+
__typename?: 'OrderPositionData';
|
|
578
|
+
time: string;
|
|
579
|
+
price?: number | null;
|
|
580
|
+
buckets: Array<{
|
|
581
|
+
__typename?: 'OrderPositionBucket';
|
|
582
|
+
price: number;
|
|
583
|
+
sentiment?: number | null;
|
|
584
|
+
} | null>;
|
|
585
|
+
}> | null;
|
|
586
|
+
};
|
|
568
587
|
};
|
|
569
588
|
|
|
570
589
|
export type GetPriceCandlesQueryVariables = Exact<{
|
|
@@ -579,6 +598,7 @@ export type GetPriceCandlesQuery = {
|
|
|
579
598
|
__typename?: 'Query';
|
|
580
599
|
priceCandles: {
|
|
581
600
|
__typename?: 'CandlesData';
|
|
601
|
+
pipsLocation: number;
|
|
582
602
|
candle: Array<{
|
|
583
603
|
__typename?: 'Candle';
|
|
584
604
|
point: string;
|
|
@@ -692,6 +712,28 @@ export const GetOrderPositionBooksDocument = {
|
|
|
692
712
|
},
|
|
693
713
|
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Float' } },
|
|
694
714
|
},
|
|
715
|
+
{
|
|
716
|
+
kind: 'VariableDefinition',
|
|
717
|
+
variable: {
|
|
718
|
+
kind: 'Variable',
|
|
719
|
+
name: { kind: 'Name', value: 'bucketMultiplier' },
|
|
720
|
+
},
|
|
721
|
+
type: {
|
|
722
|
+
kind: 'NonNullType',
|
|
723
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
kind: 'VariableDefinition',
|
|
728
|
+
variable: {
|
|
729
|
+
kind: 'Variable',
|
|
730
|
+
name: { kind: 'Name', value: 'bucketMargin' },
|
|
731
|
+
},
|
|
732
|
+
type: {
|
|
733
|
+
kind: 'NonNullType',
|
|
734
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
|
|
735
|
+
},
|
|
736
|
+
},
|
|
695
737
|
],
|
|
696
738
|
selectionSet: {
|
|
697
739
|
kind: 'SelectionSet',
|
|
@@ -748,27 +790,63 @@ export const GetOrderPositionBooksDocument = {
|
|
|
748
790
|
name: { kind: 'Name', value: 'minBookPrice' },
|
|
749
791
|
},
|
|
750
792
|
},
|
|
793
|
+
{
|
|
794
|
+
kind: 'Argument',
|
|
795
|
+
name: { kind: 'Name', value: 'bucketMultiplier' },
|
|
796
|
+
value: {
|
|
797
|
+
kind: 'Variable',
|
|
798
|
+
name: { kind: 'Name', value: 'bucketMultiplier' },
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
kind: 'Argument',
|
|
803
|
+
name: { kind: 'Name', value: 'bucketMargin' },
|
|
804
|
+
value: {
|
|
805
|
+
kind: 'Variable',
|
|
806
|
+
name: { kind: 'Name', value: 'bucketMargin' },
|
|
807
|
+
},
|
|
808
|
+
},
|
|
751
809
|
],
|
|
752
810
|
selectionSet: {
|
|
753
811
|
kind: 'SelectionSet',
|
|
754
812
|
selections: [
|
|
755
|
-
{ kind: 'Field', name: { kind: 'Name', value: 'bucketWidth' } },
|
|
756
|
-
{ kind: 'Field', name: { kind: 'Name', value: 'price' } },
|
|
757
|
-
{ kind: 'Field', name: { kind: 'Name', value: 'time' } },
|
|
758
813
|
{
|
|
759
814
|
kind: 'Field',
|
|
760
|
-
name: { kind: 'Name', value: '
|
|
815
|
+
name: { kind: 'Name', value: 'books' },
|
|
761
816
|
selectionSet: {
|
|
762
817
|
kind: 'SelectionSet',
|
|
763
818
|
selections: [
|
|
819
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'time' } },
|
|
764
820
|
{ kind: 'Field', name: { kind: 'Name', value: 'price' } },
|
|
765
821
|
{
|
|
766
822
|
kind: 'Field',
|
|
767
|
-
name: { kind: 'Name', value: '
|
|
823
|
+
name: { kind: 'Name', value: 'buckets' },
|
|
824
|
+
selectionSet: {
|
|
825
|
+
kind: 'SelectionSet',
|
|
826
|
+
selections: [
|
|
827
|
+
{
|
|
828
|
+
kind: 'Field',
|
|
829
|
+
name: { kind: 'Name', value: 'price' },
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
kind: 'Field',
|
|
833
|
+
name: { kind: 'Name', value: 'sentiment' },
|
|
834
|
+
},
|
|
835
|
+
],
|
|
836
|
+
},
|
|
768
837
|
},
|
|
769
838
|
],
|
|
770
839
|
},
|
|
771
840
|
},
|
|
841
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'bucketWidth' } },
|
|
842
|
+
{
|
|
843
|
+
kind: 'Field',
|
|
844
|
+
name: { kind: 'Name', value: 'sentimentThresholdMax' },
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
kind: 'Field',
|
|
848
|
+
name: { kind: 'Name', value: 'sentimentThresholdMin' },
|
|
849
|
+
},
|
|
772
850
|
],
|
|
773
851
|
},
|
|
774
852
|
},
|
|
@@ -924,6 +1002,10 @@ export const GetPriceCandlesDocument = {
|
|
|
924
1002
|
],
|
|
925
1003
|
},
|
|
926
1004
|
},
|
|
1005
|
+
{
|
|
1006
|
+
kind: 'Field',
|
|
1007
|
+
name: { kind: 'Name', value: 'pipsLocation' },
|
|
1008
|
+
},
|
|
927
1009
|
],
|
|
928
1010
|
},
|
|
929
1011
|
},
|
|
@@ -7,16 +7,18 @@ import {
|
|
|
7
7
|
getTooltipFormatter,
|
|
8
8
|
isDifferenceGreaterThanTwoWeeks,
|
|
9
9
|
} from '../../../../src/CrowdViewWidget/components/Chart/utils/chartUtils';
|
|
10
|
-
import {
|
|
11
|
-
BOOKS_THRESHOLDS,
|
|
12
|
-
COLOR_MAP,
|
|
13
|
-
} from '../../../../src/CrowdViewWidget/constants';
|
|
10
|
+
import { COLOR_MAP } from '../../../../src/CrowdViewWidget/constants';
|
|
14
11
|
import {
|
|
15
12
|
BookType,
|
|
16
13
|
Granularity,
|
|
17
14
|
TimeSpan,
|
|
18
15
|
} from '../../../../src/gql/types/graphql';
|
|
19
16
|
|
|
17
|
+
const TEST_THRESHOLDS = {
|
|
18
|
+
MIN: 0.15,
|
|
19
|
+
MAX: 0.55,
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
20
22
|
describe('chartUtils', () => {
|
|
21
23
|
describe('getTimeSpanForGranularity', () => {
|
|
22
24
|
it('maps granularity to expected TimeSpan', () => {
|
|
@@ -50,7 +52,12 @@ describe('chartUtils', () => {
|
|
|
50
52
|
|
|
51
53
|
describe('getRectColor', () => {
|
|
52
54
|
it('uses long color scale for positive sentiment in light mode', () => {
|
|
53
|
-
const color = getRectColor(
|
|
55
|
+
const color = getRectColor(
|
|
56
|
+
TEST_THRESHOLDS.MAX,
|
|
57
|
+
false,
|
|
58
|
+
TEST_THRESHOLDS.MIN,
|
|
59
|
+
TEST_THRESHOLDS.MAX
|
|
60
|
+
);
|
|
54
61
|
expect(typeof color).toBe('string');
|
|
55
62
|
// At max threshold, should be at or near target color
|
|
56
63
|
expect(color.toLowerCase()).toContain(
|
|
@@ -59,7 +66,12 @@ describe('chartUtils', () => {
|
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
it('uses short color scale for negative sentiment in light mode', () => {
|
|
62
|
-
const color = getRectColor(
|
|
69
|
+
const color = getRectColor(
|
|
70
|
+
-TEST_THRESHOLDS.MAX,
|
|
71
|
+
false,
|
|
72
|
+
TEST_THRESHOLDS.MIN,
|
|
73
|
+
TEST_THRESHOLDS.MAX
|
|
74
|
+
);
|
|
63
75
|
expect(typeof color).toBe('string');
|
|
64
76
|
expect(color.toLowerCase()).toContain(
|
|
65
77
|
COLOR_MAP.light.short[1].slice(1).toLowerCase().substring(0, 3)
|
|
@@ -67,7 +79,12 @@ describe('chartUtils', () => {
|
|
|
67
79
|
});
|
|
68
80
|
|
|
69
81
|
it('uses long color scale for positive sentiment in dark mode', () => {
|
|
70
|
-
const color = getRectColor(
|
|
82
|
+
const color = getRectColor(
|
|
83
|
+
TEST_THRESHOLDS.MAX,
|
|
84
|
+
true,
|
|
85
|
+
TEST_THRESHOLDS.MIN,
|
|
86
|
+
TEST_THRESHOLDS.MAX
|
|
87
|
+
);
|
|
71
88
|
expect(typeof color).toBe('string');
|
|
72
89
|
// At max threshold, should be at or near target color
|
|
73
90
|
expect(color.toLowerCase()).toContain(
|
|
@@ -76,7 +93,12 @@ describe('chartUtils', () => {
|
|
|
76
93
|
});
|
|
77
94
|
|
|
78
95
|
it('uses short color scale for negative sentiment in dark mode', () => {
|
|
79
|
-
const color = getRectColor(
|
|
96
|
+
const color = getRectColor(
|
|
97
|
+
-TEST_THRESHOLDS.MAX,
|
|
98
|
+
true,
|
|
99
|
+
TEST_THRESHOLDS.MIN,
|
|
100
|
+
TEST_THRESHOLDS.MAX
|
|
101
|
+
);
|
|
80
102
|
expect(typeof color).toBe('string');
|
|
81
103
|
expect(color.toLowerCase()).toContain(
|
|
82
104
|
COLOR_MAP.dark.short[1].slice(1).toLowerCase().substring(0, 3)
|
|
@@ -111,7 +133,7 @@ describe('chartUtils', () => {
|
|
|
111
133
|
|
|
112
134
|
it('emits label when day changes for < two weeks case', () => {
|
|
113
135
|
const labels = getLabelData({
|
|
114
|
-
|
|
136
|
+
dates,
|
|
115
137
|
isGreaterThanTwoWeeks: true,
|
|
116
138
|
});
|
|
117
139
|
// First change happens between 1st and 2nd
|
|
@@ -126,7 +148,7 @@ describe('chartUtils', () => {
|
|
|
126
148
|
'2025-02-15T00:00:00Z',
|
|
127
149
|
];
|
|
128
150
|
const labels = getLabelData({
|
|
129
|
-
|
|
151
|
+
dates: monthSpanDates,
|
|
130
152
|
isGreaterThanTwoWeeks: false,
|
|
131
153
|
});
|
|
132
154
|
expect(labels.length).toBe(1);
|
|
@@ -162,7 +184,6 @@ describe('chartUtils', () => {
|
|
|
162
184
|
buckets,
|
|
163
185
|
bucketWidth: 0.0005,
|
|
164
186
|
selectedPrice: 1.3306,
|
|
165
|
-
precision: 5,
|
|
166
187
|
bookType: BookType.Order,
|
|
167
188
|
labelCallback,
|
|
168
189
|
});
|
|
@@ -198,7 +219,6 @@ describe('chartUtils', () => {
|
|
|
198
219
|
buckets,
|
|
199
220
|
bucketWidth: 0.0005,
|
|
200
221
|
selectedPrice: 1.3306,
|
|
201
|
-
precision: 5,
|
|
202
222
|
bookType: BookType.Order,
|
|
203
223
|
labelCallback,
|
|
204
224
|
});
|
|
@@ -226,7 +246,6 @@ describe('chartUtils', () => {
|
|
|
226
246
|
buckets,
|
|
227
247
|
bucketWidth: 0.0005,
|
|
228
248
|
selectedPrice: 1.3306,
|
|
229
|
-
precision: 5,
|
|
230
249
|
bookType: BookType.Order,
|
|
231
250
|
labelCallback,
|
|
232
251
|
});
|
|
@@ -239,7 +258,6 @@ describe('chartUtils', () => {
|
|
|
239
258
|
buckets: [],
|
|
240
259
|
bucketWidth: 0.0005,
|
|
241
260
|
selectedPrice: 1.3306,
|
|
242
|
-
precision: 5,
|
|
243
261
|
bookType: BookType.Order,
|
|
244
262
|
labelCallback,
|
|
245
263
|
});
|
|
@@ -2,33 +2,45 @@ import { processSentiments } from '../../../../src/CrowdViewWidget/components/Ch
|
|
|
2
2
|
import type { GetSentimentsQuery } from '../../../../src/gql/types/graphql';
|
|
3
3
|
|
|
4
4
|
describe('processSentiments', () => {
|
|
5
|
-
it('returns empty
|
|
5
|
+
it('returns empty arrays when sentimentsData is undefined', () => {
|
|
6
6
|
const result = processSentiments(undefined, ['2025-03-15T10:30:00Z']);
|
|
7
|
-
expect(result).toEqual(
|
|
7
|
+
expect(result).toEqual({
|
|
8
|
+
sentimentLongs: [],
|
|
9
|
+
sentimentShorts: [],
|
|
10
|
+
hasValidSentiments: false,
|
|
11
|
+
});
|
|
8
12
|
});
|
|
9
13
|
|
|
10
|
-
it('returns empty
|
|
14
|
+
it('returns empty arrays when sentiments array is empty', () => {
|
|
11
15
|
const sentimentsData: GetSentimentsQuery = {
|
|
12
16
|
sentiments: {
|
|
13
17
|
sentiments: [],
|
|
14
18
|
},
|
|
15
19
|
};
|
|
16
20
|
const result = processSentiments(sentimentsData, ['2025-03-15T10:30:00Z']);
|
|
17
|
-
expect(result).toEqual(
|
|
21
|
+
expect(result).toEqual({
|
|
22
|
+
sentimentLongs: [],
|
|
23
|
+
sentimentShorts: [],
|
|
24
|
+
hasValidSentiments: false,
|
|
25
|
+
});
|
|
18
26
|
});
|
|
19
27
|
|
|
20
|
-
it('returns empty
|
|
28
|
+
it('returns empty arrays when sentiments is null', () => {
|
|
21
29
|
const sentimentsData: GetSentimentsQuery = {
|
|
22
30
|
sentiments: {
|
|
23
31
|
sentiments: null as never,
|
|
24
32
|
},
|
|
25
33
|
};
|
|
26
34
|
const result = processSentiments(sentimentsData, ['2025-03-15T10:30:00Z']);
|
|
27
|
-
expect(result).toEqual(
|
|
35
|
+
expect(result).toEqual({
|
|
36
|
+
sentimentLongs: [],
|
|
37
|
+
sentimentShorts: [],
|
|
38
|
+
hasValidSentiments: false,
|
|
39
|
+
});
|
|
28
40
|
});
|
|
29
41
|
|
|
30
|
-
it('processes sentiments and matches with
|
|
31
|
-
const
|
|
42
|
+
it('processes sentiments and matches with dates', () => {
|
|
43
|
+
const dates = [
|
|
32
44
|
'2025-03-15T10:30:00Z',
|
|
33
45
|
'2025-03-15T11:30:00Z',
|
|
34
46
|
'2025-03-15T12:30:00Z',
|
|
@@ -54,15 +66,14 @@ describe('processSentiments', () => {
|
|
|
54
66
|
},
|
|
55
67
|
};
|
|
56
68
|
|
|
57
|
-
const result = processSentiments(sentimentsData,
|
|
58
|
-
expect(result).
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
]);
|
|
69
|
+
const result = processSentiments(sentimentsData, dates);
|
|
70
|
+
expect(result.hasValidSentiments).toBe(true);
|
|
71
|
+
expect(result.sentimentShorts).toEqual([30.5, 40.2, null]);
|
|
72
|
+
expect(result.sentimentLongs).toEqual([69.5, 59.8, null]);
|
|
62
73
|
});
|
|
63
74
|
|
|
64
|
-
it('
|
|
65
|
-
const
|
|
75
|
+
it('returns null for dates that do not match any sentiment', () => {
|
|
76
|
+
const dates = ['2025-03-15T10:30:00Z', '2025-03-15T11:30:00Z'];
|
|
66
77
|
const sentimentsData: GetSentimentsQuery = {
|
|
67
78
|
sentiments: {
|
|
68
79
|
sentiments: [
|
|
@@ -74,7 +85,7 @@ describe('processSentiments', () => {
|
|
|
74
85
|
},
|
|
75
86
|
},
|
|
76
87
|
{
|
|
77
|
-
time: '2025-03-15T12:30:00Z', // Not in
|
|
88
|
+
time: '2025-03-15T12:30:00Z', // Not in dates
|
|
78
89
|
sentiment: {
|
|
79
90
|
shortPercent: 50.0,
|
|
80
91
|
longPercent: 50.0,
|
|
@@ -84,37 +95,133 @@ describe('processSentiments', () => {
|
|
|
84
95
|
},
|
|
85
96
|
};
|
|
86
97
|
|
|
87
|
-
const result = processSentiments(sentimentsData,
|
|
88
|
-
expect(result).toEqual([
|
|
98
|
+
const result = processSentiments(sentimentsData, dates);
|
|
99
|
+
expect(result.sentimentShorts).toEqual([30.5, null]);
|
|
100
|
+
expect(result.sentimentLongs).toEqual([69.5, null]);
|
|
89
101
|
});
|
|
90
102
|
|
|
91
|
-
it('
|
|
92
|
-
const
|
|
103
|
+
it('returns null arrays when no sentiments match dates', () => {
|
|
104
|
+
const dates = ['2025-03-15T10:30:00Z'];
|
|
105
|
+
const sentimentsData: GetSentimentsQuery = {
|
|
106
|
+
sentiments: {
|
|
107
|
+
sentiments: [
|
|
108
|
+
{
|
|
109
|
+
time: '2025-03-15T11:30:00Z',
|
|
110
|
+
sentiment: {
|
|
111
|
+
shortPercent: 30.5,
|
|
112
|
+
longPercent: 69.5,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const result = processSentiments(sentimentsData, dates);
|
|
120
|
+
expect(result.sentimentShorts).toEqual([null]);
|
|
121
|
+
expect(result.sentimentLongs).toEqual([null]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('handles multiple dates with mixed matching sentiments', () => {
|
|
125
|
+
const dates = [
|
|
126
|
+
'2025-03-15T10:30:00Z',
|
|
127
|
+
'2025-03-15T11:30:00Z',
|
|
128
|
+
'2025-03-15T12:30:00Z',
|
|
129
|
+
'2025-03-15T13:30:00Z',
|
|
130
|
+
];
|
|
93
131
|
const sentimentsData: GetSentimentsQuery = {
|
|
94
132
|
sentiments: {
|
|
95
133
|
sentiments: [
|
|
96
134
|
{
|
|
97
135
|
time: '2025-03-15T10:30:00Z',
|
|
98
136
|
sentiment: {
|
|
99
|
-
shortPercent:
|
|
100
|
-
longPercent:
|
|
137
|
+
shortPercent: 30.5,
|
|
138
|
+
longPercent: 69.5,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
time: '2025-03-15T12:30:00Z',
|
|
143
|
+
sentiment: {
|
|
144
|
+
shortPercent: 25.0,
|
|
145
|
+
longPercent: 75.0,
|
|
101
146
|
},
|
|
102
147
|
},
|
|
103
148
|
],
|
|
104
149
|
},
|
|
105
150
|
};
|
|
106
151
|
|
|
107
|
-
const result = processSentiments(sentimentsData,
|
|
108
|
-
expect(result).toEqual([]);
|
|
152
|
+
const result = processSentiments(sentimentsData, dates);
|
|
153
|
+
expect(result.sentimentShorts).toEqual([30.5, null, 25.0, null]);
|
|
154
|
+
expect(result.sentimentLongs).toEqual([69.5, null, 75.0, null]);
|
|
109
155
|
});
|
|
110
156
|
|
|
111
|
-
it('
|
|
112
|
-
const
|
|
157
|
+
it('should handle null sentiment objects gracefully', () => {
|
|
158
|
+
const dates = ['2025-03-15T10:30:00Z'];
|
|
113
159
|
const sentimentsData: GetSentimentsQuery = {
|
|
114
160
|
sentiments: {
|
|
115
161
|
sentiments: [
|
|
116
162
|
{
|
|
117
|
-
time: '2025-03-
|
|
163
|
+
time: '2025-03-15T10:30:00Z',
|
|
164
|
+
sentiment: null as never,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const result = processSentiments(sentimentsData, dates);
|
|
171
|
+
expect(result.sentimentShorts).toEqual([null]);
|
|
172
|
+
expect(result.sentimentLongs).toEqual([null]);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should handle undefined sentiment properties', () => {
|
|
176
|
+
const dates = ['2025-03-15T10:30:00Z'];
|
|
177
|
+
const sentimentsData: GetSentimentsQuery = {
|
|
178
|
+
sentiments: {
|
|
179
|
+
sentiments: [
|
|
180
|
+
{
|
|
181
|
+
time: '2025-03-15T10:30:00Z',
|
|
182
|
+
sentiment: {
|
|
183
|
+
shortPercent: undefined as never,
|
|
184
|
+
longPercent: undefined as never,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const result = processSentiments(sentimentsData, dates);
|
|
192
|
+
expect(result.sentimentShorts).toEqual([null]);
|
|
193
|
+
expect(result.sentimentLongs).toEqual([null]);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should return empty arrays when dates array is empty', () => {
|
|
197
|
+
const sentimentsData: GetSentimentsQuery = {
|
|
198
|
+
sentiments: {
|
|
199
|
+
sentiments: [
|
|
200
|
+
{
|
|
201
|
+
time: '2025-03-15T10:30:00Z',
|
|
202
|
+
sentiment: {
|
|
203
|
+
shortPercent: 30.5,
|
|
204
|
+
longPercent: 69.5,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const result = processSentiments(sentimentsData, []);
|
|
212
|
+
expect(result).toEqual({
|
|
213
|
+
sentimentLongs: [],
|
|
214
|
+
sentimentShorts: [],
|
|
215
|
+
hasValidSentiments: false,
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should return empty arrays when dates is not an array', () => {
|
|
220
|
+
const sentimentsData: GetSentimentsQuery = {
|
|
221
|
+
sentiments: {
|
|
222
|
+
sentiments: [
|
|
223
|
+
{
|
|
224
|
+
time: '2025-03-15T10:30:00Z',
|
|
118
225
|
sentiment: {
|
|
119
226
|
shortPercent: 30.5,
|
|
120
227
|
longPercent: 69.5,
|
|
@@ -124,7 +231,8 @@ describe('processSentiments', () => {
|
|
|
124
231
|
},
|
|
125
232
|
};
|
|
126
233
|
|
|
127
|
-
|
|
128
|
-
|
|
234
|
+
// @ts-expect-error - Testing invalid input
|
|
235
|
+
const result = processSentiments(sentimentsData, null);
|
|
236
|
+
expect(result.hasValidSentiments).toBe(false);
|
|
129
237
|
});
|
|
130
238
|
});
|