@pear-protocol/hyperliquid-sdk 0.1.18 → 0.1.20-pnl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/tradeHistory.d.ts +7 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/usePnlCalendar.d.ts +61 -0
- package/dist/hooks/usePnlHeatmap.d.ts +13 -0
- package/dist/hooks/usePosition.d.ts +21 -0
- package/dist/index.d.ts +100 -2
- package/dist/index.js +542 -8
- package/dist/types.d.ts +2 -0
- package/package.json +3 -3
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiResponse, TradeHistoryDataDto } from '../types';
|
|
2
|
+
export interface GetTradeHistoryParams {
|
|
3
|
+
startDate?: string;
|
|
4
|
+
endDate?: string;
|
|
5
|
+
limit?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function getTradeHistory(baseUrl: string, params?: GetTradeHistoryParams): Promise<ApiResponse<TradeHistoryDataDto[]>>;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type PnlCalendarTimeframe = '2W' | '3W' | '2M' | '3M';
|
|
2
|
+
export interface PnlCalendarOptions {
|
|
3
|
+
timeframe?: PnlCalendarTimeframe;
|
|
4
|
+
startDate?: Date | string;
|
|
5
|
+
endDate?: Date | string;
|
|
6
|
+
}
|
|
7
|
+
export interface PnlCalendarAsset {
|
|
8
|
+
coin: string;
|
|
9
|
+
symbol: string;
|
|
10
|
+
assetName: string;
|
|
11
|
+
marketPrefix: string;
|
|
12
|
+
percentage: number;
|
|
13
|
+
collateralToken: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PnlCalendarTrade {
|
|
16
|
+
tradeHistoryId: string;
|
|
17
|
+
realizedPnl: number;
|
|
18
|
+
result: 'profit' | 'loss' | 'breakeven';
|
|
19
|
+
collateralTypes: string[];
|
|
20
|
+
closedLongAssets: PnlCalendarAsset[];
|
|
21
|
+
closedShortAssets: PnlCalendarAsset[];
|
|
22
|
+
}
|
|
23
|
+
export interface PnlCalendarDay {
|
|
24
|
+
date: string;
|
|
25
|
+
totalPnl: number;
|
|
26
|
+
volume: number;
|
|
27
|
+
positionsClosed: number;
|
|
28
|
+
result: 'profit' | 'loss' | 'breakeven';
|
|
29
|
+
trades: PnlCalendarTrade[];
|
|
30
|
+
}
|
|
31
|
+
export interface PeriodSummary {
|
|
32
|
+
pnl: number;
|
|
33
|
+
volume: number;
|
|
34
|
+
winRate: number;
|
|
35
|
+
wins: number;
|
|
36
|
+
losses: number;
|
|
37
|
+
totalProfit: number;
|
|
38
|
+
totalLoss: number;
|
|
39
|
+
}
|
|
40
|
+
export interface PnlCalendarWeek {
|
|
41
|
+
weekStart: string;
|
|
42
|
+
weekEnd: string;
|
|
43
|
+
days: PnlCalendarDay[];
|
|
44
|
+
summary: PeriodSummary;
|
|
45
|
+
}
|
|
46
|
+
export interface PnlCalendarMonth {
|
|
47
|
+
month: string;
|
|
48
|
+
label: string;
|
|
49
|
+
days: PnlCalendarDay[];
|
|
50
|
+
summary: PeriodSummary;
|
|
51
|
+
}
|
|
52
|
+
export interface UsePnlCalendarResult {
|
|
53
|
+
timeframe: PnlCalendarTimeframe;
|
|
54
|
+
weeks: PnlCalendarWeek[];
|
|
55
|
+
months: PnlCalendarMonth[];
|
|
56
|
+
overall: PeriodSummary;
|
|
57
|
+
isLoading: boolean;
|
|
58
|
+
error: string | null;
|
|
59
|
+
refetch: () => void;
|
|
60
|
+
}
|
|
61
|
+
export declare function usePnlCalendar(options?: PnlCalendarTimeframe | PnlCalendarOptions): UsePnlCalendarResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PnlCalendarTrade } from './usePnlCalendar';
|
|
2
|
+
export type PnlHeatmapTimeframe = 'allTime' | '100D' | '30D' | '7D';
|
|
3
|
+
export interface PnlHeatmapTrade extends PnlCalendarTrade {
|
|
4
|
+
percentage: number;
|
|
5
|
+
}
|
|
6
|
+
export interface UsePnlHeatmapResult {
|
|
7
|
+
timeframe: PnlHeatmapTimeframe;
|
|
8
|
+
trades: PnlHeatmapTrade[];
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
refetch: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function usePnlHeatmap(timeframe?: PnlHeatmapTimeframe): UsePnlHeatmapResult;
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import { type UpdateRiskParametersRequestInput, type UpdateRiskParametersResponseDto, type ClosePositionRequestInput, type ClosePositionResponseDto, type CloseAllPositionsResponseDto, type AdjustPositionRequestInput, type AdjustPositionResponseDto, type AdjustAdvanceItemInput, type AdjustAdvanceResponseDto, type UpdateLeverageResponseDto } from '../clients/positions';
|
|
2
2
|
import type { ApiResponse, CreatePositionRequestInput, CreatePositionResponseDto, OpenPositionDto } from '../types';
|
|
3
|
+
export interface RebalanceAssetPlan {
|
|
4
|
+
coin: string;
|
|
5
|
+
side: 'long' | 'short';
|
|
6
|
+
currentWeight: number;
|
|
7
|
+
targetWeight: number;
|
|
8
|
+
currentValue: number;
|
|
9
|
+
targetValue: number;
|
|
10
|
+
deltaValue: number;
|
|
11
|
+
currentSize: number;
|
|
12
|
+
newSize: number;
|
|
13
|
+
deltaSize: number;
|
|
14
|
+
skipped: boolean;
|
|
15
|
+
skipReason?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RebalancePlan {
|
|
18
|
+
positionId: string;
|
|
19
|
+
assets: RebalanceAssetPlan[];
|
|
20
|
+
canExecute: boolean;
|
|
21
|
+
}
|
|
3
22
|
export declare function usePosition(): {
|
|
4
23
|
readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
|
|
5
24
|
readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
@@ -10,4 +29,6 @@ export declare function usePosition(): {
|
|
|
10
29
|
readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
|
|
11
30
|
readonly openPositions: OpenPositionDto[] | null;
|
|
12
31
|
readonly isLoading: boolean;
|
|
32
|
+
readonly planRebalance: (positionId: string, targetWeights?: Record<string, number>) => RebalancePlan;
|
|
33
|
+
readonly executeRebalance: (positionId: string, targetWeights?: Record<string, number>) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
|
|
13
34
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -286,6 +286,7 @@ interface PositionAssetDetailDto {
|
|
|
286
286
|
initialWeight: number;
|
|
287
287
|
currentWeight: number;
|
|
288
288
|
fundingPaid?: number;
|
|
289
|
+
targetWeight?: number;
|
|
289
290
|
metadata?: TokenMetadata | null;
|
|
290
291
|
}
|
|
291
292
|
interface TpSlThreshold {
|
|
@@ -763,6 +764,7 @@ interface RawAssetDto {
|
|
|
763
764
|
side: string;
|
|
764
765
|
fundingPaid?: number;
|
|
765
766
|
leverage: number;
|
|
767
|
+
targetWeight?: number;
|
|
766
768
|
}
|
|
767
769
|
/**
|
|
768
770
|
* Raw position data from open-positions channel
|
|
@@ -1295,6 +1297,25 @@ interface UpdateLeverageResponseDto {
|
|
|
1295
1297
|
}
|
|
1296
1298
|
declare function updateLeverage(baseUrl: string, positionId: string, payload: UpdateLeverageRequestInput): Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
|
|
1297
1299
|
|
|
1300
|
+
interface RebalanceAssetPlan {
|
|
1301
|
+
coin: string;
|
|
1302
|
+
side: 'long' | 'short';
|
|
1303
|
+
currentWeight: number;
|
|
1304
|
+
targetWeight: number;
|
|
1305
|
+
currentValue: number;
|
|
1306
|
+
targetValue: number;
|
|
1307
|
+
deltaValue: number;
|
|
1308
|
+
currentSize: number;
|
|
1309
|
+
newSize: number;
|
|
1310
|
+
deltaSize: number;
|
|
1311
|
+
skipped: boolean;
|
|
1312
|
+
skipReason?: string;
|
|
1313
|
+
}
|
|
1314
|
+
interface RebalancePlan {
|
|
1315
|
+
positionId: string;
|
|
1316
|
+
assets: RebalanceAssetPlan[];
|
|
1317
|
+
canExecute: boolean;
|
|
1318
|
+
}
|
|
1298
1319
|
declare function usePosition(): {
|
|
1299
1320
|
readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
|
|
1300
1321
|
readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
@@ -1305,6 +1326,8 @@ declare function usePosition(): {
|
|
|
1305
1326
|
readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
|
|
1306
1327
|
readonly openPositions: OpenPositionDto[] | null;
|
|
1307
1328
|
readonly isLoading: boolean;
|
|
1329
|
+
readonly planRebalance: (positionId: string, targetWeights?: Record<string, number>) => RebalancePlan;
|
|
1330
|
+
readonly executeRebalance: (positionId: string, targetWeights?: Record<string, number>) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
|
|
1308
1331
|
};
|
|
1309
1332
|
|
|
1310
1333
|
declare function useOrders(): {
|
|
@@ -1475,6 +1498,81 @@ interface UseHyperliquidUserFillsState {
|
|
|
1475
1498
|
*/
|
|
1476
1499
|
declare function useHyperliquidUserFills(options: UseHyperliquidUserFillsOptions): UseHyperliquidUserFillsState;
|
|
1477
1500
|
|
|
1501
|
+
type PnlCalendarTimeframe = '2W' | '3W' | '2M' | '3M';
|
|
1502
|
+
interface PnlCalendarOptions {
|
|
1503
|
+
timeframe?: PnlCalendarTimeframe;
|
|
1504
|
+
startDate?: Date | string;
|
|
1505
|
+
endDate?: Date | string;
|
|
1506
|
+
}
|
|
1507
|
+
interface PnlCalendarAsset {
|
|
1508
|
+
coin: string;
|
|
1509
|
+
symbol: string;
|
|
1510
|
+
assetName: string;
|
|
1511
|
+
marketPrefix: string;
|
|
1512
|
+
percentage: number;
|
|
1513
|
+
collateralToken: string;
|
|
1514
|
+
}
|
|
1515
|
+
interface PnlCalendarTrade {
|
|
1516
|
+
tradeHistoryId: string;
|
|
1517
|
+
realizedPnl: number;
|
|
1518
|
+
result: 'profit' | 'loss' | 'breakeven';
|
|
1519
|
+
collateralTypes: string[];
|
|
1520
|
+
closedLongAssets: PnlCalendarAsset[];
|
|
1521
|
+
closedShortAssets: PnlCalendarAsset[];
|
|
1522
|
+
}
|
|
1523
|
+
interface PnlCalendarDay {
|
|
1524
|
+
date: string;
|
|
1525
|
+
totalPnl: number;
|
|
1526
|
+
volume: number;
|
|
1527
|
+
positionsClosed: number;
|
|
1528
|
+
result: 'profit' | 'loss' | 'breakeven';
|
|
1529
|
+
trades: PnlCalendarTrade[];
|
|
1530
|
+
}
|
|
1531
|
+
interface PeriodSummary {
|
|
1532
|
+
pnl: number;
|
|
1533
|
+
volume: number;
|
|
1534
|
+
winRate: number;
|
|
1535
|
+
wins: number;
|
|
1536
|
+
losses: number;
|
|
1537
|
+
totalProfit: number;
|
|
1538
|
+
totalLoss: number;
|
|
1539
|
+
}
|
|
1540
|
+
interface PnlCalendarWeek {
|
|
1541
|
+
weekStart: string;
|
|
1542
|
+
weekEnd: string;
|
|
1543
|
+
days: PnlCalendarDay[];
|
|
1544
|
+
summary: PeriodSummary;
|
|
1545
|
+
}
|
|
1546
|
+
interface PnlCalendarMonth {
|
|
1547
|
+
month: string;
|
|
1548
|
+
label: string;
|
|
1549
|
+
days: PnlCalendarDay[];
|
|
1550
|
+
summary: PeriodSummary;
|
|
1551
|
+
}
|
|
1552
|
+
interface UsePnlCalendarResult {
|
|
1553
|
+
timeframe: PnlCalendarTimeframe;
|
|
1554
|
+
weeks: PnlCalendarWeek[];
|
|
1555
|
+
months: PnlCalendarMonth[];
|
|
1556
|
+
overall: PeriodSummary;
|
|
1557
|
+
isLoading: boolean;
|
|
1558
|
+
error: string | null;
|
|
1559
|
+
refetch: () => void;
|
|
1560
|
+
}
|
|
1561
|
+
declare function usePnlCalendar(options?: PnlCalendarTimeframe | PnlCalendarOptions): UsePnlCalendarResult;
|
|
1562
|
+
|
|
1563
|
+
type PnlHeatmapTimeframe = 'allTime' | '100D' | '30D' | '7D';
|
|
1564
|
+
interface PnlHeatmapTrade extends PnlCalendarTrade {
|
|
1565
|
+
percentage: number;
|
|
1566
|
+
}
|
|
1567
|
+
interface UsePnlHeatmapResult {
|
|
1568
|
+
timeframe: PnlHeatmapTimeframe;
|
|
1569
|
+
trades: PnlHeatmapTrade[];
|
|
1570
|
+
isLoading: boolean;
|
|
1571
|
+
error: string | null;
|
|
1572
|
+
refetch: () => void;
|
|
1573
|
+
}
|
|
1574
|
+
declare function usePnlHeatmap(timeframe?: PnlHeatmapTimeframe): UsePnlHeatmapResult;
|
|
1575
|
+
|
|
1478
1576
|
/**
|
|
1479
1577
|
* Mark notifications as read up to a given timestamp (ms)
|
|
1480
1578
|
*/
|
|
@@ -1749,5 +1847,5 @@ interface MarketDataState {
|
|
|
1749
1847
|
}
|
|
1750
1848
|
declare const useMarketData: zustand.UseBoundStore<zustand.StoreApi<MarketDataState>>;
|
|
1751
1849
|
|
|
1752
|
-
export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, ReadyState, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
|
1753
|
-
export type { AccountSummaryResponseDto, ActiveAssetData, ActiveAssetGroupItem, ActiveAssetsAllResponse, ActiveAssetsResponse, AddressState, AdjustAdvanceAssetInput, AdjustAdvanceItemInput, AdjustAdvanceResponseDto, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, AgentWalletStatus, AllDexsAssetCtxsData, AllDexsClearinghouseStateData, AllPerpMetasItem, AllPerpMetasResponse, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AuthenticateRequest, AuthenticateResponse, AvailableToTrades, BalanceSummaryDto, BaseTriggerOrderNotificationParams, BtcDomTriggerParams, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ChunkFillDto, ClearinghouseState, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CollateralToken, CreateAgentWalletResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossAssetPriceTriggerParams, CrossMarginSummaryDto, CumFundingDto, EIP712AuthDetails, ExecutionType, ExternalFillDto, ExternalLiquidationDto, ExtraAgent, GetAgentWalletResponseDto, GetEIP712MessageResponse, GetKalshiMarketsParams, HLChannel, HLChannelDataMap, HLWebSocketResponse, HistoricalRange, KalshiMarket, KalshiMarketsResponse, KalshiMveLeg, KalshiPriceRange, LadderConfigInput, LadderOrderParameters, LeverageInfo, LogoutRequest, LogoutResponse, MarginRequiredPerCollateral, MarginRequiredResult, MarginSummaryDto, MarginTableDef, MarginTablesEntry, MarginTier, MarketOrderParameters, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderDirection, OrderParameters, OrderStatus, OrderType, PairAssetDto, PairAssetInput, PerformanceOverlay, PerpDex, PerpDexsResponse, PerpMetaAsset, PlatformAccountSummaryResponseDto, PortfolioBucketDto, PortfolioInterval, PortfolioIntervalsDto, PortfolioOverallDto, PortfolioResponseDto, PositionAdjustmentType, PositionAssetDetailDto, PredictionMarketOutcomeTriggerParams, PriceRatioTriggerParams, PriceTriggerParams, PrivyAuthDetails, RawAssetDto, RawPositionDto, RealtimeBar, RealtimeBarsCallback, RefreshTokenRequest, RefreshTokenResponse, SpotBalance, SpotBalances, SpotOrderFilledStatus, SpotOrderHyperliquidData, SpotOrderHyperliquidResult, SpotOrderRequestInput, SpotOrderResponseDto, SpotState, SyncFillsRequestDto, SyncFillsResponseDto, ToggleWatchlistResponseDto, TokenConflict, TokenEntry, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TokenSelectorConfig, TpSlOrderParameters, TpSlThreshold, TpSlThresholdInput, TpSlThresholdType, TpSlTriggerType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TriggerOrderNotificationAsset, TriggerOrderNotificationParams, TriggerOrderNotificationType, TriggerOrderParameters, TriggerType, TwapChunkStatus, TwapChunkStatusDto, TwapMonitoringDto, TwapOrderOverallStatus, TwapOrderParameters, TwapSliceFillResponseItem, UniverseAsset, UpdateLeverageRequestInput, UpdateLeverageResponseDto, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseHyperliquidUserFillsOptions, UseHyperliquidUserFillsState, UseNotificationsResult, UsePerformanceOverlaysReturn, UsePortfolioResult, UseSpotOrderResult, UseTokenSelectionMetadataReturn, UserAbstraction, UserProfile, UserSelectionState, WatchlistAssetDto, WatchlistItemDto, WebData3AssetCtx, WebData3PerpDexState, WebData3Response, WebData3UserState, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
|
|
1850
|
+
export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, ReadyState, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePnlCalendar, usePnlHeatmap, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
|
1851
|
+
export type { AccountSummaryResponseDto, ActiveAssetData, ActiveAssetGroupItem, ActiveAssetsAllResponse, ActiveAssetsResponse, AddressState, AdjustAdvanceAssetInput, AdjustAdvanceItemInput, AdjustAdvanceResponseDto, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, AgentWalletStatus, AllDexsAssetCtxsData, AllDexsClearinghouseStateData, AllPerpMetasItem, AllPerpMetasResponse, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AuthenticateRequest, AuthenticateResponse, AvailableToTrades, BalanceSummaryDto, BaseTriggerOrderNotificationParams, BtcDomTriggerParams, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ChunkFillDto, ClearinghouseState, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CollateralToken, CreateAgentWalletResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossAssetPriceTriggerParams, CrossMarginSummaryDto, CumFundingDto, EIP712AuthDetails, ExecutionType, ExternalFillDto, ExternalLiquidationDto, ExtraAgent, GetAgentWalletResponseDto, GetEIP712MessageResponse, GetKalshiMarketsParams, HLChannel, HLChannelDataMap, HLWebSocketResponse, HistoricalRange, KalshiMarket, KalshiMarketsResponse, KalshiMveLeg, KalshiPriceRange, LadderConfigInput, LadderOrderParameters, LeverageInfo, LogoutRequest, LogoutResponse, MarginRequiredPerCollateral, MarginRequiredResult, MarginSummaryDto, MarginTableDef, MarginTablesEntry, MarginTier, MarketOrderParameters, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderDirection, OrderParameters, OrderStatus, OrderType, PairAssetDto, PairAssetInput, PerformanceOverlay, PeriodSummary, PerpDex, PerpDexsResponse, PerpMetaAsset, PlatformAccountSummaryResponseDto, PnlCalendarAsset, PnlCalendarDay, PnlCalendarMonth, PnlCalendarOptions, PnlCalendarTimeframe, PnlCalendarTrade, PnlCalendarWeek, PnlHeatmapTimeframe, PnlHeatmapTrade, PortfolioBucketDto, PortfolioInterval, PortfolioIntervalsDto, PortfolioOverallDto, PortfolioResponseDto, PositionAdjustmentType, PositionAssetDetailDto, PredictionMarketOutcomeTriggerParams, PriceRatioTriggerParams, PriceTriggerParams, PrivyAuthDetails, RawAssetDto, RawPositionDto, RealtimeBar, RealtimeBarsCallback, RebalanceAssetPlan, RebalancePlan, RefreshTokenRequest, RefreshTokenResponse, SpotBalance, SpotBalances, SpotOrderFilledStatus, SpotOrderHyperliquidData, SpotOrderHyperliquidResult, SpotOrderRequestInput, SpotOrderResponseDto, SpotState, SyncFillsRequestDto, SyncFillsResponseDto, ToggleWatchlistResponseDto, TokenConflict, TokenEntry, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TokenSelectorConfig, TpSlOrderParameters, TpSlThreshold, TpSlThresholdInput, TpSlThresholdType, TpSlTriggerType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TriggerOrderNotificationAsset, TriggerOrderNotificationParams, TriggerOrderNotificationType, TriggerOrderParameters, TriggerType, TwapChunkStatus, TwapChunkStatusDto, TwapMonitoringDto, TwapOrderOverallStatus, TwapOrderParameters, TwapSliceFillResponseItem, UniverseAsset, UpdateLeverageRequestInput, UpdateLeverageResponseDto, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseHyperliquidUserFillsOptions, UseHyperliquidUserFillsState, UseNotificationsResult, UsePerformanceOverlaysReturn, UsePnlCalendarResult, UsePnlHeatmapResult, UsePortfolioResult, UseSpotOrderResult, UseTokenSelectionMetadataReturn, UserAbstraction, UserProfile, UserSelectionState, WatchlistAssetDto, WatchlistItemDto, WebData3AssetCtx, WebData3PerpDexState, WebData3Response, WebData3UserState, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
|
package/dist/index.js
CHANGED
|
@@ -1576,11 +1576,6 @@ const useAccountSummary = () => {
|
|
|
1576
1576
|
const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
|
|
1577
1577
|
const registeredAgentWallets = useUserData((state) => state.userExtraAgents);
|
|
1578
1578
|
const isLoading = useMemo(() => {
|
|
1579
|
-
console.log('[USE ACCOUNT SUMMARY DEBUG] Loading check:', {
|
|
1580
|
-
platformAccountSummary,
|
|
1581
|
-
registeredAgentWallets,
|
|
1582
|
-
aggregatedClearingHouseState,
|
|
1583
|
-
});
|
|
1584
1579
|
return !platformAccountSummary || !registeredAgentWallets || !aggregatedClearingHouseState;
|
|
1585
1580
|
}, [platformAccountSummary, registeredAgentWallets, aggregatedClearingHouseState]);
|
|
1586
1581
|
// Create calculator and compute account summary
|
|
@@ -7098,6 +7093,7 @@ const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, t
|
|
|
7098
7093
|
initialWeight: totalInitialPositionSize > 0 ? entryNotional / totalInitialPositionSize : 0,
|
|
7099
7094
|
currentWeight: totalCurrentPositionSize > 0 ? currentNotional / totalCurrentPositionSize : 0,
|
|
7100
7095
|
fundingPaid: (_a = asset.fundingPaid) !== null && _a !== void 0 ? _a : 0,
|
|
7096
|
+
targetWeight: asset.targetWeight,
|
|
7101
7097
|
metadata,
|
|
7102
7098
|
};
|
|
7103
7099
|
};
|
|
@@ -7203,6 +7199,7 @@ const buildPositionValue = (rawPositions, clearinghouseState, getAssetByName) =>
|
|
|
7203
7199
|
});
|
|
7204
7200
|
};
|
|
7205
7201
|
|
|
7202
|
+
const MIN_TRADE_SIZE_USD = 11;
|
|
7206
7203
|
function usePosition() {
|
|
7207
7204
|
const context = useContext(PearHyperliquidContext);
|
|
7208
7205
|
if (!context) {
|
|
@@ -7245,6 +7242,85 @@ function usePosition() {
|
|
|
7245
7242
|
return null;
|
|
7246
7243
|
return buildPositionValue(userOpenPositions, aggregatedClearingHouseState, getAssetByName);
|
|
7247
7244
|
}, [userOpenPositions, aggregatedClearingHouseState, tokenMetadata, getAssetByName]);
|
|
7245
|
+
const planRebalance = (positionId, targetWeights) => {
|
|
7246
|
+
var _a;
|
|
7247
|
+
if (!openPositions) {
|
|
7248
|
+
throw new Error('Open positions not loaded');
|
|
7249
|
+
}
|
|
7250
|
+
const position = openPositions.find((p) => p.positionId === positionId);
|
|
7251
|
+
if (!position) {
|
|
7252
|
+
throw new Error(`Position ${positionId} not found`);
|
|
7253
|
+
}
|
|
7254
|
+
const assets = [];
|
|
7255
|
+
const allAssets = [
|
|
7256
|
+
...position.longAssets.map((a) => ({ asset: a, side: 'long' })),
|
|
7257
|
+
...position.shortAssets.map((a) => ({ asset: a, side: 'short' })),
|
|
7258
|
+
];
|
|
7259
|
+
const totalValue = allAssets.reduce((sum, { asset }) => sum + asset.positionValue, 0);
|
|
7260
|
+
for (const { asset, side } of allAssets) {
|
|
7261
|
+
const tw = (_a = targetWeights === null || targetWeights === void 0 ? void 0 : targetWeights[asset.coin]) !== null && _a !== void 0 ? _a : asset.targetWeight;
|
|
7262
|
+
if (tw === undefined) {
|
|
7263
|
+
assets.push({
|
|
7264
|
+
coin: asset.coin,
|
|
7265
|
+
side,
|
|
7266
|
+
currentWeight: totalValue > 0 ? (asset.positionValue / totalValue) * 100 : 0,
|
|
7267
|
+
targetWeight: 0,
|
|
7268
|
+
currentValue: asset.positionValue,
|
|
7269
|
+
targetValue: asset.positionValue,
|
|
7270
|
+
deltaValue: 0,
|
|
7271
|
+
currentSize: asset.actualSize,
|
|
7272
|
+
newSize: asset.actualSize,
|
|
7273
|
+
deltaSize: 0,
|
|
7274
|
+
skipped: true,
|
|
7275
|
+
skipReason: 'No target weight defined',
|
|
7276
|
+
});
|
|
7277
|
+
continue;
|
|
7278
|
+
}
|
|
7279
|
+
const currentWeight = totalValue > 0 ? (asset.positionValue / totalValue) * 100 : 0;
|
|
7280
|
+
const targetValue = totalValue * (tw / 100);
|
|
7281
|
+
const deltaValue = targetValue - asset.positionValue;
|
|
7282
|
+
const currentPrice = asset.actualSize > 0 ? asset.positionValue / asset.actualSize : 0;
|
|
7283
|
+
const deltaSize = currentPrice > 0 ? deltaValue / currentPrice : 0;
|
|
7284
|
+
const newSize = asset.actualSize + deltaSize;
|
|
7285
|
+
const belowMinimum = Math.abs(deltaValue) > 0 && Math.abs(deltaValue) < MIN_TRADE_SIZE_USD;
|
|
7286
|
+
assets.push({
|
|
7287
|
+
coin: asset.coin,
|
|
7288
|
+
side,
|
|
7289
|
+
currentWeight,
|
|
7290
|
+
targetWeight: tw,
|
|
7291
|
+
currentValue: asset.positionValue,
|
|
7292
|
+
targetValue,
|
|
7293
|
+
deltaValue,
|
|
7294
|
+
currentSize: asset.actualSize,
|
|
7295
|
+
newSize,
|
|
7296
|
+
deltaSize,
|
|
7297
|
+
skipped: belowMinimum,
|
|
7298
|
+
skipReason: belowMinimum
|
|
7299
|
+
? `Trade size $${Math.abs(deltaValue).toFixed(2)} is below minimum $${MIN_TRADE_SIZE_USD}`
|
|
7300
|
+
: undefined,
|
|
7301
|
+
});
|
|
7302
|
+
}
|
|
7303
|
+
const canExecute = assets.some((a) => !a.skipped && Math.abs(a.deltaValue) > 0);
|
|
7304
|
+
return { positionId, assets, canExecute };
|
|
7305
|
+
};
|
|
7306
|
+
const executeRebalance = async (positionId, targetWeights) => {
|
|
7307
|
+
const plan = planRebalance(positionId, targetWeights);
|
|
7308
|
+
if (!plan.canExecute) {
|
|
7309
|
+
throw new Error('No executable rebalance changes — all below minimum trade size or no changes needed');
|
|
7310
|
+
}
|
|
7311
|
+
const executable = plan.assets.filter((a) => !a.skipped && Math.abs(a.deltaValue) > 0);
|
|
7312
|
+
const payload = [
|
|
7313
|
+
{
|
|
7314
|
+
longAssets: executable
|
|
7315
|
+
.filter((a) => a.side === 'long')
|
|
7316
|
+
.map((a) => ({ asset: a.coin, size: a.newSize })),
|
|
7317
|
+
shortAssets: executable
|
|
7318
|
+
.filter((a) => a.side === 'short')
|
|
7319
|
+
.map((a) => ({ asset: a.coin, size: a.newSize })),
|
|
7320
|
+
},
|
|
7321
|
+
];
|
|
7322
|
+
return adjustAdvancePosition$1(positionId, payload);
|
|
7323
|
+
};
|
|
7248
7324
|
return {
|
|
7249
7325
|
createPosition: createPosition$1,
|
|
7250
7326
|
updateRiskParameters: updateRiskParameters$1,
|
|
@@ -7255,6 +7331,8 @@ function usePosition() {
|
|
|
7255
7331
|
updateLeverage: updateLeverage$1,
|
|
7256
7332
|
openPositions,
|
|
7257
7333
|
isLoading,
|
|
7334
|
+
planRebalance,
|
|
7335
|
+
executeRebalance,
|
|
7258
7336
|
};
|
|
7259
7337
|
}
|
|
7260
7338
|
|
|
@@ -8070,14 +8148,20 @@ const useAllUserBalances = () => {
|
|
|
8070
8148
|
}
|
|
8071
8149
|
}
|
|
8072
8150
|
if (!availableToTrades['USDC']) {
|
|
8073
|
-
availableToTrades['USDC'] = parseFloat((aggregatedClearingHouseState === null || aggregatedClearingHouseState === void 0 ? void 0 : aggregatedClearingHouseState.marginSummary.accountValue) || '0') -
|
|
8151
|
+
availableToTrades['USDC'] = Math.max(0, parseFloat((aggregatedClearingHouseState === null || aggregatedClearingHouseState === void 0 ? void 0 : aggregatedClearingHouseState.marginSummary.accountValue) || '0') -
|
|
8152
|
+
parseFloat((aggregatedClearingHouseState === null || aggregatedClearingHouseState === void 0 ? void 0 : aggregatedClearingHouseState.marginSummary.totalMarginUsed) || '0'));
|
|
8074
8153
|
}
|
|
8075
8154
|
return {
|
|
8076
8155
|
spotBalances,
|
|
8077
8156
|
availableToTrades,
|
|
8078
8157
|
isLoading,
|
|
8079
8158
|
};
|
|
8080
|
-
}, [
|
|
8159
|
+
}, [
|
|
8160
|
+
spotState,
|
|
8161
|
+
longTokensMetadata,
|
|
8162
|
+
shortTokensMetadata,
|
|
8163
|
+
aggregatedClearingHouseState,
|
|
8164
|
+
]);
|
|
8081
8165
|
/**
|
|
8082
8166
|
* Calculate margin required for every collateral token based on asset leverages and size.
|
|
8083
8167
|
* Returns margin required per collateral and whether there's sufficient margin.
|
|
@@ -8338,6 +8422,456 @@ function useHyperliquidUserFills(options) {
|
|
|
8338
8422
|
};
|
|
8339
8423
|
}
|
|
8340
8424
|
|
|
8425
|
+
async function getTradeHistory(baseUrl, params) {
|
|
8426
|
+
const url = joinUrl(baseUrl, '/trade-history');
|
|
8427
|
+
try {
|
|
8428
|
+
const resp = await apiClient.get(url, {
|
|
8429
|
+
params,
|
|
8430
|
+
timeout: 60000,
|
|
8431
|
+
});
|
|
8432
|
+
return { data: resp.data, status: resp.status, headers: resp.headers };
|
|
8433
|
+
}
|
|
8434
|
+
catch (error) {
|
|
8435
|
+
throw toApiError(error);
|
|
8436
|
+
}
|
|
8437
|
+
}
|
|
8438
|
+
|
|
8439
|
+
// ─── helpers ────────────────────────────────────────────────────
|
|
8440
|
+
const EMPTY_SUMMARY = {
|
|
8441
|
+
pnl: 0,
|
|
8442
|
+
volume: 0,
|
|
8443
|
+
winRate: 0,
|
|
8444
|
+
wins: 0,
|
|
8445
|
+
losses: 0,
|
|
8446
|
+
totalProfit: 0,
|
|
8447
|
+
totalLoss: 0,
|
|
8448
|
+
};
|
|
8449
|
+
const getTimeframeDays$1 = (tf) => {
|
|
8450
|
+
switch (tf) {
|
|
8451
|
+
case '2W':
|
|
8452
|
+
return 14;
|
|
8453
|
+
case '3W':
|
|
8454
|
+
return 21;
|
|
8455
|
+
case '2M':
|
|
8456
|
+
return 60;
|
|
8457
|
+
case '3M':
|
|
8458
|
+
return 90;
|
|
8459
|
+
}
|
|
8460
|
+
};
|
|
8461
|
+
const isWeekTimeframe = (tf) => tf === '2W' || tf === '3W';
|
|
8462
|
+
const toDateKey = (date) => {
|
|
8463
|
+
const y = date.getFullYear();
|
|
8464
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
8465
|
+
const d = String(date.getDate()).padStart(2, '0');
|
|
8466
|
+
return `${y}-${m}-${d}`;
|
|
8467
|
+
};
|
|
8468
|
+
const toMonthKey = (date) => {
|
|
8469
|
+
const y = date.getFullYear();
|
|
8470
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
8471
|
+
return `${y}-${m}`;
|
|
8472
|
+
};
|
|
8473
|
+
const formatMonthLabel = (date) => date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
|
|
8474
|
+
const getMonday = (date) => {
|
|
8475
|
+
const d = new Date(date);
|
|
8476
|
+
const day = d.getDay(); // 0=Sun … 6=Sat
|
|
8477
|
+
const diff = day === 0 ? -6 : 1 - day;
|
|
8478
|
+
d.setDate(d.getDate() + diff);
|
|
8479
|
+
d.setHours(0, 0, 0, 0);
|
|
8480
|
+
return d;
|
|
8481
|
+
};
|
|
8482
|
+
const toLocalMidnight = (input) => {
|
|
8483
|
+
const d = typeof input === 'string' ? new Date(input + 'T00:00:00') : new Date(input);
|
|
8484
|
+
d.setHours(0, 0, 0, 0);
|
|
8485
|
+
return d;
|
|
8486
|
+
};
|
|
8487
|
+
const diffDays = (start, end) => {
|
|
8488
|
+
return Math.round((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1;
|
|
8489
|
+
};
|
|
8490
|
+
const toISODateString$1 = (input) => {
|
|
8491
|
+
const d = typeof input === 'string' ? new Date(input + 'T00:00:00') : new Date(input);
|
|
8492
|
+
return d.toISOString();
|
|
8493
|
+
};
|
|
8494
|
+
const round2 = (n) => Math.round(n * 100) / 100;
|
|
8495
|
+
const mapAsset$1 = (asset, getAssetByName) => {
|
|
8496
|
+
var _a, _b, _c, _d;
|
|
8497
|
+
const metadata = getAssetByName(asset.coin);
|
|
8498
|
+
const marketInfo = getMarketInfoFromSymbol(asset.coin);
|
|
8499
|
+
return {
|
|
8500
|
+
coin: asset.coin,
|
|
8501
|
+
symbol: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.symbolName) !== null && _a !== void 0 ? _a : marketInfo.symbolName,
|
|
8502
|
+
assetName: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.assetName) !== null && _b !== void 0 ? _b : asset.coin,
|
|
8503
|
+
marketPrefix: (_c = metadata === null || metadata === void 0 ? void 0 : metadata.marketName) !== null && _c !== void 0 ? _c : marketInfo.marketName,
|
|
8504
|
+
percentage: asset.closeWeight * 100,
|
|
8505
|
+
collateralToken: (_d = metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) !== null && _d !== void 0 ? _d : 'USDC',
|
|
8506
|
+
};
|
|
8507
|
+
};
|
|
8508
|
+
const getCollateralTypes$1 = (assets) => {
|
|
8509
|
+
const set = new Set();
|
|
8510
|
+
for (const a of assets)
|
|
8511
|
+
set.add(a.collateralToken);
|
|
8512
|
+
return set.size > 0 ? Array.from(set) : ['USDC'];
|
|
8513
|
+
};
|
|
8514
|
+
const buildSummary = (days) => {
|
|
8515
|
+
let pnl = 0;
|
|
8516
|
+
let volume = 0;
|
|
8517
|
+
let wins = 0;
|
|
8518
|
+
let losses = 0;
|
|
8519
|
+
let totalProfit = 0;
|
|
8520
|
+
let totalLoss = 0;
|
|
8521
|
+
for (const day of days) {
|
|
8522
|
+
pnl += day.totalPnl;
|
|
8523
|
+
volume += day.volume;
|
|
8524
|
+
if (day.positionsClosed === 0)
|
|
8525
|
+
continue;
|
|
8526
|
+
if (day.totalPnl > 0) {
|
|
8527
|
+
wins++;
|
|
8528
|
+
totalProfit += day.totalPnl;
|
|
8529
|
+
}
|
|
8530
|
+
else if (day.totalPnl < 0) {
|
|
8531
|
+
losses++;
|
|
8532
|
+
totalLoss += Math.abs(day.totalPnl);
|
|
8533
|
+
}
|
|
8534
|
+
}
|
|
8535
|
+
const total = wins + losses;
|
|
8536
|
+
const winRate = total > 0 ? Math.round((wins / total) * 100) : 0;
|
|
8537
|
+
return {
|
|
8538
|
+
pnl: round2(pnl),
|
|
8539
|
+
volume: round2(volume),
|
|
8540
|
+
winRate,
|
|
8541
|
+
wins,
|
|
8542
|
+
losses,
|
|
8543
|
+
totalProfit: round2(totalProfit),
|
|
8544
|
+
totalLoss: round2(totalLoss),
|
|
8545
|
+
};
|
|
8546
|
+
};
|
|
8547
|
+
const buildCalendarData = (tradeHistories, timeframe, rangeStart, rangeEnd, totalDays, useCustomDates, getAssetByName) => {
|
|
8548
|
+
const startKey = toDateKey(rangeStart);
|
|
8549
|
+
const endKey = toDateKey(rangeEnd);
|
|
8550
|
+
// Build day buckets for the full range
|
|
8551
|
+
const buckets = new Map();
|
|
8552
|
+
for (let i = 0; i < totalDays; i++) {
|
|
8553
|
+
const d = new Date(rangeStart);
|
|
8554
|
+
d.setDate(rangeStart.getDate() + i);
|
|
8555
|
+
buckets.set(toDateKey(d), {
|
|
8556
|
+
pnl: 0,
|
|
8557
|
+
volume: 0,
|
|
8558
|
+
positionsClosed: 0,
|
|
8559
|
+
trades: [],
|
|
8560
|
+
});
|
|
8561
|
+
}
|
|
8562
|
+
// Populate buckets from trade histories
|
|
8563
|
+
for (const trade of tradeHistories) {
|
|
8564
|
+
if (!trade.createdAt)
|
|
8565
|
+
continue;
|
|
8566
|
+
const date = new Date(trade.createdAt);
|
|
8567
|
+
if (isNaN(date.getTime()))
|
|
8568
|
+
continue;
|
|
8569
|
+
const dateKey = toDateKey(date);
|
|
8570
|
+
if (dateKey < startKey || dateKey > endKey)
|
|
8571
|
+
continue;
|
|
8572
|
+
const bucket = buckets.get(dateKey);
|
|
8573
|
+
if (!bucket)
|
|
8574
|
+
continue;
|
|
8575
|
+
const pnl = trade.realizedPnl;
|
|
8576
|
+
bucket.pnl += isFinite(pnl) ? pnl : 0;
|
|
8577
|
+
const vol = trade.totalValue;
|
|
8578
|
+
bucket.volume += isFinite(vol) ? vol : 0;
|
|
8579
|
+
bucket.positionsClosed += 1;
|
|
8580
|
+
const tradePnl = trade.realizedPnl;
|
|
8581
|
+
const longAssets = trade.closedLongAssets.map((a) => mapAsset$1(a, getAssetByName));
|
|
8582
|
+
const shortAssets = trade.closedShortAssets.map((a) => mapAsset$1(a, getAssetByName));
|
|
8583
|
+
bucket.trades.push({
|
|
8584
|
+
tradeHistoryId: trade.tradeHistoryId,
|
|
8585
|
+
realizedPnl: tradePnl,
|
|
8586
|
+
result: tradePnl > 0 ? 'profit' : tradePnl < 0 ? 'loss' : 'breakeven',
|
|
8587
|
+
collateralTypes: getCollateralTypes$1([...longAssets, ...shortAssets]),
|
|
8588
|
+
closedLongAssets: longAssets,
|
|
8589
|
+
closedShortAssets: shortAssets,
|
|
8590
|
+
});
|
|
8591
|
+
}
|
|
8592
|
+
// Build day objects
|
|
8593
|
+
const allDays = [];
|
|
8594
|
+
const sortedKeys = Array.from(buckets.keys()).sort();
|
|
8595
|
+
for (const key of sortedKeys) {
|
|
8596
|
+
const bucket = buckets.get(key);
|
|
8597
|
+
const roundedPnl = round2(bucket.pnl);
|
|
8598
|
+
const result = roundedPnl > 0 ? 'profit' : roundedPnl < 0 ? 'loss' : 'breakeven';
|
|
8599
|
+
allDays.push({
|
|
8600
|
+
date: key,
|
|
8601
|
+
totalPnl: roundedPnl,
|
|
8602
|
+
volume: round2(bucket.volume),
|
|
8603
|
+
positionsClosed: bucket.positionsClosed,
|
|
8604
|
+
result,
|
|
8605
|
+
trades: bucket.trades,
|
|
8606
|
+
});
|
|
8607
|
+
}
|
|
8608
|
+
// Group into periods
|
|
8609
|
+
let weeks = [];
|
|
8610
|
+
let months = [];
|
|
8611
|
+
const useWeekGrouping = useCustomDates
|
|
8612
|
+
? totalDays <= 28
|
|
8613
|
+
: isWeekTimeframe(timeframe);
|
|
8614
|
+
if (useWeekGrouping) {
|
|
8615
|
+
const weekMap = new Map();
|
|
8616
|
+
for (const day of allDays) {
|
|
8617
|
+
const date = new Date(day.date + 'T00:00:00');
|
|
8618
|
+
const monday = getMonday(date);
|
|
8619
|
+
const mondayKey = toDateKey(monday);
|
|
8620
|
+
if (!weekMap.has(mondayKey)) {
|
|
8621
|
+
weekMap.set(mondayKey, []);
|
|
8622
|
+
}
|
|
8623
|
+
weekMap.get(mondayKey).push(day);
|
|
8624
|
+
}
|
|
8625
|
+
const sortedWeekKeys = Array.from(weekMap.keys()).sort();
|
|
8626
|
+
weeks = sortedWeekKeys.map((mondayKey) => {
|
|
8627
|
+
const days = weekMap.get(mondayKey);
|
|
8628
|
+
const monday = new Date(mondayKey + 'T00:00:00');
|
|
8629
|
+
const sunday = new Date(monday);
|
|
8630
|
+
sunday.setDate(monday.getDate() + 6);
|
|
8631
|
+
return {
|
|
8632
|
+
weekStart: mondayKey,
|
|
8633
|
+
weekEnd: toDateKey(sunday),
|
|
8634
|
+
days,
|
|
8635
|
+
summary: buildSummary(days),
|
|
8636
|
+
};
|
|
8637
|
+
});
|
|
8638
|
+
}
|
|
8639
|
+
else {
|
|
8640
|
+
const monthMap = new Map();
|
|
8641
|
+
for (const day of allDays) {
|
|
8642
|
+
const date = new Date(day.date + 'T00:00:00');
|
|
8643
|
+
const mk = toMonthKey(date);
|
|
8644
|
+
if (!monthMap.has(mk)) {
|
|
8645
|
+
monthMap.set(mk, { days: [], label: formatMonthLabel(date) });
|
|
8646
|
+
}
|
|
8647
|
+
monthMap.get(mk).days.push(day);
|
|
8648
|
+
}
|
|
8649
|
+
const sortedMonthKeys = Array.from(monthMap.keys()).sort();
|
|
8650
|
+
months = sortedMonthKeys.map((mk) => {
|
|
8651
|
+
const { days, label } = monthMap.get(mk);
|
|
8652
|
+
return {
|
|
8653
|
+
month: mk,
|
|
8654
|
+
label,
|
|
8655
|
+
days,
|
|
8656
|
+
summary: buildSummary(days),
|
|
8657
|
+
};
|
|
8658
|
+
});
|
|
8659
|
+
}
|
|
8660
|
+
return {
|
|
8661
|
+
timeframe,
|
|
8662
|
+
weeks,
|
|
8663
|
+
months,
|
|
8664
|
+
overall: buildSummary(allDays),
|
|
8665
|
+
isLoading: false,
|
|
8666
|
+
};
|
|
8667
|
+
};
|
|
8668
|
+
// ─── hook ───────────────────────────────────────────────────────
|
|
8669
|
+
function usePnlCalendar(options) {
|
|
8670
|
+
var _a;
|
|
8671
|
+
const opts = typeof options === 'string'
|
|
8672
|
+
? { timeframe: options }
|
|
8673
|
+
: options !== null && options !== void 0 ? options : {};
|
|
8674
|
+
const timeframe = (_a = opts.timeframe) !== null && _a !== void 0 ? _a : '2W';
|
|
8675
|
+
const customStart = opts.startDate;
|
|
8676
|
+
const customEnd = opts.endDate;
|
|
8677
|
+
const context = useContext(PearHyperliquidContext);
|
|
8678
|
+
if (!context) {
|
|
8679
|
+
throw new Error('usePnlCalendar must be used within a PearHyperliquidProvider');
|
|
8680
|
+
}
|
|
8681
|
+
const { apiBaseUrl } = context;
|
|
8682
|
+
const isAuthenticated = useUserData((state) => state.isAuthenticated);
|
|
8683
|
+
const { getAssetByName } = useMarket();
|
|
8684
|
+
const [trades, setTrades] = useState(null);
|
|
8685
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
8686
|
+
const [error, setError] = useState(null);
|
|
8687
|
+
const mountedRef = useRef(true);
|
|
8688
|
+
useEffect(() => {
|
|
8689
|
+
mountedRef.current = true;
|
|
8690
|
+
return () => { mountedRef.current = false; };
|
|
8691
|
+
}, []);
|
|
8692
|
+
// Compute the date range
|
|
8693
|
+
const useCustomDates = !!(customStart && customEnd);
|
|
8694
|
+
let rangeStart;
|
|
8695
|
+
let rangeEnd;
|
|
8696
|
+
let totalDays;
|
|
8697
|
+
if (useCustomDates) {
|
|
8698
|
+
rangeStart = toLocalMidnight(customStart);
|
|
8699
|
+
rangeEnd = toLocalMidnight(customEnd);
|
|
8700
|
+
totalDays = diffDays(rangeStart, rangeEnd);
|
|
8701
|
+
}
|
|
8702
|
+
else {
|
|
8703
|
+
totalDays = getTimeframeDays$1(timeframe);
|
|
8704
|
+
rangeEnd = new Date();
|
|
8705
|
+
rangeEnd.setHours(0, 0, 0, 0);
|
|
8706
|
+
rangeStart = new Date(rangeEnd);
|
|
8707
|
+
rangeStart.setDate(rangeEnd.getDate() - totalDays + 1);
|
|
8708
|
+
}
|
|
8709
|
+
const startIso = toISODateString$1(rangeStart);
|
|
8710
|
+
const endIso = toISODateString$1(rangeEnd);
|
|
8711
|
+
const fetchData = useCallback(async () => {
|
|
8712
|
+
if (!isAuthenticated)
|
|
8713
|
+
return;
|
|
8714
|
+
setIsLoading(true);
|
|
8715
|
+
setError(null);
|
|
8716
|
+
try {
|
|
8717
|
+
const response = await getTradeHistory(apiBaseUrl, {
|
|
8718
|
+
startDate: startIso,
|
|
8719
|
+
endDate: endIso,
|
|
8720
|
+
limit: totalDays * 50,
|
|
8721
|
+
});
|
|
8722
|
+
if (!mountedRef.current)
|
|
8723
|
+
return;
|
|
8724
|
+
setTrades(response.data);
|
|
8725
|
+
}
|
|
8726
|
+
catch (err) {
|
|
8727
|
+
if (!mountedRef.current)
|
|
8728
|
+
return;
|
|
8729
|
+
setError(err instanceof Error ? err.message : 'Failed to fetch trade history');
|
|
8730
|
+
setTrades(null);
|
|
8731
|
+
}
|
|
8732
|
+
finally {
|
|
8733
|
+
if (mountedRef.current)
|
|
8734
|
+
setIsLoading(false);
|
|
8735
|
+
}
|
|
8736
|
+
}, [apiBaseUrl, isAuthenticated, startIso, endIso, totalDays]);
|
|
8737
|
+
useEffect(() => {
|
|
8738
|
+
fetchData();
|
|
8739
|
+
}, [fetchData]);
|
|
8740
|
+
const result = useMemo(() => {
|
|
8741
|
+
const empty = {
|
|
8742
|
+
timeframe,
|
|
8743
|
+
weeks: [],
|
|
8744
|
+
months: [],
|
|
8745
|
+
overall: EMPTY_SUMMARY,
|
|
8746
|
+
isLoading: true,
|
|
8747
|
+
};
|
|
8748
|
+
if (!trades)
|
|
8749
|
+
return empty;
|
|
8750
|
+
if (totalDays <= 0)
|
|
8751
|
+
return empty;
|
|
8752
|
+
return buildCalendarData(trades, timeframe, rangeStart, rangeEnd, totalDays, useCustomDates, getAssetByName);
|
|
8753
|
+
}, [trades, timeframe, startIso, endIso, getAssetByName]);
|
|
8754
|
+
return { ...result, isLoading, error, refetch: fetchData };
|
|
8755
|
+
}
|
|
8756
|
+
|
|
8757
|
+
const HEATMAP_LIMIT = 50;
|
|
8758
|
+
// ─── helpers ────────────────────────────────────────────────────
|
|
8759
|
+
const getTimeframeDays = (tf) => {
|
|
8760
|
+
switch (tf) {
|
|
8761
|
+
case '7D':
|
|
8762
|
+
return 7;
|
|
8763
|
+
case '30D':
|
|
8764
|
+
return 30;
|
|
8765
|
+
case '100D':
|
|
8766
|
+
return 100;
|
|
8767
|
+
case 'allTime':
|
|
8768
|
+
return null;
|
|
8769
|
+
}
|
|
8770
|
+
};
|
|
8771
|
+
const toISODateString = (date) => date.toISOString();
|
|
8772
|
+
const mapAsset = (asset, getAssetByName) => {
|
|
8773
|
+
var _a, _b, _c, _d;
|
|
8774
|
+
const metadata = getAssetByName(asset.coin);
|
|
8775
|
+
const marketInfo = getMarketInfoFromSymbol(asset.coin);
|
|
8776
|
+
return {
|
|
8777
|
+
coin: asset.coin,
|
|
8778
|
+
symbol: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.symbolName) !== null && _a !== void 0 ? _a : marketInfo.symbolName,
|
|
8779
|
+
assetName: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.assetName) !== null && _b !== void 0 ? _b : asset.coin,
|
|
8780
|
+
marketPrefix: (_c = metadata === null || metadata === void 0 ? void 0 : metadata.marketName) !== null && _c !== void 0 ? _c : marketInfo.marketName,
|
|
8781
|
+
percentage: asset.closeWeight * 100,
|
|
8782
|
+
collateralToken: (_d = metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) !== null && _d !== void 0 ? _d : 'USDC',
|
|
8783
|
+
};
|
|
8784
|
+
};
|
|
8785
|
+
const getCollateralTypes = (assets) => {
|
|
8786
|
+
const set = new Set();
|
|
8787
|
+
for (const a of assets)
|
|
8788
|
+
set.add(a.collateralToken);
|
|
8789
|
+
return set.size > 0 ? Array.from(set) : ['USDC'];
|
|
8790
|
+
};
|
|
8791
|
+
const toCalendarTrade = (trade, getAssetByName) => {
|
|
8792
|
+
const pnl = trade.realizedPnl;
|
|
8793
|
+
const longAssets = trade.closedLongAssets.map((a) => mapAsset(a, getAssetByName));
|
|
8794
|
+
const shortAssets = trade.closedShortAssets.map((a) => mapAsset(a, getAssetByName));
|
|
8795
|
+
return {
|
|
8796
|
+
tradeHistoryId: trade.tradeHistoryId,
|
|
8797
|
+
realizedPnl: pnl,
|
|
8798
|
+
result: pnl > 0 ? 'profit' : pnl < 0 ? 'loss' : 'breakeven',
|
|
8799
|
+
collateralTypes: getCollateralTypes([...longAssets, ...shortAssets]),
|
|
8800
|
+
closedLongAssets: longAssets,
|
|
8801
|
+
closedShortAssets: shortAssets,
|
|
8802
|
+
};
|
|
8803
|
+
};
|
|
8804
|
+
// ─── hook ───────────────────────────────────────────────────────
|
|
8805
|
+
function usePnlHeatmap(timeframe = 'allTime') {
|
|
8806
|
+
const context = useContext(PearHyperliquidContext);
|
|
8807
|
+
if (!context) {
|
|
8808
|
+
throw new Error('usePnlHeatmap must be used within a PearHyperliquidProvider');
|
|
8809
|
+
}
|
|
8810
|
+
const { apiBaseUrl } = context;
|
|
8811
|
+
const isAuthenticated = useUserData((state) => state.isAuthenticated);
|
|
8812
|
+
const { getAssetByName } = useMarket();
|
|
8813
|
+
const [trades, setTrades] = useState(null);
|
|
8814
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
8815
|
+
const [error, setError] = useState(null);
|
|
8816
|
+
const mountedRef = useRef(true);
|
|
8817
|
+
useEffect(() => {
|
|
8818
|
+
mountedRef.current = true;
|
|
8819
|
+
return () => { mountedRef.current = false; };
|
|
8820
|
+
}, []);
|
|
8821
|
+
const days = getTimeframeDays(timeframe);
|
|
8822
|
+
let startIso;
|
|
8823
|
+
if (days !== null) {
|
|
8824
|
+
const start = new Date();
|
|
8825
|
+
start.setHours(0, 0, 0, 0);
|
|
8826
|
+
start.setDate(start.getDate() - days);
|
|
8827
|
+
startIso = toISODateString(start);
|
|
8828
|
+
}
|
|
8829
|
+
const fetchData = useCallback(async () => {
|
|
8830
|
+
if (!isAuthenticated)
|
|
8831
|
+
return;
|
|
8832
|
+
setIsLoading(true);
|
|
8833
|
+
setError(null);
|
|
8834
|
+
try {
|
|
8835
|
+
const response = await getTradeHistory(apiBaseUrl, {
|
|
8836
|
+
...(startIso ? { startDate: startIso } : {}),
|
|
8837
|
+
limit: 5000,
|
|
8838
|
+
});
|
|
8839
|
+
if (!mountedRef.current)
|
|
8840
|
+
return;
|
|
8841
|
+
setTrades(response.data);
|
|
8842
|
+
}
|
|
8843
|
+
catch (err) {
|
|
8844
|
+
if (!mountedRef.current)
|
|
8845
|
+
return;
|
|
8846
|
+
setError(err instanceof Error ? err.message : 'Failed to fetch trade history');
|
|
8847
|
+
setTrades(null);
|
|
8848
|
+
}
|
|
8849
|
+
finally {
|
|
8850
|
+
if (mountedRef.current)
|
|
8851
|
+
setIsLoading(false);
|
|
8852
|
+
}
|
|
8853
|
+
}, [apiBaseUrl, isAuthenticated, startIso]);
|
|
8854
|
+
useEffect(() => {
|
|
8855
|
+
fetchData();
|
|
8856
|
+
}, [fetchData]);
|
|
8857
|
+
const result = useMemo(() => {
|
|
8858
|
+
if (!trades)
|
|
8859
|
+
return [];
|
|
8860
|
+
const top = trades
|
|
8861
|
+
.slice()
|
|
8862
|
+
.sort((a, b) => Math.abs(b.realizedPnl) - Math.abs(a.realizedPnl))
|
|
8863
|
+
.slice(0, HEATMAP_LIMIT);
|
|
8864
|
+
const totalAbsPnl = top.reduce((sum, t) => sum + Math.abs(t.realizedPnl), 0);
|
|
8865
|
+
return top.map((t) => ({
|
|
8866
|
+
...toCalendarTrade(t, getAssetByName),
|
|
8867
|
+
percentage: totalAbsPnl > 0
|
|
8868
|
+
? Math.round((Math.abs(t.realizedPnl) / totalAbsPnl) * 10000) / 100
|
|
8869
|
+
: 0,
|
|
8870
|
+
}));
|
|
8871
|
+
}, [trades, getAssetByName]);
|
|
8872
|
+
return { timeframe, trades: result, isLoading, error, refetch: fetchData };
|
|
8873
|
+
}
|
|
8874
|
+
|
|
8341
8875
|
const PearHyperliquidContext = createContext(undefined);
|
|
8342
8876
|
/**
|
|
8343
8877
|
* React Provider for PearHyperliquidClient
|
|
@@ -8689,4 +9223,4 @@ function getOrderTrailingInfo(order) {
|
|
|
8689
9223
|
return undefined;
|
|
8690
9224
|
}
|
|
8691
9225
|
|
|
8692
|
-
export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
|
9226
|
+
export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePnlCalendar, usePnlHeatmap, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
package/dist/types.d.ts
CHANGED
|
@@ -258,6 +258,7 @@ export interface PositionAssetDetailDto {
|
|
|
258
258
|
initialWeight: number;
|
|
259
259
|
currentWeight: number;
|
|
260
260
|
fundingPaid?: number;
|
|
261
|
+
targetWeight?: number;
|
|
261
262
|
metadata?: TokenMetadata | null;
|
|
262
263
|
}
|
|
263
264
|
export interface TpSlThreshold {
|
|
@@ -735,6 +736,7 @@ export interface RawAssetDto {
|
|
|
735
736
|
side: string;
|
|
736
737
|
fundingPaid?: number;
|
|
737
738
|
leverage: number;
|
|
739
|
+
targetWeight?: number;
|
|
738
740
|
}
|
|
739
741
|
/**
|
|
740
742
|
* Raw position data from open-positions channel
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pear-protocol/hyperliquid-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20-pnl",
|
|
4
4
|
"description": "React SDK for Pear Protocol Hyperliquid API integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"zustand": "^5.0.9"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"react": "^18.0.0",
|
|
32
|
-
"react-dom": "^18.0.0"
|
|
31
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
32
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@rollup/plugin-commonjs": "^25.0.0",
|