Skip to content

Commit

Permalink
feat(trading): margin mode selector (#5660)
Browse files Browse the repository at this point in the history
Co-authored-by: Bartłomiej Głownia <[email protected]>
Co-authored-by: Dariusz Majcherczyk <[email protected]>
  • Loading branch information
3 people authored Jan 24, 2024
1 parent 053775b commit 261f32a
Show file tree
Hide file tree
Showing 37 changed files with 874 additions and 135 deletions.
1 change: 1 addition & 0 deletions apps/trading/.env
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
NX_ICEBERG_ORDERS=true
NX_METAMASK_SNAPS=true
NX_REFERRALS=true
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.capsule
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supp
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false
NX_ISOLATED_MARGIN=true
# NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=false
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.devnet
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
# NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=true
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.mainnet
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=false
NX_ICEBERG_ORDERS=true
NX_METAMASK_SNAPS=true
NX_REFERRALS=true
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.mainnet-mirror
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NX_APP_VERSION=v0.20.19-core-0.71.6
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=false
NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=false
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.stagnet1
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=true
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.testnet
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
NX_ICEBERG_ORDERS=true
NX_METAMASK_SNAPS=true
NX_REFERRALS=true
Expand Down
1 change: 1 addition & 0 deletions apps/trading/.env.validators-testnet
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=false
Expand Down
4 changes: 2 additions & 2 deletions apps/trading/e2e/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions apps/trading/e2e/tests/deal_ticket/test_isolated_cross_margin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from actions.vega import submit_order
from actions.utils import next_epoch, wait_for_toast_confirmation

tooltip_content = "tooltip-content"
leverage_input = "#leverage-input"
tab_positions = "tab-positions"
margin_row = '[col-id="margin"]'


def create_position(vega: VegaServiceNull, market_id):
submit_order(vega, "Key 1", market_id, "SIDE_SELL", 100, 110)
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 100, 110)
vega.wait_fn(1)
vega.wait_for_total_catchup


@pytest.mark.usefixtures("auth", "risk_accepted")
def test_switch_cross_isolated_margin(
continuous_market, vega: VegaServiceNull, page: Page):
create_position(vega, continuous_market)
page.goto(f"/#/markets/{continuous_market}")
expect(page.locator(margin_row).nth(1)).to_have_text("874.21992Cross1.0x")
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
page.get_by_test_id(tab_positions).get_by_text("Cross").hover()
expect(page.get_by_test_id(tooltip_content).nth(0)).to_have_text(
"Liquidation: 582.81328Margin: 874.21992General account: 998,084.95183"
)
page.get_by_role("button", name="Isolated 10x").click()
page.locator(leverage_input).clear()
page.locator(leverage_input).type("1")
page.get_by_role("button", name="Confirm").click()
wait_for_toast_confirmation(page)
next_epoch(vega=vega)
expect(page.get_by_test_id("toast-content")).to_have_text(
"ConfirmedYour transaction has been confirmedView in block explorerUpdate margin modeBTC:DAI_2023Isolated margin mode, leverage: 1.0x")
expect(page.locator(margin_row).nth(1)
).to_have_text("11,109.99996Isolated1.0x")
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
page.get_by_test_id(tab_positions).get_by_text("Isolated").hover()
expect(page.get_by_test_id(tooltip_content).nth(0)).to_have_text(
"Liquidation: 583.62409Margin: 11,109.99996Order: 11,000.00"
)
page.get_by_role("button", name="Cross").click()
page.get_by_role("button", name="Confirm").click()
wait_for_toast_confirmation(page)
next_epoch(vega=vega)
expect(page.locator(margin_row).nth(1)).to_have_text(
"22,109.99996Cross1.0x")
11 changes: 7 additions & 4 deletions apps/trading/e2e/tests/order/test_order_match.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ def verify_data_grid(page: Page, data_test_id, expected_pattern):
logger.info(f"Matched: {expected} == {actual}")
else:
logger.info(f"Not Matched: {expected} != {actual}")
raise AssertionError(f"Pattern does not match: {expected} != {actual}")
raise AssertionError(
f"Pattern does not match: {expected} != {actual}")
else: # it's not a regex, so we escape it
if re.search(re.escape(expected), actual):
logger.info(f"Matched: {expected} == {actual}")
else:
logger.info(f"Not Matched: {expected} != {actual}")
raise AssertionError(f"Pattern does not match: {expected} != {actual}")
raise AssertionError(
f"Pattern does not match: {expected} != {actual}")


