Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/components/Trading/Position/AddRemoveMarginModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { useState, useEffect } from 'react';
import { Modal, Button, InputNumber, Alert } from 'antd';
import { usePosition } from '@/hooks/usePosition';
import { Position } from '@/types';

interface AddRemoveMarginProps {
position: Position;
isVisible: boolean;
onClose: () => void;
currentLiquidationPrice: number;
newLiquidationPrice: number;
}

const [currentLiquidationPrice, setCurrentLiquidationPrice] = useState<number>(0);
const [newLiquidationPrice, setNewLiquidationPrice] = useState<number>(0);
const [amount, setAmount] = useState<number>(0);
const [isAdding, setIsAdding] = useState<boolean>(true);

useEffect(() => {
if (position) {
setCurrentLiquidationPrice(position.liquidationPrice || 0);
const newPrice = calculateNewLiquidationPrice(position, amount, isAdding);
setNewLiquidationPrice(newPrice);
}
}, [position, amount, isAdding]);

const calculateNewLiquidationPrice = (pos: any, marginChange: number, adding: boolean) => {
// This is a simplified calculation - in a real implementation this would use
// the exchange's specific liquidation price formula
if (pos && pos.liquidationPrice) {
return adding ? pos.liquidationPrice + 0.1 :
Math.max(0, pos.liquidationPrice - 0.1);
}
return pos?.liquidationPrice || 0;
};

const handleAmountChange = (value: number) => {
setAmount(value);
};

const handleTypeChange = (isAdd: boolean) => {
setIsAdding(isAdd);
};

return { currentLiquidationPrice, newLiquidationValue };
};

return (
<Modal title={`${isAdding ? 'Add' : 'Remove'} Margin`}>
<div>
<div>Current Liquidation Price: {currentLiquidationPrice.toFixed(2)}</div>
<div>New Liquidation Price: {newLiquidationPrice.toFixed(2)}</div>
</div>
</Modal>
);
};

export default AddRemoveMargin;
import React, { useState } from 'react';
import { Modal, Button } from 'antd';

interface Props {
position: any;
onConfirm: (amount: number, isAdding: boolean) => void;
onCancel: () => void;
}

const AddRemoveMargin: React.FC<Props> = ({ position, onConfirm, onCancel }) => {
const [amount, setAmount] = useState<number>(0);
const [isAdding, setIsAdding] = useState<boolean>(true);

const currentLiquidationPrice = position?.liquidationPrice || 0;
const newLiquidationPrice = currentLiquidationPrice ?
(isAdding ? currentLiquidationPrice + (amount * 0.1) :
Math.max(0, currentLiquidationPrice - (amount * 0.1))) : 0;

return (
<Modal
title={`${isAdding ? 'Add' : 'Remove'} Margin`}
>
<div>
<div>Current Liquidation Price: {currentLiquidationPrice.toFixed(2)}</div>
<div>New Liquidation Price: {newLiquidationPrice.toFixed(2)}</div>
</div>
</Modal>
);
};

export default AddRemoveMargin;
50 changes: 50 additions & 0 deletions src/components/modals/AddMargin.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script>
import { onMount } from 'svelte'
import { submitAddMargin, submitRemoveMargin } from '@api'
import { getLiquidationPrice } from '@lib/utils'
import { addMarginAmount, removeMarginAmount } from '@lib/stores'
import { showToast } from '@lib/ui'
import { focusInput } from '@lib/utils'
let loading = false
let errors = {}

$: newLiquidationPrice = data.isAdding ? getLiquidationPrice(data.position, $addMarginAmount) : getLiquidationPrice(data.position, -$removeMarginAmount)
$: currentLiquidationPrice = data.position.liquidationPrice
Comment on lines +11 to +12

async function handleSubmit() {
errors = {}
if (!amount) {
</div>
</div>

<div class='row'>
<div class='label'>Current Liquidation Price</div>
<div class='value'>{currentLiquidationPrice ? `$${formatNumber(currentLiquidationPrice)}` : '-'}</div>
</div>

{#if amount}
<div class='row'>
<div class='label'>New Liquidation Price</div>
<div class='value'>{newLiquidationPrice ? `$${formatNumber(newLiquidationPrice)}` : '-'}</div>
</div>
{/if}

<div class='buttons'>
<Button isLoading={loading} label={data.isAdding ? 'Add Margin' : 'Remove Margin'} />
</div>
margin-bottom: 20px;
Comment on lines +14 to +35
}

.row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
font-size: 14px;
}
.label { color: var(--text-secondary); }
.value { font-weight: 600; }

.buttons {
margin-top: 20px;
}
20 changes: 17 additions & 3 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { get } from 'svelte/store'

import { BPS_DIVIDER, CHAINDATA, USD_CONVERSION_MARKETS } from './config'
export function focusInput(node) {
node.focus()
}

export function getLiquidationPrice(position, marginChange) {
if (!position || !position.size) return null

const newMargin = position.margin + marginChange
Comment on lines +5 to +8
if (newMargin <= 0) return null

// Liquidation price formula: entryPrice +/- (entryPrice * newMargin / size)
// For longs: entryPrice * (1 - newMargin/size) - for shorts: entryPrice * (1 + newMargin/size)
const direction = position.isLong ? 1 : -1
const liquidationPrice = position.entryPrice * (1 - direction * newMargin / position.size)

return liquidationPrice
}
import { formatForDisplay } from './formatters'
Comment on lines +1 to 18
import { chainId, leverage, selectedMarket, selectedMarketInfo } from './stores'

Expand Down