@@ -27,6 +27,9 @@ export default function PositionCalculator({ type }: { type: Position }) {
2727 const [ stop , setStop ] = useState < Decimal > ( ) ;
2828 const [ riskPercent , setRiskPercent ] = useState < Decimal > ( ) ;
2929 const [ riskAmount , setRiskAmount ] = useState < Decimal > ( ) ;
30+ const [ feePercent , setFeePercent ] = useState < Decimal | undefined > (
31+ new Decimal ( 0.075 ) // Binance Fee when using BNB with 25% discount
32+ ) ;
3033
3134 const [ error , setError ] = useState < Error > ( noError ) ;
3235
@@ -72,6 +75,22 @@ export default function PositionCalculator({ type }: { type: Position }) {
7275 setRiskAmount ( computed . riskAmount ) ;
7376 } ;
7477
78+ const computeNettProfit = ( ) => {
79+ if ( ! feePercent || ! tpSellAmount || ! buyAmount || ! rewardAmount ) return ;
80+ const entryFee = buyAmount . mul ( feePercent ) . div ( 100 ) ;
81+ const tpFee = tpSellAmount . mul ( feePercent ) . div ( 100 ) ;
82+ const allFees = entryFee . plus ( tpFee ) ;
83+ return isShort ? rewardAmount . plus ( allFees ) : rewardAmount . minus ( allFees ) ;
84+ } ;
85+
86+ const computeNettLoss = ( ) => {
87+ if ( ! feePercent || ! slSellAmount || ! buyAmount || ! riskAmount ) return ;
88+ const entryFee = buyAmount . mul ( feePercent ) . div ( 100 ) ;
89+ const slFee = slSellAmount . mul ( feePercent ) . div ( 100 ) ;
90+ const allFees = entryFee . plus ( slFee ) ;
91+ return isShort ? riskAmount . minus ( allFees ) : riskAmount . plus ( allFees ) ;
92+ } ;
93+
7594 const resetAllState = ( ) => {
7695 setTarget ( undefined ) ;
7796 setRewardPercent ( undefined ) ;
@@ -94,6 +113,7 @@ export default function PositionCalculator({ type }: { type: Position }) {
94113 const isError = Object . values ( error ) . some ( ( value ) => value ) ;
95114
96115 const baseAdornment = "XYZ" ;
116+ const quoteAdornment = "ABC" ;
97117 const green = "#003705" ;
98118 const red = "#5a2d2d" ;
99119 const config = {
@@ -116,9 +136,13 @@ export default function PositionCalculator({ type }: { type: Position }) {
116136 aboveColor : isShort ? red : green ,
117137 belowHeight : isShort ? 150 : 50 ,
118138 belowColor : isShort ? green : red ,
139+ tpFee : isShort ? "SL Fee" : "TP Fee" ,
140+ slFee : isShort ? "TP Fee" : "SL Fee" ,
141+ nettProfit : isShort ? "Nett Loss After Fees" : "Nett Profit After Fees" ,
142+ nettLoss : isShort ? "Nett Profit After Fees" : "Nett Loss After Fees" ,
119143 } ;
120144
121- return (
145+ const mainCalculator = (
122146 < >
123147 < Alert severity = { isError ? "error" : "info" } >
124148 { isError
@@ -142,6 +166,8 @@ export default function PositionCalculator({ type }: { type: Position }) {
142166 error = { error . rewardPercent }
143167 />
144168 < Text
169+ baseAmount = { computeNettProfit ( ) }
170+ baseAdornment = { quoteAdornment }
145171 label = { config . rewardAmount }
146172 xs
147173 value = { rewardAmount }
@@ -258,6 +284,8 @@ export default function PositionCalculator({ type }: { type: Position }) {
258284 error = { error . riskPercent }
259285 />
260286 < Text
287+ baseAmount = { computeNettLoss ( ) }
288+ baseAdornment = { quoteAdornment }
261289 label = { config . riskAmount }
262290 xs
263291 value = { riskAmount }
@@ -275,4 +303,108 @@ export default function PositionCalculator({ type }: { type: Position }) {
275303 </ Box >
276304 </ >
277305 ) ;
306+
307+ const feeCalculator = (
308+ < >
309+ < Box
310+ sx = { {
311+ display : "flex" ,
312+ justifyContent : "space-around" ,
313+ alignItems : "center" ,
314+ width : "100%" ,
315+ } }
316+ >
317+ < h6 > Trading Fees</ h6 >
318+ < Text
319+ adornment = "%"
320+ label = "Trading Fee %"
321+ xs
322+ value = { feePercent }
323+ onChange = { setFeePercent }
324+ error = { false }
325+ />
326+ </ Box >
327+ < Box
328+ sx = { {
329+ display : "flex" ,
330+ flexDirection : isShort ? "column-reverse" : "column" ,
331+ } }
332+ >
333+ < TextBoxes >
334+ < Text
335+ disabled
336+ label = { config . tpFee }
337+ value = { tpSellAmount ?. mul ( feePercent || 0 ) . div ( 100 ) }
338+ onChange = { ( ) => { } }
339+ error = { false }
340+ />
341+ < Text
342+ disabled
343+ label = { config . nettProfit }
344+ value = { computeNettProfit ( ) }
345+ onChange = { ( ) => { } }
346+ error = { false }
347+ />
348+ </ TextBoxes >
349+ < TextBoxes >
350+ < Text
351+ disabled
352+ label = "Entry Fee"
353+ value = { buyAmount ?. mul ( feePercent || 0 ) . div ( 100 ) }
354+ onChange = { ( ) => { } }
355+ error = { false }
356+ />
357+ </ TextBoxes >
358+ < TextBoxes >
359+ < Text
360+ disabled
361+ label = { config . slFee }
362+ value = { slSellAmount ?. mul ( feePercent || 0 ) . div ( 100 ) }
363+ onChange = { ( ) => { } }
364+ error = { false }
365+ />
366+ < Text
367+ disabled
368+ label = { config . nettLoss }
369+ value = { computeNettLoss ( ) }
370+ onChange = { ( ) => { } }
371+ error = { false }
372+ />
373+ </ TextBoxes >
374+ </ Box >
375+ </ >
376+ ) ;
377+
378+ return (
379+ < Box
380+ sx = { {
381+ marginTop : 2 ,
382+ display : "flex" ,
383+ flexDirection : "row" ,
384+ justifyContent : "center" ,
385+ alignItems : "center" ,
386+ flexWrap : "wrap" ,
387+ gap : 5 ,
388+ } }
389+ >
390+ < Box
391+ sx = { {
392+ display : "flex" ,
393+ flexDirection : "column" ,
394+ alignItems : "center" ,
395+ } }
396+ >
397+ { mainCalculator }
398+ </ Box >
399+ < Box
400+ sx = { {
401+ display : "flex" ,
402+ flexDirection : "column" ,
403+ alignItems : "center" ,
404+ } }
405+ >
406+ { feeCalculator }
407+ </ Box >
408+ </ Box >
409+ ) ;
278410}
0 commit comments