def submit_order(vega: VegaServiceNull, wallet_name, market_id, side, volume, price):
Expand Down Expand Up @@ -91,7 +93,7 @@ def test_limit_order_trade_open_position(continuous_market, page: Page):
"average_entry_price": "107.50",
"mark_price": "107.50",
"margin": "8.50269",
"leverage": "1.0x",
"leverage": "Cross1.0x",
"liquidation": "0.00",
"realised_pnl": "0.00",
"unrealised_pnl": "0.00",
Expand All @@ -104,7 +106,8 @@ def test_limit_order_trade_open_position(continuous_market, page: Page):
# 7004-POSI-002

size_and_notional = table.locator("[col-id='openVolume']")
expect(size_and_notional.get_by_test_id(primary_id)).to_have_text(position["size"])
expect(size_and_notional.get_by_test_id(
primary_id)).to_have_text(position["size"])
expect(size_and_notional.get_by_test_id(secondary_id)).to_have_text(
position["notional"]
)
Expand Down
29 changes: 5 additions & 24 deletions apps/trading/e2e/tests/positions/test_collateral.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ def test_usage_breakdown(continuous_market, page: Page):
usage_breakdown = page.get_by_test_id("usage-breakdown")

# Verify headers
headers = ["Market", "Account type", "Balance", "Margin health"]
ag_headers = usage_breakdown.locator(".ag-header-cell-text").element_handles()
headers = ["Market", "Account type", "Balance"]
ag_headers = usage_breakdown.locator(
".ag-header-cell-text").element_handles()
for i, header_element in enumerate(ag_headers):
header_text = header_element.text_content()
assert header_text == headers[i]
Expand All @@ -38,30 +39,10 @@ def test_usage_breakdown(continuous_market, page: Page):
expect(usage_breakdown.locator('[class="mb-2 text-sm"]')).to_have_text(
"You have 1,000,000.00 tDAI in total."
)
expect(usage_breakdown.locator(COL_ID_USED).first).to_have_text("8.50269 (0%)")
expect(usage_breakdown.locator(
COL_ID_USED).first).to_have_text("8.50269 (0%)")
expect(usage_breakdown.locator(COL_ID_USED).nth(1)).to_have_text(
"999,991.49731 (99%)"
)

# Maintenance Level
expect(
usage_breakdown.locator(
".ag-center-cols-container [col-id='market.id'] .ag-cell-value"
).first
).to_have_text("2.85556 above maintenance level")

# Margin health tooltip
usage_breakdown.get_by_test_id("margin-health-chart-track").hover()
tooltip_data = [
("maintenance level", "5.64713"),
("search level", "6.21184"),
("initial level", "8.47069"),
("balance", "8.50269"),
("release level", "9.60012"),
]

for index, (label, value) in enumerate(tooltip_data):
expect(page.get_by_test_id(TOOLTIP_LABEL).nth(index)).to_have_text(label)
expect(page.get_by_test_id(TOOLTIP_VALUE).nth(index)).to_have_text(value)

