Skip to content

Commit

Permalink
Merge pull request #1137 from bancorprotocol/simulator/overlapping
Browse files Browse the repository at this point in the history
Add simulator overlapping
  • Loading branch information
pingustar committed Apr 15, 2024
2 parents c972a5f + a2e01be commit b77bc7d
Show file tree
Hide file tree
Showing 109 changed files with 2,508 additions and 868 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/strategy/overlapping/Overlapping/create/form.jpg
4 changes: 2 additions & 2 deletions src/assets/icons/action.svg
8 changes: 4 additions & 4 deletions src/components/activity/ActivityFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ export const ActivityFilter: FC<ActivityFilterProps> = (props) => {
const updateParams = () => {
const selector = `input[form="${formId}"]`;
const inputs = document.querySelectorAll<HTMLInputElement>(selector);
const params: Record<string, string[]> = {};
const params: Record<string, string[] | string> = {};
for (const input of inputs) {
const name = input.name;
params[name] ||= [];
if (input.type === 'checkbox') {
if (input.checked) params[name].push(input.value);
params[name] ||= [];
if (input.checked) (params[name] as string[]).push(input.value);
} else {
params[name].push(input.value);
params[name] = input.value;
}
}
setSearchParams(params);
Expand Down
18 changes: 12 additions & 6 deletions src/components/common/datePicker/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface Props {
options?: Omit<CalendarProps, 'mode' | 'selected' | 'onSelect'>;
required?: boolean;
form?: string;
disabled?: boolean;
}

const displayRange = (start?: Date, end?: Date) => {
Expand All @@ -65,9 +66,12 @@ export const DateRangePicker = memo((props: Omit<Props, 'setIsOpen'>) => {
'hover:bg-background-800',
hasDates
? 'border-primary active:border-primary-light'
: 'border-background-800 hover:border-background-700 active:border-background-600'
: 'border-background-800 hover:border-background-700 active:border-background-600',
props.disabled &&
'cursor-not-allowed border-background-800 hover:border-background-800 hover:bg-transparent active:border-background-800'
)}
data-testid="date-picker-button"
disabled={props.disabled}
>
<CalendarIcon className="h-14 w-14 text-primary" />
<span
Expand All @@ -76,11 +80,13 @@ export const DateRangePicker = memo((props: Omit<Props, 'setIsOpen'>) => {
>
{displayRange(props.start, props.end)}
</span>
<ChevronIcon
className={cn('h-12 w-12 text-white/80 transition-transform', {
'rotate-180': isOpen,
})}
/>
{!props.disabled && (
<ChevronIcon
className={cn('h-12 w-12 text-white/80 transition-transform', {
'rotate-180': isOpen,
})}
/>
)}
</button>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ export const LimitRangeSection: FC<Props> = ({
ignoreMarketPriceWarning,
}) => {
const { isRange } = order;
const { marketPricePercentage, isOrderAboveOrBelowMarketPrice } =
useMarketIndication({
base,
quote,
order: { ...order, price: order.min },
buy,
});
const { isOrderAboveOrBelowMarketPrice } = useMarketIndication({
base,
quote,
order: { ...order, price: order.min },
buy,
});

const overlappingOrdersPricesMessage =
'Notice: your Buy and Sell orders overlap';
Expand Down Expand Up @@ -81,7 +80,6 @@ export const LimitRangeSection: FC<Props> = ({
quote={quote}
base={base}
buy={buy}
marketPricePercentages={marketPricePercentage}
ignoreMarketPriceWarning={ignoreMarketPriceWarning}
isOrdersReversed={isOrdersReversed}
warnings={getWarnings()}
Expand All @@ -98,7 +96,6 @@ export const LimitRangeSection: FC<Props> = ({
error={order.priceError}
setPriceError={setPriceError}
buy={buy}
marketPricePercentage={marketPricePercentage}
ignoreMarketPriceWarning={ignoreMarketPriceWarning}
isOrdersReversed={isOrdersReversed}
warnings={getWarnings()}
Expand Down
87 changes: 18 additions & 69 deletions src/components/simulator/input/SimInputChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,35 @@ import {
} from 'components/common/datePicker/DateRangePicker';
import { IconTitleText } from 'components/common/iconTitleText/IconTitleText';
import { datePickerDisabledDays } from 'components/simulator/result/SimResultChartHeader';
import { SimulatorInputDispatch } from 'hooks/useSimulatorInput';
import {
SimulatorInputOverlappingValues,
SimulatorOverlappingInputDispatch,
} from 'hooks/useSimulatorOverlappingInput';
import { StrategyInputValues } from 'hooks/useStrategyInput';
import {
ChartPrices,
D3ChartCandlesticks,
OnPriceUpdates,
} from 'components/simulator/input/d3Chart';
import { useCompareTokenPrice } from 'libs/queries/extApi/tokenPrice';
import { StrategyDirection } from 'libs/routing';
import { SafeDecimal } from 'libs/safedecimal';
import { Dispatch, SetStateAction, useCallback, useEffect } from 'react';
import { SimulatorType } from 'libs/routing/routes/sim';
import { useCallback } from 'react';
import { ReactComponent as IconPlus } from 'assets/icons/plus.svg';
import { CandlestickData, D3ChartSettingsProps, D3ChartWrapper } from 'libs/d3';
import { fromUnixUTC, toUnixUTC } from '../utils';
import { useStore } from 'store';
import { startOfDay, sub } from 'date-fns';

interface Props {
state: StrategyInputValues;
dispatch: SimulatorInputDispatch;
initBuyRange: boolean;
initSellRange: boolean;
setInitBuyRange: Dispatch<SetStateAction<boolean>>;
setInitSellRange: Dispatch<SetStateAction<boolean>>;
state: StrategyInputValues | SimulatorInputOverlappingValues;
dispatch: SimulatorOverlappingInputDispatch;
isLimit?: { buy: boolean; sell: boolean };
spread?: string;
bounds: ChartPrices;
data?: CandlestickData[];
isLoading: boolean;
isError: boolean;
simulationType: SimulatorType;
}

const chartSettings: D3ChartSettingsProps = {
Expand All @@ -49,71 +50,20 @@ const chartSettings: D3ChartSettingsProps = {
export const SimInputChart = ({
state,
dispatch,
initBuyRange,
initSellRange,
setInitBuyRange,
setInitSellRange,
isLimit,
spread,
bounds,
isLoading,
isError,
data,
simulationType,
}: Props) => {
const { debug } = useStore();
const marketPrice = useCompareTokenPrice(
state.baseToken?.address,
state.quoteToken?.address
);

const handleDefaultValues = useCallback(
(type: StrategyDirection) => {
const init = type === 'buy' ? initBuyRange : initSellRange;
const setInit = type === 'buy' ? setInitBuyRange : setInitSellRange;

if (!marketPrice || !init) return;
setInit(false);

if (!(!state[type].max && !state[type].min)) {
return;
}

const operation = type === 'buy' ? 'minus' : 'plus';

const multiplierMax = type === 'buy' ? 0.1 : 0.2;
const multiplierMin = type === 'buy' ? 0.2 : 0.1;

const max = new SafeDecimal(marketPrice)
[operation](marketPrice * multiplierMax)
.toFixed();

const min = new SafeDecimal(marketPrice)
[operation](marketPrice * multiplierMin)
.toFixed();

if (state[type].isRange) {
dispatch(`${type}Max`, max);
dispatch(`${type}Min`, min);
} else {
const value = type === 'buy' ? max : min;
dispatch(`${type}Max`, value);
dispatch(`${type}Min`, value);
}
},
[
dispatch,
initBuyRange,
initSellRange,
marketPrice,
setInitBuyRange,
setInitSellRange,
state,
]
);

useEffect(() => {
handleDefaultValues('buy');
handleDefaultValues('sell');
}, [handleDefaultValues]);

const prices = {
buy: {
min: state.buy.min,
Expand Down Expand Up @@ -155,7 +105,7 @@ export const SimInputChart = ({
);

return (
<div className="align-stretch sticky top-80 grid h-[calc(100vh-180px)] min-h-[500px] flex-1 grid-rows-[auto_1fr] justify-items-stretch rounded-12 bg-background-900 p-20">
<div className="align-stretch top-120 fixed right-20 grid h-[calc(100vh-220px)] min-h-[500px] w-[calc(100%-500px)] flex-1 grid-rows-[auto_1fr] justify-items-stretch rounded-12 bg-background-900 p-20">
<div className="mb-20 flex items-center justify-between">
<h2 className="mr-20 text-20 font-weight-500">Price Chart</h2>
<DateRangePicker
Expand Down Expand Up @@ -197,10 +147,9 @@ export const SimInputChart = ({
marketPrice={marketPrice}
bounds={bounds}
onDragEnd={onPriceUpdatesEnd}
isLimit={{
buy: !state.buy.isRange,
sell: !state.sell.isRange,
}}
isLimit={isLimit}
type={simulationType}
overlappingSpread={spread}
/>
)}
</D3ChartWrapper>
Expand Down
7 changes: 0 additions & 7 deletions src/components/simulator/input/SimInputOverlapping.tsx

This file was deleted.

50 changes: 28 additions & 22 deletions src/components/simulator/input/SimInputStrategyType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ import { cn } from 'utils/helpers';
import { SimulatorType } from 'libs/routing/routes/sim';
import { Link } from 'libs/routing';

interface Props {
strategyType: SimulatorType;
}

interface ItemProps {
label: SimulatorType;
svg: JSX.Element;
tooltipText: string;
}

export const SimInputStrategyType: FC<Props> = ({ strategyType }) => {
interface Props {
baseToken?: string;
quoteToken?: string;
}

export const SimInputStrategyType: FC<Props> = ({ baseToken, quoteToken }) => {
const items: ItemProps[] = [
{
label: 'recurring',
Expand Down Expand Up @@ -46,33 +47,38 @@ export const SimInputStrategyType: FC<Props> = ({ strategyType }) => {
role="tab"
id={'tab-' + label}
aria-controls={'panel-' + label}
aria-selected={strategyType === label}
key={label}
to="/simulate/$simulationType"
to={`/simulate/${label}`}
search={{ baseToken, quoteToken }}
className={cn(
'flex h-full w-full flex-row items-center justify-center gap-8 rounded-10 bg-black px-8 py-16 text-14 font-weight-500 outline-white/60',
'md:px-12',
'focus-visible:outline focus-visible:outline-1',
strategyType === label ? 'outline outline-1 outline-white' : ''
'focus-visible:outline focus-visible:outline-1'
)}
activeProps={{ className: 'outline outline-1 outline-white' }}
replace={true}
resetScroll={false}
params={{ simulationType: label }}
data-testid={`select-type-${label}`}
>
{svg}
<span
className={`capitalize ${
strategyType === label ? 'text-white' : 'text-white/40'
}`}
>
{label}
</span>

<Tooltip
element={<div>{tooltipText}</div>}
iconClassName="!h-12 !w-12 text-white/60"
/>
{({ isActive }) => {
return (
<>
{svg}
<span
className={`capitalize ${
isActive ? 'text-white' : 'text-white/40'
}`}
>
{label}
</span>
<Tooltip
element={<div>{tooltipText}</div>}
iconClassName="!h-12 !w-12 text-white/60"
/>
</>
);
}}
</Link>
))}
</article>
Expand Down

0 comments on commit b77bc7d

Please sign in to comment.