@oanda/labs-crowd-view-widget 1.0.44 → 1.0.46
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 +372 -0
- package/dist/main/CrowdViewWidget/Main.js +20 -7
- package/dist/main/CrowdViewWidget/Main.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js +6 -10
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js +46 -20
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/index.js +4 -4
- package/dist/main/CrowdViewWidget/components/Chart/index.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js +18 -88
- package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +37 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js +54 -2
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +14 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/index.js +83 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/index.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js +29 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +23 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +43 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js +23 -0
- package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -0
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js +5 -3
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/main/CrowdViewWidget/constants.js +105 -5
- package/dist/main/CrowdViewWidget/constants.js.map +1 -1
- package/dist/main/CrowdViewWidget/selectConfig.js +18 -60
- package/dist/main/CrowdViewWidget/selectConfig.js.map +1 -1
- package/dist/main/CrowdViewWidget/types.js +20 -0
- package/dist/main/CrowdViewWidget/types.js.map +1 -1
- package/dist/main/translations/sources/en.json +29 -0
- package/dist/module/CrowdViewWidget/Main.js +21 -8
- package/dist/module/CrowdViewWidget/Main.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js +7 -11
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js +47 -21
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/index.js +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/index.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js +14 -84
- package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +29 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js +52 -2
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +7 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/index.js +8 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/index.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js +22 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +16 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +36 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js +16 -0
- package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -0
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js +5 -3
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/module/CrowdViewWidget/constants.js +104 -4
- package/dist/module/CrowdViewWidget/constants.js.map +1 -1
- package/dist/module/CrowdViewWidget/selectConfig.js +3 -45
- package/dist/module/CrowdViewWidget/selectConfig.js.map +1 -1
- package/dist/module/CrowdViewWidget/types.js +19 -1
- package/dist/module/CrowdViewWidget/types.js.map +1 -1
- package/dist/module/translations/sources/en.json +29 -0
- package/dist/types/CrowdViewWidget/components/Chart/index.d.ts +1 -1
- package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +12 -4
- package/dist/types/CrowdViewWidget/components/Chart/utils/aggregateBuckets.d.ts +2 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/chartUtils.d.ts +12 -2
- package/dist/types/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.d.ts +3 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/index.d.ts +7 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/processBuckets.d.ts +3 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.d.ts +8 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/processPriceCandles.d.ts +27 -0
- package/dist/types/CrowdViewWidget/components/Chart/utils/validateData.d.ts +2 -0
- package/dist/types/CrowdViewWidget/components/Legend/Legend.d.ts +3 -1
- package/dist/types/CrowdViewWidget/constants.d.ts +11 -3
- package/dist/types/CrowdViewWidget/selectConfig.d.ts +2 -2
- package/dist/types/CrowdViewWidget/types.d.ts +18 -1
- package/dist/types/CrowdViewWidget/utils/instrumentUtils.d.ts +1 -4
- package/lokalise.config.json +1 -1
- package/package.json +4 -3
- package/src/CrowdViewWidget/Main.tsx +25 -10
- package/src/CrowdViewWidget/components/Chart/Chart.tsx +6 -12
- package/src/CrowdViewWidget/components/Chart/chartOptions.ts +70 -36
- package/src/CrowdViewWidget/components/Chart/index.ts +1 -1
- package/src/CrowdViewWidget/components/Chart/types.ts +16 -4
- package/src/CrowdViewWidget/components/Chart/useCrowdViewData.ts +41 -140
- package/src/CrowdViewWidget/components/Chart/utils/aggregateBuckets.ts +44 -0
- package/src/CrowdViewWidget/components/Chart/utils/chartUtils.ts +96 -3
- package/src/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.ts +13 -0
- package/src/CrowdViewWidget/components/Chart/utils/index.ts +7 -0
- package/src/CrowdViewWidget/components/Chart/utils/processBuckets.ts +43 -0
- package/src/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.ts +30 -0
- package/src/CrowdViewWidget/components/Chart/utils/processPriceCandles.ts +53 -0
- package/src/CrowdViewWidget/components/Chart/utils/validateData.ts +27 -0
- package/src/CrowdViewWidget/components/Legend/Legend.tsx +13 -2
- package/src/CrowdViewWidget/constants.ts +113 -3
- package/src/CrowdViewWidget/selectConfig.ts +5 -60
- package/src/CrowdViewWidget/types.ts +18 -1
- package/src/translations/sources/en.json +29 -0
- package/test/Main.test.tsx +73 -27
- package/test/components/Chart/utils/chartUtils.test.ts +158 -0
- package/test/components/Legend.test.tsx +6 -1
- package/test/utils/aggregateBuckets.test.ts +82 -0
- package/test/utils/getTargetBucketWidth.test.ts +37 -0
- package/test/utils/instrumentUtils.test.ts +13 -7
- package/test/utils/processBuckets.test.ts +153 -0
- package/test/utils/processOrderPositionBooks.test.ts +127 -0
- package/test/utils/processPriceCandles.test.ts +245 -0
- package/test/utils/validateData.test.ts +201 -0
- package/dist/main/CrowdViewWidget/types/index.js +0 -17
- package/dist/main/CrowdViewWidget/types/index.js.map +0 -1
- package/dist/main/CrowdViewWidget/types/instruments.js +0 -45
- package/dist/main/CrowdViewWidget/types/instruments.js.map +0 -1
- package/dist/module/CrowdViewWidget/types/index.js +0 -2
- package/dist/module/CrowdViewWidget/types/index.js.map +0 -1
- package/dist/module/CrowdViewWidget/types/instruments.js +0 -39
- package/dist/module/CrowdViewWidget/types/instruments.js.map +0 -1
- package/dist/types/CrowdViewWidget/types/index.d.ts +0 -1
- package/dist/types/CrowdViewWidget/types/instruments.d.ts +0 -36
- package/src/CrowdViewWidget/types/index.ts +0 -1
- package/src/CrowdViewWidget/types/instruments.ts +0 -37
|
@@ -1,2 +1,20 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export let InstrumentId = function (InstrumentId) {
|
|
2
|
+
InstrumentId["EUR_AUD"] = "EURAUD";
|
|
3
|
+
InstrumentId["EUR_GBP"] = "EURGBP";
|
|
4
|
+
InstrumentId["EUR_JPY"] = "EURJPY";
|
|
5
|
+
InstrumentId["EUR_USD"] = "EURUSD";
|
|
6
|
+
InstrumentId["EUR_CHF"] = "EURCHF";
|
|
7
|
+
InstrumentId["USD_CHF"] = "USDCHF";
|
|
8
|
+
InstrumentId["USD_JPY"] = "USDJPY";
|
|
9
|
+
InstrumentId["USD_CAD"] = "USDCAD";
|
|
10
|
+
InstrumentId["GBP_USD"] = "GBPUSD";
|
|
11
|
+
InstrumentId["GBP_JPY"] = "GBPJPY";
|
|
12
|
+
InstrumentId["GBP_CHF"] = "GBPCHF";
|
|
13
|
+
InstrumentId["AUD_JPY"] = "AUDJPY";
|
|
14
|
+
InstrumentId["AUD_USD"] = "AUDUSD";
|
|
15
|
+
InstrumentId["NZD_USD"] = "NZDUSD";
|
|
16
|
+
InstrumentId["XAU_USD"] = "XAUUSD";
|
|
17
|
+
InstrumentId["XAG_USD"] = "XAGUSD";
|
|
18
|
+
return InstrumentId;
|
|
19
|
+
}({});
|
|
2
20
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/CrowdViewWidget/types.ts"],"sourcesContent":["import type { WidgetConfig } from '@oanda/labs-widget-common';\n\nimport type { Division } from '../gql/types/graphql';\
|
|
1
|
+
{"version":3,"file":"types.js","names":["InstrumentId"],"sources":["../../../src/CrowdViewWidget/types.ts"],"sourcesContent":["import type { WidgetConfig } from '@oanda/labs-widget-common';\n\nimport type { Division } from '../gql/types/graphql';\n\nexport enum InstrumentId {\n EUR_AUD = 'EURAUD',\n EUR_GBP = 'EURGBP',\n EUR_JPY = 'EURJPY',\n EUR_USD = 'EURUSD',\n EUR_CHF = 'EURCHF',\n USD_CHF = 'USDCHF',\n USD_JPY = 'USDJPY',\n USD_CAD = 'USDCAD',\n GBP_USD = 'GBPUSD',\n GBP_JPY = 'GBPJPY',\n GBP_CHF = 'GBPCHF',\n AUD_JPY = 'AUDJPY',\n AUD_USD = 'AUDUSD',\n NZD_USD = 'NZDUSD',\n XAU_USD = 'XAUUSD',\n XAG_USD = 'XAGUSD',\n}\nexport interface CrowdViewConfig extends WidgetConfig {\n division: Division;\n}\n\nexport interface MainProps {\n instrument?: InstrumentId;\n division: Division;\n}\n"],"mappings":"AAIA,WAAYA,YAAY,aAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA","ignoreList":[]}
|
|
@@ -1,2 +1,31 @@
|
|
|
1
1
|
{
|
|
2
|
+
"1_hour": "1 hour",
|
|
3
|
+
"15_minutes": "15 minutes",
|
|
4
|
+
"4_hours": "4 hours",
|
|
5
|
+
"5_minutes": "5 minutes",
|
|
6
|
+
"buy_advantage": "Buy advantage",
|
|
7
|
+
"buy": "Buy",
|
|
8
|
+
"candle": "Candle",
|
|
9
|
+
"close_price": "Close price",
|
|
10
|
+
"data_unavailable": "Data unavailable",
|
|
11
|
+
"granularity": "Granularity",
|
|
12
|
+
"high": "High",
|
|
13
|
+
"instrument": "Instrument",
|
|
14
|
+
"long_advantage": "Sell advantage",
|
|
15
|
+
"long": "Long",
|
|
16
|
+
"low": "Low",
|
|
17
|
+
"no_matching_results": "No matching results",
|
|
18
|
+
"open_price": "Open price",
|
|
19
|
+
"order_book": "Order book",
|
|
20
|
+
"orders": "Orders",
|
|
21
|
+
"pagination_entries_range": "{{firstItemOnPage}}-{{lastItemOnPage}} of {{itemCount}} entries",
|
|
22
|
+
"position_book": "Position book",
|
|
23
|
+
"positions": "Positions",
|
|
24
|
+
"price_range": "Price range",
|
|
25
|
+
"search": "Search",
|
|
26
|
+
"sell_advantage": "Sell advantage",
|
|
27
|
+
"sell": "Sell",
|
|
28
|
+
"sentiment": "Sentiment",
|
|
29
|
+
"short_advantage": "Buy advantage",
|
|
30
|
+
"short": "Short"
|
|
2
31
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { EChartsOption } from 'echarts';
|
|
2
2
|
import type { BookType, Division, Granularity } from '../../../gql/types/graphql';
|
|
3
|
+
import type { InstrumentId } from '../../types';
|
|
4
|
+
export interface Bucket {
|
|
5
|
+
price: number;
|
|
6
|
+
sentiment: number;
|
|
7
|
+
}
|
|
3
8
|
export interface UseCrowdViewDataProps {
|
|
4
|
-
instrument:
|
|
9
|
+
instrument: InstrumentId;
|
|
5
10
|
bookType: BookType;
|
|
6
11
|
division: Division;
|
|
7
12
|
granularity: Granularity;
|
|
@@ -9,22 +14,25 @@ export interface UseCrowdViewDataProps {
|
|
|
9
14
|
interface CrowdViewData {
|
|
10
15
|
xAxisData: string[];
|
|
11
16
|
candlesSeriesData: [number, number, number, number][];
|
|
12
|
-
orderPositionBooks:
|
|
17
|
+
orderPositionBooks: [string, number | null, number][];
|
|
13
18
|
bucketWidth: number;
|
|
19
|
+
buckets: Bucket[][];
|
|
20
|
+
precision: number;
|
|
21
|
+
bookType: BookType;
|
|
14
22
|
}
|
|
15
23
|
export interface UseCrowdViewDataReturn {
|
|
16
24
|
data: CrowdViewData | null;
|
|
17
25
|
loading: boolean;
|
|
18
26
|
error: boolean;
|
|
19
27
|
}
|
|
20
|
-
export type GetOptionType = (props: CrowdViewData, isDark: boolean) => EChartsOption;
|
|
28
|
+
export type GetOptionType = (props: CrowdViewData, isDark: boolean, labelCallback: (key: string, params?: Record<string, unknown>) => string) => EChartsOption;
|
|
21
29
|
export interface ChartProps {
|
|
22
30
|
data: CrowdViewData;
|
|
23
31
|
}
|
|
24
32
|
export interface ChartWithDataProps {
|
|
25
33
|
bookType: BookType;
|
|
26
34
|
division: Division;
|
|
27
|
-
instrument:
|
|
35
|
+
instrument: InstrumentId;
|
|
28
36
|
granularity: Granularity;
|
|
29
37
|
}
|
|
30
38
|
export interface GetLabelsDataProps {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Granularity, TimeSpan } from '../../../../gql/types/graphql';
|
|
2
|
-
import type { GetLabelsDataProps } from '../types';
|
|
1
|
+
import { BookType, Granularity, TimeSpan } from '../../../../gql/types/graphql';
|
|
2
|
+
import type { Bucket, GetLabelsDataProps } from '../types';
|
|
3
3
|
export declare const getLabelData: ({ xAxisData, isGreaterThanTwoWeeks, }: GetLabelsDataProps) => {
|
|
4
4
|
name: string;
|
|
5
5
|
xAxis: string;
|
|
@@ -19,3 +19,13 @@ export declare const getLabelData: ({ xAxisData, isGreaterThanTwoWeeks, }: GetLa
|
|
|
19
19
|
export declare const isDifferenceGreaterThanTwoWeeks: (startDate: string, endDate: string) => boolean;
|
|
20
20
|
export declare const getTimeSpanForGranularity: (granularity: Granularity) => TimeSpan;
|
|
21
21
|
export declare const getRectColor: (sentiment: number) => string;
|
|
22
|
+
export declare const getTooltipFormatter: ({ params, buckets, bucketWidth, selectedPrice, precision, bookType, labelCallback, }: {
|
|
23
|
+
params: unknown;
|
|
24
|
+
buckets: Bucket[][];
|
|
25
|
+
bucketWidth: number;
|
|
26
|
+
selectedPrice: number;
|
|
27
|
+
precision: number;
|
|
28
|
+
bookType: BookType;
|
|
29
|
+
labelCallback: (key: string) => string;
|
|
30
|
+
}) => string | undefined;
|
|
31
|
+
export declare const formatXAxisLabel: (value: unknown, isGreaterThanTwoWeeks: boolean) => string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GetOrderPositionBooksQuery } from '../../../../gql/types/graphql';
|
|
2
|
+
export declare const processOrderPositionBooks: (orderPositionData: GetOrderPositionBooksQuery | undefined, candleMap: Map<string, {
|
|
3
|
+
point?: string;
|
|
4
|
+
high?: number;
|
|
5
|
+
low?: number;
|
|
6
|
+
open?: number;
|
|
7
|
+
close?: number;
|
|
8
|
+
}>) => [string, number | null, number][];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GetPriceCandlesQuery } from '../../../../gql/types/graphql';
|
|
2
|
+
export declare const processPriceCandles: (priceCandlesData: GetPriceCandlesQuery | undefined) => {
|
|
3
|
+
minPrice: number;
|
|
4
|
+
maxPrice: number;
|
|
5
|
+
hasValidCandles: boolean;
|
|
6
|
+
candleMap: Map<any, any>;
|
|
7
|
+
candles: never[];
|
|
8
|
+
} | {
|
|
9
|
+
minPrice: number;
|
|
10
|
+
maxPrice: number;
|
|
11
|
+
hasValidCandles: boolean;
|
|
12
|
+
candleMap: Map<string, {
|
|
13
|
+
point?: string;
|
|
14
|
+
high?: number;
|
|
15
|
+
low?: number;
|
|
16
|
+
open?: number;
|
|
17
|
+
close?: number;
|
|
18
|
+
}>;
|
|
19
|
+
candles: ({
|
|
20
|
+
__typename?: "Candle";
|
|
21
|
+
point: string;
|
|
22
|
+
high: number;
|
|
23
|
+
low: number;
|
|
24
|
+
open: number;
|
|
25
|
+
close: number;
|
|
26
|
+
} | null)[];
|
|
27
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { GetOrderPositionBooksQuery, GetPriceCandlesQuery } from '../../../../gql/types/graphql';
|
|
2
|
+
export declare const validateData: (priceCandlesData: GetPriceCandlesQuery | undefined, orderPositionData: GetOrderPositionBooksQuery | undefined, hasValidCandles: boolean) => Error | null;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { BookType } from '../../../gql/types/graphql';
|
|
2
3
|
interface LegendProps {
|
|
3
4
|
longValues?: [number, number];
|
|
4
5
|
shortValues?: [number, number];
|
|
6
|
+
bookType: BookType;
|
|
5
7
|
}
|
|
6
|
-
export declare const Legend: ({ longValues, shortValues, }: LegendProps) => React.JSX.Element;
|
|
8
|
+
export declare const Legend: ({ longValues, shortValues, bookType, }: LegendProps) => React.JSX.Element;
|
|
7
9
|
export {};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { InstrumentId } from './types';
|
|
1
2
|
export declare const BOOKS_THRESHOLDS: {
|
|
2
3
|
readonly MIN: 0.15;
|
|
3
4
|
readonly MAX: 0.55;
|
|
4
5
|
};
|
|
5
6
|
export declare const BUCKET_CONFIG: {
|
|
6
|
-
readonly
|
|
7
|
+
readonly MULTIPLIER: 4;
|
|
7
8
|
readonly PRICE_PADDING_MULTIPLIER: 2;
|
|
8
9
|
};
|
|
9
10
|
export declare const TIME_THRESHOLDS: {
|
|
@@ -16,8 +17,15 @@ export declare const CHART_CONFIG: {
|
|
|
16
17
|
readonly Y_LABEL_SIZE_DESKTOP: 60;
|
|
17
18
|
readonly INITIAL_START_ZOOM: 80;
|
|
18
19
|
readonly INITIAL_END_ZOOM: 100;
|
|
20
|
+
readonly X_AXIS_DATE_PADDING: " ";
|
|
19
21
|
};
|
|
20
22
|
export declare const COLOR_MAP: {
|
|
21
|
-
readonly long: readonly ["#
|
|
22
|
-
readonly short: readonly ["#
|
|
23
|
+
readonly long: readonly ["#eaf5fa", "#83c4e0"];
|
|
24
|
+
readonly short: readonly ["#fef7e7", "#fcd171"];
|
|
23
25
|
};
|
|
26
|
+
export declare const INSTRUMENTS_CONFIG: Record<InstrumentId, {
|
|
27
|
+
precision: number;
|
|
28
|
+
defaultBucketWidth: number;
|
|
29
|
+
v20name: string;
|
|
30
|
+
mt5name: string;
|
|
31
|
+
}>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { BookType, Granularity } from '../gql/types/graphql';
|
|
2
|
-
import { InstrumentId
|
|
2
|
+
import { InstrumentId } from './types';
|
|
3
3
|
declare const navigationConfig: {
|
|
4
4
|
id: BookType;
|
|
5
5
|
label: string;
|
|
6
6
|
}[];
|
|
7
7
|
declare const instrumentSelectConfigOC: {
|
|
8
|
-
id:
|
|
8
|
+
id: InstrumentId;
|
|
9
9
|
label: string;
|
|
10
10
|
}[];
|
|
11
11
|
declare const instrumentSelectConfig: {
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import type { WidgetConfig } from '@oanda/labs-widget-common';
|
|
2
2
|
import type { Division } from '../gql/types/graphql';
|
|
3
|
-
|
|
3
|
+
export declare enum InstrumentId {
|
|
4
|
+
EUR_AUD = "EURAUD",
|
|
5
|
+
EUR_GBP = "EURGBP",
|
|
6
|
+
EUR_JPY = "EURJPY",
|
|
7
|
+
EUR_USD = "EURUSD",
|
|
8
|
+
EUR_CHF = "EURCHF",
|
|
9
|
+
USD_CHF = "USDCHF",
|
|
10
|
+
USD_JPY = "USDJPY",
|
|
11
|
+
USD_CAD = "USDCAD",
|
|
12
|
+
GBP_USD = "GBPUSD",
|
|
13
|
+
GBP_JPY = "GBPJPY",
|
|
14
|
+
GBP_CHF = "GBPCHF",
|
|
15
|
+
AUD_JPY = "AUDJPY",
|
|
16
|
+
AUD_USD = "AUDUSD",
|
|
17
|
+
NZD_USD = "NZDUSD",
|
|
18
|
+
XAU_USD = "XAUUSD",
|
|
19
|
+
XAG_USD = "XAGUSD"
|
|
20
|
+
}
|
|
4
21
|
export interface CrowdViewConfig extends WidgetConfig {
|
|
5
22
|
division: Division;
|
|
6
23
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { Division } from '../../gql/types/graphql';
|
|
2
2
|
export declare const getInstrumentConfigForDivision: (division: Division) => {
|
|
3
|
-
id: import("
|
|
4
|
-
label: string;
|
|
5
|
-
}[] | {
|
|
6
|
-
id: import("../types").InstrumentId;
|
|
3
|
+
id: import("..").InstrumentId;
|
|
7
4
|
label: string;
|
|
8
5
|
}[];
|
package/lokalise.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oanda/labs-crowd-view-widget",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.46",
|
|
4
4
|
"description": "Labs Crowd View Widget",
|
|
5
5
|
"main": "dist/main/index.js",
|
|
6
6
|
"module": "dist/module/index.js",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"author": "OANDA",
|
|
14
14
|
"license": "UNLICENSED",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@oanda/labs-widget-common": "^1.0.
|
|
16
|
+
"@oanda/labs-widget-common": "^1.0.228",
|
|
17
17
|
"@oanda/mono-i18n": "10.0.1",
|
|
18
18
|
"chroma-js": "^3.1.2",
|
|
19
|
+
"decimal.js": "^10.6.0",
|
|
19
20
|
"graphql": "16.8.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
@@ -23,5 +24,5 @@
|
|
|
23
24
|
"@graphql-codegen/client-preset": "4.1.0",
|
|
24
25
|
"@types/chroma-js": "^3.1.2"
|
|
25
26
|
},
|
|
26
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "8e6597b98667ce51cc5610dddc94f020a2a82908"
|
|
27
28
|
}
|
|
@@ -6,29 +6,44 @@ import {
|
|
|
6
6
|
useLayoutProvider,
|
|
7
7
|
} from '@oanda/labs-widget-common';
|
|
8
8
|
import { useLocale } from '@oanda/mono-i18n';
|
|
9
|
-
import React, { useState } from 'react';
|
|
9
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
11
|
import type { Granularity } from '../gql/types/graphql';
|
|
12
12
|
import { BookType } from '../gql/types/graphql';
|
|
13
13
|
import { ChartWithData, Legend } from './components';
|
|
14
14
|
import { granularitySelectConfig, navigationConfig } from './selectConfig';
|
|
15
|
-
import type { MainProps } from './types';
|
|
16
|
-
import type { InstrumentId } from './types/instruments';
|
|
15
|
+
import type { InstrumentId, MainProps } from './types';
|
|
17
16
|
import { getInstrumentConfigForDivision } from './utils/instrumentUtils';
|
|
18
17
|
|
|
19
18
|
const Main = ({ division }: MainProps) => {
|
|
20
|
-
const
|
|
21
|
-
getInstrumentConfigForDivision(division);
|
|
22
|
-
|
|
19
|
+
const { lang } = useLocale();
|
|
23
20
|
const { size } = useLayoutProvider();
|
|
24
21
|
const isDesktop = size === Size.DESKTOP;
|
|
22
|
+
|
|
25
23
|
const [bookType, setBookType] = useState(BookType.Order);
|
|
24
|
+
|
|
25
|
+
const granularitySelectConfigWithLang = useMemo(
|
|
26
|
+
() =>
|
|
27
|
+
granularitySelectConfig.map((opt) => ({
|
|
28
|
+
...opt,
|
|
29
|
+
label: lang(opt.label),
|
|
30
|
+
})),
|
|
31
|
+
[lang]
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const instrumentSelectConfigWithDivision =
|
|
35
|
+
getInstrumentConfigForDivision(division);
|
|
26
36
|
const [instrument, setInstrument] = useState(
|
|
27
37
|
instrumentSelectConfigWithDivision[0]
|
|
28
38
|
);
|
|
29
39
|
|
|
30
|
-
const [granularity, setGranularity] = useState(
|
|
31
|
-
|
|
40
|
+
const [granularity, setGranularity] = useState(
|
|
41
|
+
granularitySelectConfigWithLang[0]
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
setGranularity(granularitySelectConfigWithLang[0]);
|
|
46
|
+
}, [granularitySelectConfigWithLang]);
|
|
32
47
|
|
|
33
48
|
return (
|
|
34
49
|
<>
|
|
@@ -68,7 +83,7 @@ const Main = ({ division }: MainProps) => {
|
|
|
68
83
|
})}
|
|
69
84
|
>
|
|
70
85
|
<Select
|
|
71
|
-
options={
|
|
86
|
+
options={granularitySelectConfigWithLang}
|
|
72
87
|
searchPlaceholder={lang('search')}
|
|
73
88
|
selectLabel={lang('granularity')}
|
|
74
89
|
selectedOption={granularity}
|
|
@@ -86,7 +101,7 @@ const Main = ({ division }: MainProps) => {
|
|
|
86
101
|
instrument={instrument.id}
|
|
87
102
|
/>
|
|
88
103
|
|
|
89
|
-
<Legend />
|
|
104
|
+
<Legend bookType={bookType} />
|
|
90
105
|
</div>
|
|
91
106
|
)}
|
|
92
107
|
</>
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Theme,
|
|
5
5
|
useLayoutProvider,
|
|
6
6
|
} from '@oanda/labs-widget-common';
|
|
7
|
+
import { useLocale } from '@oanda/mono-i18n';
|
|
7
8
|
import type { EChartsType } from 'echarts';
|
|
8
9
|
import {
|
|
9
10
|
BarChart,
|
|
@@ -26,6 +27,7 @@ import { CHART_CONFIG } from '../../constants';
|
|
|
26
27
|
import { getOption } from './chartOptions';
|
|
27
28
|
import type { ChartProps } from './types';
|
|
28
29
|
import {
|
|
30
|
+
formatXAxisLabel,
|
|
29
31
|
getLabelData,
|
|
30
32
|
isDifferenceGreaterThanTwoWeeks,
|
|
31
33
|
} from './utils/chartUtils';
|
|
@@ -48,6 +50,7 @@ echarts.registerTheme('light_theme', getChartTheme(Theme.Light));
|
|
|
48
50
|
|
|
49
51
|
const Chart = ({ data }: ChartProps) => {
|
|
50
52
|
const { isDark } = useLayoutProvider();
|
|
53
|
+
const { lang } = useLocale();
|
|
51
54
|
|
|
52
55
|
return (
|
|
53
56
|
<BaseChart
|
|
@@ -55,7 +58,7 @@ const Chart = ({ data }: ChartProps) => {
|
|
|
55
58
|
echarts={echarts}
|
|
56
59
|
isDark={isDark}
|
|
57
60
|
lazyUpdate={true}
|
|
58
|
-
option={getOption(data, isDark)}
|
|
61
|
+
option={getOption(data, isDark, lang)}
|
|
59
62
|
opts={{ renderer: 'canvas' }}
|
|
60
63
|
onEvents={{
|
|
61
64
|
datazoom: (_params: unknown, instance: EChartsType) => {
|
|
@@ -78,17 +81,8 @@ const Chart = ({ data }: ChartProps) => {
|
|
|
78
81
|
instance.setOption({
|
|
79
82
|
xAxis: {
|
|
80
83
|
axisLabel: {
|
|
81
|
-
formatter: (value: string) =>
|
|
82
|
-
|
|
83
|
-
return isGreaterThanTwoWeeks
|
|
84
|
-
? `${date.toLocaleTimeString(undefined, {
|
|
85
|
-
hour: '2-digit',
|
|
86
|
-
minute: '2-digit',
|
|
87
|
-
})}`
|
|
88
|
-
: `${date.toLocaleDateString(undefined, {
|
|
89
|
-
day: 'numeric',
|
|
90
|
-
})}`;
|
|
91
|
-
},
|
|
84
|
+
formatter: (value: string) =>
|
|
85
|
+
formatXAxisLabel(value, isGreaterThanTwoWeeks),
|
|
92
86
|
},
|
|
93
87
|
},
|
|
94
88
|
series: [
|
|
@@ -5,18 +5,30 @@ import {
|
|
|
5
5
|
} from '@oanda/labs-widget-common';
|
|
6
6
|
|
|
7
7
|
import { CHART_CONFIG } from '../../constants';
|
|
8
|
-
import type { GetOptionType } from './types';
|
|
8
|
+
import type { Bucket, GetOptionType } from './types';
|
|
9
9
|
import {
|
|
10
|
+
formatXAxisLabel,
|
|
10
11
|
getLabelData,
|
|
11
12
|
getRectColor,
|
|
13
|
+
getTooltipFormatter,
|
|
12
14
|
isDifferenceGreaterThanTwoWeeks,
|
|
13
15
|
} from './utils/chartUtils';
|
|
14
16
|
|
|
15
17
|
// @ts-expect-error
|
|
16
18
|
export const getOption: GetOptionType = (
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
+
{
|
|
20
|
+
xAxisData,
|
|
21
|
+
candlesSeriesData,
|
|
22
|
+
orderPositionBooks,
|
|
23
|
+
bucketWidth,
|
|
24
|
+
buckets,
|
|
25
|
+
precision,
|
|
26
|
+
bookType,
|
|
27
|
+
},
|
|
28
|
+
isDark,
|
|
29
|
+
labelCallback
|
|
19
30
|
) => {
|
|
31
|
+
let selectedPrice: number;
|
|
20
32
|
const visibleXAxisData = xAxisData.slice(
|
|
21
33
|
(xAxisData.length * CHART_CONFIG.INITIAL_START_ZOOM) / 100,
|
|
22
34
|
(xAxisData.length * CHART_CONFIG.INITIAL_END_ZOOM) / 100
|
|
@@ -55,29 +67,51 @@ export const getOption: GetOptionType = (
|
|
|
55
67
|
trigger: 'axis',
|
|
56
68
|
axisPointer: {
|
|
57
69
|
type: 'cross',
|
|
70
|
+
axis: 'x',
|
|
71
|
+
label: {
|
|
72
|
+
formatter: (params) => {
|
|
73
|
+
if (params.axisDimension === 'y') {
|
|
74
|
+
selectedPrice = Number(params.value);
|
|
75
|
+
return Number(params.value).toFixed(precision);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (params.axisDimension === 'x') {
|
|
79
|
+
const date = new Date(params.value as string);
|
|
80
|
+
return date.toLocaleString(undefined, {
|
|
81
|
+
hour: '2-digit',
|
|
82
|
+
minute: '2-digit',
|
|
83
|
+
day: 'numeric',
|
|
84
|
+
month: 'short',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return null;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
58
91
|
},
|
|
92
|
+
confine: true,
|
|
93
|
+
formatter: (params) =>
|
|
94
|
+
getTooltipFormatter({
|
|
95
|
+
params,
|
|
96
|
+
buckets,
|
|
97
|
+
bucketWidth,
|
|
98
|
+
selectedPrice,
|
|
99
|
+
labelCallback,
|
|
100
|
+
precision,
|
|
101
|
+
bookType,
|
|
102
|
+
}),
|
|
59
103
|
},
|
|
60
104
|
xAxis: {
|
|
61
105
|
type: 'category',
|
|
62
106
|
data: xAxisData,
|
|
107
|
+
splitNumber: 1,
|
|
63
108
|
axisTick: {
|
|
64
109
|
show: false,
|
|
65
110
|
},
|
|
66
111
|
axisLabel: {
|
|
67
112
|
padding: [8, 16, 8, 16],
|
|
68
113
|
margin: 0,
|
|
69
|
-
|
|
70
|
-
formatter: (value) => {
|
|
71
|
-
const date = new Date(value as string);
|
|
72
|
-
return isGreaterThanTwoWeeks
|
|
73
|
-
? `${date.toLocaleTimeString(undefined, {
|
|
74
|
-
hour: '2-digit',
|
|
75
|
-
minute: '2-digit',
|
|
76
|
-
})}`
|
|
77
|
-
: `${date.toLocaleDateString(undefined, {
|
|
78
|
-
day: 'numeric',
|
|
79
|
-
})}`;
|
|
80
|
-
},
|
|
114
|
+
formatter: (value) => formatXAxisLabel(value, isGreaterThanTwoWeeks),
|
|
81
115
|
},
|
|
82
116
|
},
|
|
83
117
|
yAxis: {
|
|
@@ -90,6 +124,7 @@ export const getOption: GetOptionType = (
|
|
|
90
124
|
axisLabel: {
|
|
91
125
|
showMaxLabel: false,
|
|
92
126
|
showMinLabel: false,
|
|
127
|
+
formatter: (value: number) => value.toFixed(precision - 1),
|
|
93
128
|
},
|
|
94
129
|
},
|
|
95
130
|
series: [
|
|
@@ -101,6 +136,7 @@ export const getOption: GetOptionType = (
|
|
|
101
136
|
color: colorPalette.raspberryLight,
|
|
102
137
|
color0: colorPalette.bottleGreenLight,
|
|
103
138
|
},
|
|
139
|
+
|
|
104
140
|
markPoint: {
|
|
105
141
|
symbol: 'circle',
|
|
106
142
|
symbolSize: 0,
|
|
@@ -115,34 +151,32 @@ export const getOption: GetOptionType = (
|
|
|
115
151
|
clip: true,
|
|
116
152
|
renderItem: (_params, api) => {
|
|
117
153
|
const xVal = api.value(0);
|
|
118
|
-
const
|
|
154
|
+
const bucketIndex = api.value(2) as number;
|
|
155
|
+
const metaValues = buckets[bucketIndex];
|
|
119
156
|
|
|
120
157
|
const [rectWidth, rectHeight] = api.size!([
|
|
121
158
|
0,
|
|
122
159
|
bucketWidth,
|
|
123
160
|
]) as number[];
|
|
124
161
|
|
|
125
|
-
const items = metaValues.map(
|
|
126
|
-
|
|
127
|
-
const start = api.coord([xVal, price]);
|
|
162
|
+
const items = metaValues.map(({ price, sentiment }: Bucket) => {
|
|
163
|
+
const start = api.coord([xVal, price]);
|
|
128
164
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
);
|
|
165
|
+
return {
|
|
166
|
+
type: 'rect',
|
|
167
|
+
shape: {
|
|
168
|
+
x: start[0] - rectWidth / 2,
|
|
169
|
+
y: start[1] - rectHeight,
|
|
170
|
+
width: rectWidth + 1,
|
|
171
|
+
height: rectHeight,
|
|
172
|
+
},
|
|
173
|
+
style: {
|
|
174
|
+
fill: getRectColor(sentiment),
|
|
175
|
+
},
|
|
176
|
+
silent: true,
|
|
177
|
+
emphasisDisabled: true,
|
|
178
|
+
};
|
|
179
|
+
});
|
|
146
180
|
|
|
147
181
|
return {
|
|
148
182
|
type: 'group',
|