page.get_by_test_id("dialog-close").click()
6 changes: 6 additions & 0 deletions libs/accounts/src/lib/Margins.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ fragment MarginFields on MarginLevels {
searchLevel
initialLevel
collateralReleaseLevel
marginFactor
marginMode
orderMarginLevel
asset {
id
}
Expand Down Expand Up @@ -33,6 +36,9 @@ subscription MarginsSubscription($partyId: ID!) {
searchLevel
initialLevel
collateralReleaseLevel
marginFactor
marginMode
orderMarginLevel
timestamp
}
}
12 changes: 9 additions & 3 deletions libs/accounts/src/lib/__generated__/Margins.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/accounts/src/lib/accounts-data-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export interface AccountFields extends Account {
// The total balance of these accounts will be used for the 'used' column in the
// collateral table
const USE_ACCOUNT_TYPES = [
AccountType.ACCOUNT_TYPE_ORDER_MARGIN,
AccountType.ACCOUNT_TYPE_MARGIN,
AccountType.ACCOUNT_TYPE_BOND,
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
Expand Down
30 changes: 2 additions & 28 deletions libs/accounts/src/lib/breakdown-table.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ import * as Types from '@vegaprotocol/types';
import type { AccountFields } from './accounts-data-provider';
import { getAccountData } from './accounts-data-provider';

const marginHealthChartTestId = 'margin-health-chart';

jest.mock('./margin-health-chart', () => ({
MarginHealthChart: () => {
return <div data-testid={marginHealthChartTestId}></div>;
},
}));

const singleRow = {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
Expand Down Expand Up @@ -49,10 +41,10 @@ describe('BreakdownTable', () => {
render(<BreakdownTable data={singleRowData} />);
});
const headers = await screen.findAllByRole('columnheader');
expect(headers).toHaveLength(4);
expect(headers).toHaveLength(3);
expect(
headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim())
).toEqual(['Market', 'Account type', 'Balance', 'Margin health']);
).toEqual(['Market', 'Account type', 'Balance']);
});

it('should apply correct formatting', async () => {
Expand All @@ -70,24 +62,6 @@ describe('BreakdownTable', () => {
cells.slice(0, -1).forEach((cell, i) => {
expect(cell).toHaveTextContent(expectedValues[i]);
});
expect(screen.getByTestId(marginHealthChartTestId)).toBeInTheDocument();
});

it('displays margin health chart only for margin account', async () => {
await act(async () => {
render(
<BreakdownTable
data={[
{
...singleRow,
type: Types.AccountType.ACCOUNT_TYPE_GENERAL,
market: null,
},
]}
/>
);
});
expect(screen.queryByTestId(marginHealthChartTestId)).toBeNull();
});

it('should get correct account data', () => {
Expand Down
20 changes: 1 addition & 19 deletions libs/accounts/src/lib/breakdown-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import { ProgressBarCell } from '@vegaprotocol/datagrid';
import { AgGrid, PriceCell } from '@vegaprotocol/datagrid';
import type { ColDef } from 'ag-grid-community';
import { accountValuesComparator } from './accounts-table';
import { MarginHealthChart } from './margin-health-chart';
import { MarketNameCell } from '@vegaprotocol/datagrid';
import { AccountType } from '@vegaprotocol/types';

const defaultColDef = {
resizable: true,
sortable: true,
minWidth: 100,
flex: 1,
};

interface BreakdownTableProps extends AgGridReactProps {
Expand Down Expand Up @@ -111,23 +110,6 @@ const BreakdownTable = forwardRef<AgGridReact, BreakdownTableProps>(
},
comparator: accountValuesComparator,
},
{
headerName: t('Margin health'),
field: 'market.id',
maxWidth: 500,
sortable: false,
cellRenderer: ({
data,
}: VegaICellRendererParams<AccountFields, 'market.id'>) =>
data?.market?.id &&
data.type === AccountType['ACCOUNT_TYPE_MARGIN'] &&
data?.asset.id ? (
<MarginHealthChart
marketId={data.market.id}
assetId={data.asset.id}
/>
) : null,
},
];
return defs;
}, [t]);
Expand Down
Loading

0 comments on commit 261f32a

Please sign in to comment.