Skip to content

feat(tide-chart): trade management enhancements (issue #29)#33

Merged
e35ventura merged 2 commits intoentrius:mainfrom
MkDev11:feature/issue-29-trade-management
Mar 13, 2026
Merged

feat(tide-chart): trade management enhancements (issue #29)#33
e35ventura merged 2 commits intoentrius:mainfrom
MkDev11:feature/issue-29-trade-management

Conversation

@MkDev11
Copy link
Contributor

@MkDev11 MkDev11 commented Mar 11, 2026

Summary

Add advanced trade management features to Tide Chart's gTrade integration: TP/SL updates on open positions, partial closes, market hours validation for stocks, real-time fee estimation, and liquidation price display.

Related Issues

Closes #29

Type of Change

  • Bug fix
  • Improvement to existing tool
  • Documentation
  • Other (describe below)

What's New

1. TP/SL Management on Open Positions

Traders can now update or remove Take Profit and Stop Loss directly on open positions through an inline manage panel. Each trade row has a Manage button that expands TP/SL inputs and a partial close control.

  • updateTp(uint32 _index, uint64 _newTp) and updateSl(uint32 _index, uint64 _newSl) contract calls
  • Pre-filled with current TP/SL values from on-chain data
  • "Remove" button appears only when TP/SL is already set
  • Current TP/SL displayed on each trade row
  • Optimistic UI: TP/SL values update instantly after tx confirmation (no wait for backend API indexing)
  • No-change guard: Skips tx if value matches current on-chain value, saving gas
  • Client-side validations:
    • TP direction: must be above entry (long) or below entry (short)
    • TP max distance: cannot exceed 900% from entry price
    • SL direction: must be below entry (long) or above entry (short)
    • SL max distance: capped at 75 / leverage% from entry (gTrade MAX_SL_P)

2. Partial Close (Decrease Position Size)

Reduce an open position's collateral without fully closing the trade. Useful for taking partial profits or reducing exposure.

  • decreasePositionSize(uint32 _index, uint120 _collateralDelta, uint24 _leverageDelta, uint64 _expectedPrice) contract call (4 params, gTrade v9)
  • _expectedPrice fetched from Chainlink on-chain feed with Synth API fallback
  • USDC amount input with 6-decimal precision via ethers.parseUnits
  • Optimistic UI: Collateral display updates instantly after tx confirmation
  • Client-side validations:
    • Amount cannot exceed current collateral
    • Remaining position must stay above $1,500 protocol minimum (shows max decrease)
    • Stock pairs blocked during market closed hours

3. Market Hours Validation (Stocks)

Stock trades on gTrade can only execute during NYSE regular hours. The app now validates this at multiple layers to prevent wasted gas.

  • Server: is_market_open() checks Mon-Fri 9:30 AM - 4:00 PM ET with 2025-2026 US holiday calendar
  • Server: POST /api/gtrade/validate-trade returns 400 for stock trades outside market hours
  • Client: executeTrade() blocks submission with toast message before any wallet interaction
  • Client: Trade preview shows a red warning banner for stocks when market is closed
  • 60-second client-side cache to minimize API calls

4. Real-Time Fee Estimation

Trade preview now shows a breakdown of estimated protocol fees before execution.

  • Server: estimate_trade_fees(asset, collateral_usd, leverage) calculates from group fee rates
  • API: POST /api/gtrade/estimate-fees returns {open_fee, close_fee, total_fee, fee_pct}
  • Client: Async fee breakdown appended to trade preview (open fee, close fee, total)
  • Fee rates: crypto 0.06%, stocks/commodities 0.01% of position size
  • Fees also included in validate-trade response summary

5. Liquidation Price Display

Liquidation price is now visible on both open positions and the trade preview, giving traders immediate risk awareness.

  • Formula: Long entry * (1 - 0.9 / leverage), Short entry * (1 + 0.9 / leverage)
  • Backend: calculate_liquidation_price() with edge-case safety (returns 0 for invalid inputs)
  • Frontend: Client-side calculateLiquidationPrice() for instant UI feedback
  • Displayed on each open trade row as Liq: $X.XX
  • Displayed in trade preview as Est. Liq. Price

Files Changed

File Lines Changed What changed
gtrade.py +65 is_market_open(), estimate_trade_fees(), calculate_liquidation_price(), constants (GROUP_FEES, LIQ_THRESHOLD_PCT, _MARKET_HOLIDAYS)
main.py +55 CSS for manage panel / liq price / fees / market warning, GET /api/gtrade/market-status, POST /api/gtrade/estimate-fees, market guard in validate-trade
static/trading.js +190 updateTradeTP(), updateTradeSL(), decreasePosition(), toggleManagePanel(), checkMarketStatus(), calculateLiquidationPrice(), fee display in preview, market warning in preview + executeTrade, client-side validations (TP/SL direction + distance, partial close min position), optimistic UI updates with cache sync, anti-flicker polling (skip re-render when manage panel open), race-condition fix for async fee display
tests/test_tool.py +170 17 new tests for all new backend functions, API endpoints, constants, and CSS

Testing

  • Tested against Synth API
  • Manually tested
  • Tests added/updated
$ python -m pytest tools/tide-chart/tests/test_tool.py -v
...
69 passed in 1.41s

New Tests Added (17)

Test Covers
test_is_market_open_returns_tuple is_market_open() returns (bool, str)
test_estimate_trade_fees_crypto Crypto fee calc (0.06% of position)
test_estimate_trade_fees_stocks Stock fee calc (0.01% of position)
test_estimate_trade_fees_unknown_asset Unknown asset returns zeroes
test_calculate_liquidation_price_long Long liq price formula
test_calculate_liquidation_price_short Short liq price formula
test_calculate_liquidation_price_high_leverage Higher leverage = liq closer to entry
test_calculate_liquidation_price_edge_cases Zero/negative inputs return 0
test_flask_gtrade_market_status GET /api/gtrade/market-status
test_flask_gtrade_estimate_fees_valid POST /api/gtrade/estimate-fees (valid)
test_flask_gtrade_estimate_fees_invalid POST /api/gtrade/estimate-fees (400)
test_flask_validate_trade_includes_fees validate-trade includes fees in summary
test_group_fees_structure GROUP_FEES has all groups with required keys
test_liq_threshold_constant LIQ_THRESHOLD_PCT == 90
test_dashboard_html_contains_new_css Dashboard HTML includes all new CSS classes

Demo Video

https://www.loom.com/share/88d0915387514625b72d0cd381fe22f5?t=226

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Changes are documented (if applicable)
  • All 69 tests pass
  • No new dependencies added

@MkDev11 MkDev11 force-pushed the feature/issue-29-trade-management branch 10 times, most recently from 1475386 to f75a02b Compare March 11, 2026 02:40
@ventura-oss
Copy link

Hi @MkDev11, I've been auditing this PR locally with live Synth API data. I noticed a regression regarding the Take Profit (TP) and Stop Loss (SL) logic for short positions.

It seems the directional logic from PR #30 was overwritten in tools/tide-chart/static/trading.js (lines 740-749), which now always assumes a Long position. For example, setting a 10% TP on a Short results in an absolute TP price above the entry price in the preview and transaction summary, which would actually be a loss.

Verified locally on http://localhost:5000:

  • Short BTC at $67,000 with 10% TP displays as $73,700 TP in the preview.
  • Expected behavior: TP should be $60,300 for a short.

The fee estimation and market hours features look great, but this logic needs to be restored to handle both directions correctly before merging.

@MkDev11 MkDev11 force-pushed the feature/issue-29-trade-management branch from f75a02b to f49ec05 Compare March 11, 2026 16:03
@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 11, 2026

image image

@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 11, 2026

@e35ventura please review the screenshots, implemented your comments

@e35ventura
Copy link
Collaborator

if a trade gets gets close via liquidation it does not show up in the trade history

- Add TP/SL management on open positions (updateTp/updateSl contract calls)
- Add partial close via decreasePositionSize with inline manage panel
- Add market hours validation for stock trades (NYSE hours + holidays)
- Add real-time fee estimation display in trade preview
- Add liquidation price display on open positions and trade preview
- Add /api/gtrade/market-status and /api/gtrade/estimate-fees endpoints
- Include fee data in validate-trade response summary
- Block stock trades when US market is closed (server + client)
- Add 17 new tests covering all new features (69 total pass)
@MkDev11 MkDev11 force-pushed the feature/issue-29-trade-management branch from f49ec05 to f5b9398 Compare March 12, 2026 00:27
@ventura-oss
Copy link

This PR inadvertently reverts critical trading execution fixes that were recently merged in PR #30.

Specifically, it:

  1. Resets the GROUP_LIMITS for stocks back to 150 max leverage (instead of the correct 50), which causes stock trades (like TSLA) to revert on the gTrade contract.
  2. Removes the commodities_t1 group, reverting the max leverage for XAU back down from 250 to 150.
  3. Overwrites the slippageP precision fixes inside trading.js.

…UP_LIMITS, XAU fees

- Fix GROUP_LIMITS: stocks max_leverage 150→50, min_leverage 2→1.1
- Add commodities_t1 group (XAU max_leverage 250) + fee tier in GROUP_FEES
- Detect liquidations/TP/SL hits via disappeared-trade polling in loadOpenTrades
- Persist _openTradesCache to sessionStorage for cross-refresh detection
- Guard against false positives with _closingTradeIndices for user-initiated closes
- Migrate fetch_trade_history to backend-global endpoint with legacy fallback
- Add TP HIT / SL HIT / LIQUIDATED badge CSS styling
- Add regression tests: leverage limits, XAU fees, badge CSS, backend URL (73/73 pass)
@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

I addressed all your comments. can you review again?

@ventura-oss
Copy link

Thanks for the updates! It looks like you've successfully addressed the GROUP_LIMITS and liquidation history concerns.

However, it appears that the slippageP precision fix (originally merged in PR 30) is still missing in trading.js and was overwritten by this PR.

Currently, maxClosingSlippageP is being calculated with 1e3 precision:

var slippageP = Math.round(slippageInput * 1000);

The gTrade contract actually expects this to be scaled in 1e10 precision (1% = 1e8) to match the oracle prices. Could you please update the calculation in executeTrade() to use 1e10 precision using BigInt, similar to PR 30?

var slippageP = BigInt(Math.round((slippageInput / 100) * 1e10));

Once this last precision fix is restored, this should be good to merge. Thanks!

@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

Thanks for the updates! It looks like you've successfully addressed the GROUP_LIMITS and liquidation history concerns.

However, it appears that the slippageP precision fix (originally merged in PR 30) is still missing in trading.js and was overwritten by this PR.

Currently, maxClosingSlippageP is being calculated with 1e3 precision:

var slippageP = Math.round(slippageInput * 1000);

The gTrade contract actually expects this to be scaled in 1e10 precision (1% = 1e8) to match the oracle prices. Could you please update the calculation in executeTrade() to use 1e10 precision using BigInt, similar to PR 30?

var slippageP = BigInt(Math.round((slippageInput / 100) * 1e10));

Once this last precision fix is restored, this should be good to merge. Thanks!

I checked the PR #30 diff (022a8fe) — it only added TP/SL direction fixes and SL/TP validation guards. It did not change slippageP at all. Additionally, the official gTrade contract docs explicitly define _maxSlippageP as uint16 with 1e3 precision for both openTrade and updateMaxClosingSlippageP. Using 1e10 precision would overflow uint16 (max 65,535) — e.g., 1.5% → 150,000,000. The current implementation matches the contract spec.

@e35ventura e35ventura merged commit dec3e35 into entrius:main Mar 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tide Chart: Trading UX & Protocol Management Enhancements

3 participants