@pear-protocol/hyperliquid-sdk 0.1.20-pnl → 0.1.22-beta
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/README.md +12 -3
- package/dist/clients/positions.d.ts +15 -3
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/usePosition.d.ts +2 -2
- package/dist/index.d.ts +32 -80
- package/dist/index.js +57 -453
- package/dist/types.d.ts +2 -0
- package/dist/utils/position-validator.d.ts +14 -1
- package/package.json +1 -1
- package/dist/clients/tradeHistory.d.ts +0 -7
- package/dist/hooks/usePnlCalendar.d.ts +0 -61
- package/dist/hooks/usePnlHeatmap.d.ts +0 -13
package/README.md
CHANGED
|
@@ -557,8 +557,17 @@ const result = await createPosition(apiBaseUrl, {
|
|
|
557
557
|
executionType: 'MARKET',
|
|
558
558
|
});
|
|
559
559
|
|
|
560
|
-
// Close position
|
|
561
|
-
await closePosition(apiBaseUrl, positionId, {
|
|
560
|
+
// Close position immediately
|
|
561
|
+
await closePosition(apiBaseUrl, positionId, { executionType: 'MARKET' });
|
|
562
|
+
|
|
563
|
+
// Close position conditionally
|
|
564
|
+
// Example: close when the weighted price ratio rises above 1.08.
|
|
565
|
+
await closePosition(apiBaseUrl, positionId, {
|
|
566
|
+
executionType: 'TRIGGER',
|
|
567
|
+
triggerType: 'WEIGHTED_RATIO',
|
|
568
|
+
triggerValue: '1.08',
|
|
569
|
+
direction: 'MORE_THAN',
|
|
570
|
+
});
|
|
562
571
|
|
|
563
572
|
// Update TP/SL
|
|
564
573
|
await updateRiskParameters(apiBaseUrl, positionId, {
|
|
@@ -864,7 +873,7 @@ function TradingInterface() {
|
|
|
864
873
|
{openPositions?.map(pos => (
|
|
865
874
|
<div key={pos.positionId}>
|
|
866
875
|
PnL: ${pos.unrealizedPnl.toFixed(2)}
|
|
867
|
-
<button onClick={() => closePosition(pos.positionId, {
|
|
876
|
+
<button onClick={() => closePosition(pos.positionId, { executionType: 'MARKET' })}>
|
|
868
877
|
Close
|
|
869
878
|
</button>
|
|
870
879
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApiResponse, CreatePositionRequestInput, CreatePositionResponseDto, TpSlThresholdInput } from "../types";
|
|
1
|
+
import type { ApiResponse, CloseExecutionType, CloseTriggerType, CreatePositionRequestInput, CreatePositionResponseDto, OrderDirection, TpSlThresholdInput } from "../types";
|
|
2
2
|
import type { CancelTwapResponseDto } from "./orders";
|
|
3
3
|
/**
|
|
4
4
|
* Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
|
|
@@ -18,17 +18,22 @@ export interface UpdateRiskParametersResponseDto {
|
|
|
18
18
|
updatedAt: string;
|
|
19
19
|
}
|
|
20
20
|
export declare function updateRiskParameters(baseUrl: string, positionId: string, payload: UpdateRiskParametersRequestInput): Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
21
|
-
export type
|
|
21
|
+
export type ClosePositionExecutionType = CloseExecutionType;
|
|
22
|
+
export type CloseAllExecutionType = "MARKET" | "TWAP";
|
|
22
23
|
export interface ClosePositionRequestInput {
|
|
23
24
|
executionType: CloseExecutionType;
|
|
24
25
|
twapDuration?: number;
|
|
25
26
|
twapIntervalSeconds?: number;
|
|
26
27
|
randomizeExecution?: boolean;
|
|
28
|
+
triggerType?: CloseTriggerType;
|
|
29
|
+
triggerValue?: string;
|
|
30
|
+
direction?: OrderDirection;
|
|
27
31
|
referralCode?: string;
|
|
28
32
|
}
|
|
29
33
|
export interface ClosePositionResponseDto {
|
|
30
34
|
orderId: string;
|
|
31
35
|
executionTime?: string;
|
|
36
|
+
orderIds?: string[];
|
|
32
37
|
chunksScheduled?: number;
|
|
33
38
|
}
|
|
34
39
|
export declare function closePosition(baseUrl: string, positionId: string, payload: ClosePositionRequestInput): Promise<ApiResponse<ClosePositionResponseDto>>;
|
|
@@ -41,7 +46,14 @@ export interface CloseAllPositionsResultDto {
|
|
|
41
46
|
export interface CloseAllPositionsResponseDto {
|
|
42
47
|
results: CloseAllPositionsResultDto[];
|
|
43
48
|
}
|
|
44
|
-
export
|
|
49
|
+
export interface CloseAllPositionsRequestInput {
|
|
50
|
+
executionType: CloseAllExecutionType;
|
|
51
|
+
twapDuration?: number;
|
|
52
|
+
twapIntervalSeconds?: number;
|
|
53
|
+
randomizeExecution?: boolean;
|
|
54
|
+
referralCode?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function closeAllPositions(baseUrl: string, payload: CloseAllPositionsRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
|
|
45
57
|
export type AdjustExecutionType = "MARKET" | "LIMIT";
|
|
46
58
|
export type PositionAdjustmentType = "REDUCE" | "INCREASE";
|
|
47
59
|
export interface AdjustPositionRequestInput {
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
1
|
+
import { type UpdateRiskParametersRequestInput, type UpdateRiskParametersResponseDto, type ClosePositionRequestInput, type ClosePositionResponseDto, type CloseAllPositionsRequestInput, 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
3
|
export interface RebalanceAssetPlan {
|
|
4
4
|
coin: string;
|
|
@@ -23,7 +23,7 @@ export declare function usePosition(): {
|
|
|
23
23
|
readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
|
|
24
24
|
readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
25
25
|
readonly closePosition: (positionId: string, payload: ClosePositionRequestInput) => Promise<ApiResponse<ClosePositionResponseDto>>;
|
|
26
|
-
readonly closeAllPositions: (payload:
|
|
26
|
+
readonly closeAllPositions: (payload: CloseAllPositionsRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
|
|
27
27
|
readonly adjustPosition: (positionId: string, payload: AdjustPositionRequestInput) => Promise<ApiResponse<AdjustPositionResponseDto>>;
|
|
28
28
|
readonly adjustAdvancePosition: (positionId: string, payload: AdjustAdvanceItemInput[]) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
|
|
29
29
|
readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -342,6 +342,8 @@ type TpSlTriggerType = 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE' | 'PRICE' | 'P
|
|
|
342
342
|
* Trigger type for trigger orders
|
|
343
343
|
*/
|
|
344
344
|
type TriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'BTC_DOM' | 'CROSS_ASSET_PRICE' | 'PREDICTION_MARKET_OUTCOME';
|
|
345
|
+
type CloseTriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE';
|
|
346
|
+
type CloseExecutionType = 'MARKET' | 'TWAP' | 'TRIGGER';
|
|
345
347
|
type OrderDirection = 'MORE_THAN' | 'LESS_THAN';
|
|
346
348
|
/**
|
|
347
349
|
* Market order parameters
|
|
@@ -1232,17 +1234,22 @@ interface UpdateRiskParametersResponseDto {
|
|
|
1232
1234
|
updatedAt: string;
|
|
1233
1235
|
}
|
|
1234
1236
|
declare function updateRiskParameters(baseUrl: string, positionId: string, payload: UpdateRiskParametersRequestInput): Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
1235
|
-
type
|
|
1237
|
+
type ClosePositionExecutionType = CloseExecutionType;
|
|
1238
|
+
type CloseAllExecutionType = "MARKET" | "TWAP";
|
|
1236
1239
|
interface ClosePositionRequestInput {
|
|
1237
1240
|
executionType: CloseExecutionType;
|
|
1238
1241
|
twapDuration?: number;
|
|
1239
1242
|
twapIntervalSeconds?: number;
|
|
1240
1243
|
randomizeExecution?: boolean;
|
|
1244
|
+
triggerType?: CloseTriggerType;
|
|
1245
|
+
triggerValue?: string;
|
|
1246
|
+
direction?: OrderDirection;
|
|
1241
1247
|
referralCode?: string;
|
|
1242
1248
|
}
|
|
1243
1249
|
interface ClosePositionResponseDto {
|
|
1244
1250
|
orderId: string;
|
|
1245
1251
|
executionTime?: string;
|
|
1252
|
+
orderIds?: string[];
|
|
1246
1253
|
chunksScheduled?: number;
|
|
1247
1254
|
}
|
|
1248
1255
|
declare function closePosition(baseUrl: string, positionId: string, payload: ClosePositionRequestInput): Promise<ApiResponse<ClosePositionResponseDto>>;
|
|
@@ -1255,7 +1262,14 @@ interface CloseAllPositionsResultDto {
|
|
|
1255
1262
|
interface CloseAllPositionsResponseDto {
|
|
1256
1263
|
results: CloseAllPositionsResultDto[];
|
|
1257
1264
|
}
|
|
1258
|
-
|
|
1265
|
+
interface CloseAllPositionsRequestInput {
|
|
1266
|
+
executionType: CloseAllExecutionType;
|
|
1267
|
+
twapDuration?: number;
|
|
1268
|
+
twapIntervalSeconds?: number;
|
|
1269
|
+
randomizeExecution?: boolean;
|
|
1270
|
+
referralCode?: string;
|
|
1271
|
+
}
|
|
1272
|
+
declare function closeAllPositions(baseUrl: string, payload: CloseAllPositionsRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
|
|
1259
1273
|
type AdjustExecutionType = "MARKET" | "LIMIT";
|
|
1260
1274
|
type PositionAdjustmentType = "REDUCE" | "INCREASE";
|
|
1261
1275
|
interface AdjustPositionRequestInput {
|
|
@@ -1320,7 +1334,7 @@ declare function usePosition(): {
|
|
|
1320
1334
|
readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
|
|
1321
1335
|
readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
|
|
1322
1336
|
readonly closePosition: (positionId: string, payload: ClosePositionRequestInput) => Promise<ApiResponse<ClosePositionResponseDto>>;
|
|
1323
|
-
readonly closeAllPositions: (payload:
|
|
1337
|
+
readonly closeAllPositions: (payload: CloseAllPositionsRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
|
|
1324
1338
|
readonly adjustPosition: (positionId: string, payload: AdjustPositionRequestInput) => Promise<ApiResponse<AdjustPositionResponseDto>>;
|
|
1325
1339
|
readonly adjustAdvancePosition: (positionId: string, payload: AdjustAdvanceItemInput[]) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
|
|
1326
1340
|
readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
|
|
@@ -1498,81 +1512,6 @@ interface UseHyperliquidUserFillsState {
|
|
|
1498
1512
|
*/
|
|
1499
1513
|
declare function useHyperliquidUserFills(options: UseHyperliquidUserFillsOptions): UseHyperliquidUserFillsState;
|
|
1500
1514
|
|
|
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
|
-
|
|
1576
1515
|
/**
|
|
1577
1516
|
* Mark notifications as read up to a given timestamp (ms)
|
|
1578
1517
|
*/
|
|
@@ -1748,6 +1687,9 @@ declare class MaxAssetsPerLegError extends Error {
|
|
|
1748
1687
|
maxAllowed: number;
|
|
1749
1688
|
constructor(leg: "long" | "short", assetCount: number, maxAllowed: number);
|
|
1750
1689
|
}
|
|
1690
|
+
declare class ClosePositionValidationError extends Error {
|
|
1691
|
+
constructor(message: string);
|
|
1692
|
+
}
|
|
1751
1693
|
/**
|
|
1752
1694
|
* Validates that each leg doesn't exceed the maximum number of assets
|
|
1753
1695
|
* @param longAssets Array of long assets
|
|
@@ -1782,6 +1724,16 @@ declare function validatePositionSize(usdValue: number, longAssets?: PairAssetIn
|
|
|
1782
1724
|
error?: string;
|
|
1783
1725
|
minimumRequired?: number;
|
|
1784
1726
|
};
|
|
1727
|
+
interface ClosePositionValidationInput {
|
|
1728
|
+
executionType: CloseExecutionType;
|
|
1729
|
+
twapDuration?: number;
|
|
1730
|
+
twapIntervalSeconds?: number;
|
|
1731
|
+
randomizeExecution?: boolean;
|
|
1732
|
+
triggerType?: CloseTriggerType;
|
|
1733
|
+
triggerValue?: string;
|
|
1734
|
+
direction?: OrderDirection;
|
|
1735
|
+
}
|
|
1736
|
+
declare function validateClosePositionRequest(payload: ClosePositionValidationInput): void;
|
|
1785
1737
|
|
|
1786
1738
|
/**
|
|
1787
1739
|
* Helper functions to safely extract values from order parameters
|
|
@@ -1847,5 +1799,5 @@ interface MarketDataState {
|
|
|
1847
1799
|
}
|
|
1848
1800
|
declare const useMarketData: zustand.UseBoundStore<zustand.StoreApi<MarketDataState>>;
|
|
1849
1801
|
|
|
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,
|
|
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,
|
|
1802
|
+
export { ClosePositionValidationError, 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, validateClosePositionRequest, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
|
1803
|
+
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, CloseAllExecutionType, CloseAllPositionsRequestInput, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CloseTriggerType, 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, 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, UsePortfolioResult, UseSpotOrderResult, UseTokenSelectionMetadataReturn, UserAbstraction, UserProfile, UserSelectionState, WatchlistAssetDto, WatchlistItemDto, WebData3AssetCtx, WebData3PerpDexState, WebData3Response, WebData3UserState, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
|
package/dist/index.js
CHANGED
|
@@ -696,6 +696,12 @@ class MaxAssetsPerLegError extends Error {
|
|
|
696
696
|
this.name = "MaxAssetsPerLegError";
|
|
697
697
|
}
|
|
698
698
|
}
|
|
699
|
+
class ClosePositionValidationError extends Error {
|
|
700
|
+
constructor(message) {
|
|
701
|
+
super(message);
|
|
702
|
+
this.name = "ClosePositionValidationError";
|
|
703
|
+
}
|
|
704
|
+
}
|
|
699
705
|
/**
|
|
700
706
|
* Validates that each leg doesn't exceed the maximum number of assets
|
|
701
707
|
* @param longAssets Array of long assets
|
|
@@ -776,6 +782,44 @@ function validatePositionSize(usdValue, longAssets, shortAssets) {
|
|
|
776
782
|
throw error;
|
|
777
783
|
}
|
|
778
784
|
}
|
|
785
|
+
function isNumberString(value) {
|
|
786
|
+
if (value.trim() === "") {
|
|
787
|
+
return false;
|
|
788
|
+
}
|
|
789
|
+
return Number.isFinite(Number(value));
|
|
790
|
+
}
|
|
791
|
+
function validateClosePositionRequest(payload) {
|
|
792
|
+
if (payload.executionType === "TWAP") {
|
|
793
|
+
if (payload.twapDuration === undefined || payload.twapDuration <= 0) {
|
|
794
|
+
throw new ClosePositionValidationError("twapDuration is required and must be greater than 0 when executionType is TWAP");
|
|
795
|
+
}
|
|
796
|
+
if (payload.twapIntervalSeconds !== undefined &&
|
|
797
|
+
payload.twapIntervalSeconds <= 0) {
|
|
798
|
+
throw new ClosePositionValidationError("twapIntervalSeconds must be greater than 0 when provided for TWAP closes");
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
else if (payload.twapDuration !== undefined ||
|
|
802
|
+
payload.twapIntervalSeconds !== undefined ||
|
|
803
|
+
payload.randomizeExecution !== undefined) {
|
|
804
|
+
throw new ClosePositionValidationError("twapDuration, twapIntervalSeconds, and randomizeExecution are only supported when executionType is TWAP");
|
|
805
|
+
}
|
|
806
|
+
if (payload.executionType === "TRIGGER") {
|
|
807
|
+
if (!payload.triggerType) {
|
|
808
|
+
throw new ClosePositionValidationError("triggerType is required when executionType is TRIGGER");
|
|
809
|
+
}
|
|
810
|
+
if (!payload.direction) {
|
|
811
|
+
throw new ClosePositionValidationError("direction is required when executionType is TRIGGER");
|
|
812
|
+
}
|
|
813
|
+
if (!payload.triggerValue || !isNumberString(payload.triggerValue)) {
|
|
814
|
+
throw new ClosePositionValidationError("triggerValue is required and must be a numeric string when executionType is TRIGGER");
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
else if (payload.triggerType !== undefined ||
|
|
818
|
+
payload.triggerValue !== undefined ||
|
|
819
|
+
payload.direction !== undefined) {
|
|
820
|
+
throw new ClosePositionValidationError("triggerType, triggerValue, and direction are only supported when executionType is TRIGGER");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
779
823
|
|
|
780
824
|
const DEFAULT_STATE = {
|
|
781
825
|
longTokens: [
|
|
@@ -981,7 +1025,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
|
|
|
981
1025
|
// finalAssetContexts now sourced from allDexsAssetCtxs channel
|
|
982
1026
|
const finalAtOICaps = webData3.perpDexStates.flatMap((dex) => dex.perpsAtOpenInterestCap);
|
|
983
1027
|
setFinalAtOICaps(finalAtOICaps);
|
|
984
|
-
setUserAbstractionMode(webData3.userState.abstraction ||
|
|
1028
|
+
setUserAbstractionMode(webData3.userState.abstraction || 'disabled');
|
|
985
1029
|
break;
|
|
986
1030
|
case "allDexsAssetCtxs":
|
|
987
1031
|
{
|
|
@@ -6950,10 +6994,20 @@ async function updateRiskParameters(baseUrl, positionId, payload) {
|
|
|
6950
6994
|
throw toApiError(error);
|
|
6951
6995
|
}
|
|
6952
6996
|
}
|
|
6997
|
+
function normalizeClosePositionPayload(payload) {
|
|
6998
|
+
return {
|
|
6999
|
+
...payload,
|
|
7000
|
+
triggerValue: payload.triggerValue === undefined
|
|
7001
|
+
? undefined
|
|
7002
|
+
: String(payload.triggerValue),
|
|
7003
|
+
};
|
|
7004
|
+
}
|
|
6953
7005
|
async function closePosition(baseUrl, positionId, payload) {
|
|
6954
7006
|
const url = joinUrl(baseUrl, `/positions/${positionId}/close`);
|
|
7007
|
+
const normalizedPayload = normalizeClosePositionPayload(payload);
|
|
7008
|
+
validateClosePositionRequest(normalizedPayload);
|
|
6955
7009
|
try {
|
|
6956
|
-
const resp = await apiClient.post(url,
|
|
7010
|
+
const resp = await apiClient.post(url, normalizedPayload, {
|
|
6957
7011
|
headers: {
|
|
6958
7012
|
"Content-Type": "application/json",
|
|
6959
7013
|
},
|
|
@@ -8422,456 +8476,6 @@ function useHyperliquidUserFills(options) {
|
|
|
8422
8476
|
};
|
|
8423
8477
|
}
|
|
8424
8478
|
|
|
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
|
-
|
|
8875
8479
|
const PearHyperliquidContext = createContext(undefined);
|
|
8876
8480
|
/**
|
|
8877
8481
|
* React Provider for PearHyperliquidClient
|
|
@@ -9223,4 +8827,4 @@ function getOrderTrailingInfo(order) {
|
|
|
9223
8827
|
return undefined;
|
|
9224
8828
|
}
|
|
9225
8829
|
|
|
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,
|
|
8830
|
+
export { ClosePositionValidationError, 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, validateClosePositionRequest, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|
package/dist/types.d.ts
CHANGED
|
@@ -314,6 +314,8 @@ export type TpSlTriggerType = 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE' | 'PRIC
|
|
|
314
314
|
* Trigger type for trigger orders
|
|
315
315
|
*/
|
|
316
316
|
export type TriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'BTC_DOM' | 'CROSS_ASSET_PRICE' | 'PREDICTION_MARKET_OUTCOME';
|
|
317
|
+
export type CloseTriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE';
|
|
318
|
+
export type CloseExecutionType = 'MARKET' | 'TWAP' | 'TRIGGER';
|
|
317
319
|
export type OrderDirection = 'MORE_THAN' | 'LESS_THAN';
|
|
318
320
|
/**
|
|
319
321
|
* Market order parameters
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PairAssetInput } from "../types";
|
|
1
|
+
import type { CloseExecutionType, CloseTriggerType, OrderDirection, PairAssetInput } from "../types";
|
|
2
2
|
/**
|
|
3
3
|
* Minimum USD value required per asset when creating a position
|
|
4
4
|
*/
|
|
@@ -25,6 +25,9 @@ export declare class MaxAssetsPerLegError extends Error {
|
|
|
25
25
|
maxAllowed: number;
|
|
26
26
|
constructor(leg: "long" | "short", assetCount: number, maxAllowed: number);
|
|
27
27
|
}
|
|
28
|
+
export declare class ClosePositionValidationError extends Error {
|
|
29
|
+
constructor(message: string);
|
|
30
|
+
}
|
|
28
31
|
/**
|
|
29
32
|
* Validates that each leg doesn't exceed the maximum number of assets
|
|
30
33
|
* @param longAssets Array of long assets
|
|
@@ -59,3 +62,13 @@ export declare function validatePositionSize(usdValue: number, longAssets?: Pair
|
|
|
59
62
|
error?: string;
|
|
60
63
|
minimumRequired?: number;
|
|
61
64
|
};
|
|
65
|
+
export interface ClosePositionValidationInput {
|
|
66
|
+
executionType: CloseExecutionType;
|
|
67
|
+
twapDuration?: number;
|
|
68
|
+
twapIntervalSeconds?: number;
|
|
69
|
+
randomizeExecution?: boolean;
|
|
70
|
+
triggerType?: CloseTriggerType;
|
|
71
|
+
triggerValue?: string;
|
|
72
|
+
direction?: OrderDirection;
|
|
73
|
+
}
|
|
74
|
+
export declare function validateClosePositionRequest(payload: ClosePositionValidationInput): void;
|
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
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[]>>;
|
|
@@ -1,61 +0,0 @@
|
|
|
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;
|
|
@@ -1,13 +0,0 @@
|
|
|
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;
|