@anrmk/str-package 0.1.22 → 0.1.24
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/{utils/challengeHelper.cjs → chunk-6R5UUXX4.js} +21 -8
- package/dist/chunk-6R5UUXX4.js.map +1 -0
- package/dist/chunk-DYYQMXKC.js +31 -0
- package/dist/chunk-DYYQMXKC.js.map +1 -0
- package/dist/{chunk-6M7HA36Z.js → chunk-Q6DF2HKM.js} +2 -2
- package/dist/{chunk-6M7HA36Z.js.map → chunk-Q6DF2HKM.js.map} +1 -1
- package/dist/{utils/bybitHelper.cjs → clients/index.cjs} +68 -5
- package/dist/clients/index.cjs.map +1 -0
- package/dist/clients/index.d.cts +16 -0
- package/dist/clients/index.d.ts +16 -0
- package/dist/clients/index.js +4 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -19
- package/dist/index.d.ts +3 -19
- package/dist/index.js +3 -32
- package/dist/index.js.map +1 -1
- package/dist/providers/bybit/index.js +1 -1
- package/dist/types/challenge/index.d.cts +1 -0
- package/dist/types/challenge/index.d.ts +1 -0
- package/dist/utils/index.cjs +222 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/{challengeHelper.d.cts → index.d.cts} +13 -1
- package/dist/utils/{challengeHelper.d.ts → index.d.ts} +13 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-GIWOOWDE.js +0 -39
- package/dist/chunk-GIWOOWDE.js.map +0 -1
- package/dist/chunk-LMNE5WZX.js +0 -99
- package/dist/chunk-LMNE5WZX.js.map +0 -1
- package/dist/utils/bybitHelper.cjs.map +0 -1
- package/dist/utils/bybitHelper.d.cts +0 -11
- package/dist/utils/bybitHelper.d.ts +0 -11
- package/dist/utils/bybitHelper.js +0 -3
- package/dist/utils/bybitHelper.js.map +0 -1
- package/dist/utils/challengeHelper.cjs.map +0 -1
- package/dist/utils/challengeHelper.js +0 -5
- package/dist/utils/challengeHelper.js.map +0 -1
- package/dist/utils/helper.cjs +0 -43
- package/dist/utils/helper.cjs.map +0 -1
- package/dist/utils/helper.d.cts +0 -5
- package/dist/utils/helper.d.ts +0 -5
- package/dist/utils/helper.js +0 -3
- package/dist/utils/helper.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export { IBybitAccountInfo, IBybitApiResponseList, IBybitClosedPnl, IBybitClosedPnlRequest, IBybitClosedPnlResponse, IBybitCoinBalance, IBybitDemoApplyMoneyItem, IBybitDemoApplyMoneyPayload, IBybitDemoApplyMoneyRequest, IBybitDemoApplyMoneyResponse, IBybitPositionInfo, IBybitServerTime, IBybitSignRequest, IBybitWalletAccount, IBybitWalletResponse } from './types/bybit/index.cjs';
|
|
1
|
+
export { BybitClient } from './clients/index.cjs';
|
|
3
2
|
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance } from './providers/bybit/index.cjs';
|
|
4
|
-
export { getBybitTimestamp, signBybitRequest, syncBybitServerTime } from './utils/
|
|
5
|
-
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, tradingDaysCountCalculation } from './utils/challengeHelper.cjs';
|
|
6
|
-
export { isSameUtcDay, parseNumber, toIsoDate } from './utils/helper.cjs';
|
|
3
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, getBybitTimestamp, isSameUtcDay, parseNumber, signBybitRequest, syncBybitServerTime, toIsoDate, tradingDaysCountCalculation } from './utils/index.cjs';
|
|
7
4
|
export { TSyncResponse } from './types/index.cjs';
|
|
5
|
+
export { IBybitAccountInfo, IBybitApiKeyInfo, IBybitApiResponse, IBybitApiResponseList, IBybitClosedPnl, IBybitClosedPnlRequest, IBybitClosedPnlResponse, IBybitCoinBalance, IBybitCredentials, IBybitDemoApplyMoneyItem, IBybitDemoApplyMoneyPayload, IBybitDemoApplyMoneyRequest, IBybitDemoApplyMoneyResponse, IBybitPositionInfo, IBybitServerTime, IBybitSignRequest, IBybitWalletAccount, IBybitWalletResponse } from './types/bybit/index.cjs';
|
|
8
6
|
export { TChallengeAccountInfo, TChallengeApiKeyInfo, TChallengeCapital, TChallengeItem, TChallengeListItem, TChallengeMode, TChallengePositionInfo, TChallengeProvider, TChallengeRule, TChallengeRuleGroup, TChallengeStatistics, TChallengeStatus, TChallengeTier, TChallengeType, TDrawdownType, TTradingType } from './types/challenge/index.cjs';
|
|
9
7
|
export { T as TChallengeClosedPnl, a as TChallengeProgress, b as TChallengeWalletBalance } from './TChallengeProgress-C_DBsbUa.cjs';
|
|
10
8
|
export { I as IBybitAccountType, a as IBybitApiKeyVipLevel, b as IBybitCoinType } from './enums--bdw39rp.cjs';
|
|
11
|
-
|
|
12
|
-
declare class BybitClient {
|
|
13
|
-
private readonly credentials;
|
|
14
|
-
private readonly timeOffset;
|
|
15
|
-
constructor(credentials: IBybitCredentials);
|
|
16
|
-
applyDemoMoney(): Promise<void>;
|
|
17
|
-
getAccountInfo(): Promise<void>;
|
|
18
|
-
getApiKeyInfo(): Promise<IBybitApiResponse<IBybitApiKeyInfo>>;
|
|
19
|
-
getClosedPnl(): Promise<void>;
|
|
20
|
-
getPositionInfo(): Promise<void>;
|
|
21
|
-
getWalletBalance(): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { BybitClient, IBybitApiKeyInfo, IBybitApiResponse, IBybitCredentials };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
export { IBybitAccountInfo, IBybitApiResponseList, IBybitClosedPnl, IBybitClosedPnlRequest, IBybitClosedPnlResponse, IBybitCoinBalance, IBybitDemoApplyMoneyItem, IBybitDemoApplyMoneyPayload, IBybitDemoApplyMoneyRequest, IBybitDemoApplyMoneyResponse, IBybitPositionInfo, IBybitServerTime, IBybitSignRequest, IBybitWalletAccount, IBybitWalletResponse } from './types/bybit/index.js';
|
|
1
|
+
export { BybitClient } from './clients/index.js';
|
|
3
2
|
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance } from './providers/bybit/index.js';
|
|
4
|
-
export { getBybitTimestamp, signBybitRequest, syncBybitServerTime } from './utils/
|
|
5
|
-
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, tradingDaysCountCalculation } from './utils/challengeHelper.js';
|
|
6
|
-
export { isSameUtcDay, parseNumber, toIsoDate } from './utils/helper.js';
|
|
3
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, getBybitTimestamp, isSameUtcDay, parseNumber, signBybitRequest, syncBybitServerTime, toIsoDate, tradingDaysCountCalculation } from './utils/index.js';
|
|
7
4
|
export { TSyncResponse } from './types/index.js';
|
|
5
|
+
export { IBybitAccountInfo, IBybitApiKeyInfo, IBybitApiResponse, IBybitApiResponseList, IBybitClosedPnl, IBybitClosedPnlRequest, IBybitClosedPnlResponse, IBybitCoinBalance, IBybitCredentials, IBybitDemoApplyMoneyItem, IBybitDemoApplyMoneyPayload, IBybitDemoApplyMoneyRequest, IBybitDemoApplyMoneyResponse, IBybitPositionInfo, IBybitServerTime, IBybitSignRequest, IBybitWalletAccount, IBybitWalletResponse } from './types/bybit/index.js';
|
|
8
6
|
export { TChallengeAccountInfo, TChallengeApiKeyInfo, TChallengeCapital, TChallengeItem, TChallengeListItem, TChallengeMode, TChallengePositionInfo, TChallengeProvider, TChallengeRule, TChallengeRuleGroup, TChallengeStatistics, TChallengeStatus, TChallengeTier, TChallengeType, TDrawdownType, TTradingType } from './types/challenge/index.js';
|
|
9
7
|
export { T as TChallengeClosedPnl, a as TChallengeProgress, b as TChallengeWalletBalance } from './TChallengeProgress-UmIOnrHy.js';
|
|
10
8
|
export { I as IBybitAccountType, a as IBybitApiKeyVipLevel, b as IBybitCoinType } from './enums--bdw39rp.js';
|
|
11
|
-
|
|
12
|
-
declare class BybitClient {
|
|
13
|
-
private readonly credentials;
|
|
14
|
-
private readonly timeOffset;
|
|
15
|
-
constructor(credentials: IBybitCredentials);
|
|
16
|
-
applyDemoMoney(): Promise<void>;
|
|
17
|
-
getAccountInfo(): Promise<void>;
|
|
18
|
-
getApiKeyInfo(): Promise<IBybitApiResponse<IBybitApiKeyInfo>>;
|
|
19
|
-
getClosedPnl(): Promise<void>;
|
|
20
|
-
getPositionInfo(): Promise<void>;
|
|
21
|
-
getWalletBalance(): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { BybitClient, IBybitApiKeyInfo, IBybitApiResponse, IBybitCredentials };
|
package/dist/index.js
CHANGED
|
@@ -1,35 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getBybitTimestamp, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance, signBybitRequest, syncBybitServerTime } from './chunk-6M7HA36Z.js';
|
|
3
|
-
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, tradingDaysCountCalculation } from './chunk-LMNE5WZX.js';
|
|
1
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, isSameUtcDay, parseNumber, toIsoDate, tradingDaysCountCalculation } from './chunk-6R5UUXX4.js';
|
|
4
2
|
import './chunk-2KHIGJJV.js';
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
// src/client/BybitClient.ts
|
|
8
|
-
var BybitClient = class {
|
|
9
|
-
credentials;
|
|
10
|
-
timeOffset = 0;
|
|
11
|
-
constructor(credentials) {
|
|
12
|
-
this.credentials = credentials;
|
|
13
|
-
(async () => {
|
|
14
|
-
this.timeOffset = await syncBybitServerTime();
|
|
15
|
-
})();
|
|
16
|
-
}
|
|
17
|
-
async applyDemoMoney() {
|
|
18
|
-
}
|
|
19
|
-
async getAccountInfo() {
|
|
20
|
-
}
|
|
21
|
-
async getApiKeyInfo() {
|
|
22
|
-
console.log(this.credentials, this.timeOffset);
|
|
23
|
-
return await getApiKeyInfo(this.credentials, this.timeOffset);
|
|
24
|
-
}
|
|
25
|
-
async getClosedPnl() {
|
|
26
|
-
}
|
|
27
|
-
async getPositionInfo() {
|
|
28
|
-
}
|
|
29
|
-
async getWalletBalance() {
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export { BybitClient };
|
|
3
|
+
export { BybitClient } from './chunk-DYYQMXKC.js';
|
|
4
|
+
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getBybitTimestamp, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance, signBybitRequest, syncBybitServerTime } from './chunk-Q6DF2HKM.js';
|
|
34
5
|
//# sourceMappingURL=index.js.map
|
|
35
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance } from '../../chunk-
|
|
1
|
+
export { applyDemoMoney, getAccountInfo, getApiKeyInfo, getClosedPnl, getPositionInfo, getServerTime, getWalletBalance } from '../../chunk-Q6DF2HKM.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var process$1 = require('process');
|
|
5
|
+
|
|
6
|
+
// src/utils/bybitHelper.ts
|
|
7
|
+
|
|
8
|
+
// src/providers/bybit/constants.ts
|
|
9
|
+
var BYBIT_CONSTANTS = {
|
|
10
|
+
baseUrl: process.env.BYBIT_BASE_URL || "https://api-demo.bybit.com",
|
|
11
|
+
fetchTimeoutMs: Number(process.env.BYBIT_FETCH_TIMEOUT_MS) || 1e4,
|
|
12
|
+
recvWindowTimeoutMs: process.env.BYBIT_RECV_WINDOW_TIMEOUT_MS || "20000"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// src/providers/bybit/get-server-time.ts
|
|
16
|
+
async function getServerTime() {
|
|
17
|
+
let bybitRes;
|
|
18
|
+
try {
|
|
19
|
+
bybitRes = await fetch(
|
|
20
|
+
`${BYBIT_CONSTANTS.baseUrl}/v5/market/time`,
|
|
21
|
+
{
|
|
22
|
+
cache: "no-store"
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error("ByBit Server Time network error", error);
|
|
27
|
+
throw new Error("ByBit Server Time network error", { cause: error });
|
|
28
|
+
}
|
|
29
|
+
if (!bybitRes.ok) {
|
|
30
|
+
console.error("ByBit Server Time request failed", bybitRes.status, bybitRes.statusText);
|
|
31
|
+
throw new Error(`ByBit Server Time request failed: ${bybitRes.status}`);
|
|
32
|
+
}
|
|
33
|
+
let bybitJson;
|
|
34
|
+
try {
|
|
35
|
+
bybitJson = await bybitRes.json();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error("Invalid ByBit Server Time response", error);
|
|
38
|
+
throw new Error("Invalid ByBit Server Time response", { cause: error });
|
|
39
|
+
}
|
|
40
|
+
if (!bybitJson) {
|
|
41
|
+
throw new Error("Invalid ByBit Server Time response");
|
|
42
|
+
}
|
|
43
|
+
if (bybitJson.retCode !== 0) {
|
|
44
|
+
console.error("ByBit Server Time API error", bybitJson);
|
|
45
|
+
throw new Error(bybitJson.retMsg ?? "ByBit server time error");
|
|
46
|
+
}
|
|
47
|
+
return bybitJson;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/utils/bybitHelper.ts
|
|
51
|
+
var BYBIT_RECV_WINDOW_TIMEOUT_MS = process$1.env.NEXT_PUBLIC_BYBIT_RECV_WINDOW_TIMEOUT_MS ?? "20000";
|
|
52
|
+
function signBybitRequest(request) {
|
|
53
|
+
const { credentials, queryString, timeOffset } = request;
|
|
54
|
+
const { apiSecret, apiKey } = credentials;
|
|
55
|
+
const timestamp = getBybitTimestamp(timeOffset);
|
|
56
|
+
console.log("Bybit server time timestamp:", timestamp);
|
|
57
|
+
const payload = `${timestamp}${apiKey}${BYBIT_RECV_WINDOW_TIMEOUT_MS}${queryString ?? ""}`;
|
|
58
|
+
const signature = crypto.createHmac("sha256", apiSecret).update(payload).digest("hex");
|
|
59
|
+
return { signature, timestamp };
|
|
60
|
+
}
|
|
61
|
+
async function syncBybitServerTime() {
|
|
62
|
+
const requestStart = Date.now();
|
|
63
|
+
const { result } = await getServerTime();
|
|
64
|
+
const requestEnd = Date.now();
|
|
65
|
+
const serverTime = Number(result.timeSecond) * 1e3;
|
|
66
|
+
const localMidpoint = requestStart + (requestEnd - requestStart) / 2;
|
|
67
|
+
const bybitTimeOffset = serverTime - localMidpoint;
|
|
68
|
+
console.log({
|
|
69
|
+
serverTime,
|
|
70
|
+
requestStart,
|
|
71
|
+
requestEnd,
|
|
72
|
+
latency: requestEnd - requestStart,
|
|
73
|
+
bybitTimeOffset
|
|
74
|
+
});
|
|
75
|
+
return bybitTimeOffset;
|
|
76
|
+
}
|
|
77
|
+
function getBybitTimestamp(timeOffset = 0) {
|
|
78
|
+
return String(Date.now() + timeOffset - 250);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/utils/helper.ts
|
|
82
|
+
var parseNumber = (value) => {
|
|
83
|
+
if (value === null || value === void 0) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const parsed = Number(value);
|
|
87
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
88
|
+
};
|
|
89
|
+
var toIsoDate = (value) => {
|
|
90
|
+
const parsed = parseNumber(value);
|
|
91
|
+
if (parsed === null || parsed <= 0) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const date = new Date(parsed);
|
|
95
|
+
if (Number.isNaN(date.getTime())) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return date.toISOString();
|
|
99
|
+
};
|
|
100
|
+
var isSameUtcDay = (left, right) => {
|
|
101
|
+
if (!left || !right) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const normalizedLeft = left.trim();
|
|
105
|
+
const normalizedRight = right.trim();
|
|
106
|
+
if (!normalizedLeft || !normalizedRight) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const leftDate = new Date(normalizedLeft);
|
|
110
|
+
const rightDate = new Date(normalizedRight);
|
|
111
|
+
if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return leftDate.toISOString().slice(0, 10) === rightDate.toISOString().slice(0, 10);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/utils/challengeHelper.ts
|
|
118
|
+
var createDefaultWallet = (challengeId = "", capital = 0) => ({
|
|
119
|
+
challengeId,
|
|
120
|
+
accountType: "UNIFIED" /* UNIFIED */,
|
|
121
|
+
totalEquity: 0,
|
|
122
|
+
totalPerpUpl: 0,
|
|
123
|
+
totalWalletBalance: 0,
|
|
124
|
+
totalAvailableBalance: 0,
|
|
125
|
+
capital,
|
|
126
|
+
equity: 0,
|
|
127
|
+
usdValue: 0,
|
|
128
|
+
unrealisedPnl: 0,
|
|
129
|
+
walletBalance: 0,
|
|
130
|
+
availableToWithdraw: 0,
|
|
131
|
+
coin: "USDT" /* USDT */,
|
|
132
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
133
|
+
});
|
|
134
|
+
var createDefaultProgress = (challengeId = "", currentEquity = 0) => ({
|
|
135
|
+
id: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
136
|
+
challengeId,
|
|
137
|
+
currentEquity,
|
|
138
|
+
totalLoss: 0,
|
|
139
|
+
tradingDays: 0,
|
|
140
|
+
dailyDrawdown: 0,
|
|
141
|
+
profitTarget: 0,
|
|
142
|
+
dailyStartingEquity: 0,
|
|
143
|
+
dailyStartingUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
144
|
+
dailyMaxEquity: 0,
|
|
145
|
+
dailyMinEquity: 0,
|
|
146
|
+
dailyMaxUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
147
|
+
dailyMinUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
148
|
+
});
|
|
149
|
+
var tradingDaysCountCalculation = async (closedPnlData, minPositionSize) => {
|
|
150
|
+
if (!closedPnlData || closedPnlData.length === 0) {
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
const closedPnlGrouped = closedPnlData.reduce(
|
|
154
|
+
(acc, trade) => {
|
|
155
|
+
const day = trade.updatedTime.split("T")[0];
|
|
156
|
+
if (!acc[day]) {
|
|
157
|
+
acc[day] = [];
|
|
158
|
+
}
|
|
159
|
+
acc[day].push(trade);
|
|
160
|
+
return acc;
|
|
161
|
+
},
|
|
162
|
+
{}
|
|
163
|
+
);
|
|
164
|
+
return await Object.values(closedPnlGrouped).reduce((count, dayTrades) => {
|
|
165
|
+
const hasQualifyingTrade = dayTrades.some((trade) => {
|
|
166
|
+
const entryValue = trade.cumEntryValue;
|
|
167
|
+
const closedPnL = trade.closedPnl;
|
|
168
|
+
const passesSize = entryValue >= minPositionSize;
|
|
169
|
+
const minRequiredPnL = entryValue * 0.01;
|
|
170
|
+
const passesPnL = Math.abs(closedPnL) >= minRequiredPnL;
|
|
171
|
+
return passesSize && passesPnL;
|
|
172
|
+
});
|
|
173
|
+
return hasQualifyingTrade ? count + 1 : count;
|
|
174
|
+
}, 0);
|
|
175
|
+
};
|
|
176
|
+
var currentDailyEquity = (wallet, progress) => {
|
|
177
|
+
const today = (/* @__PURE__ */ new Date()).toISOString();
|
|
178
|
+
const startDate = (/* @__PURE__ */ new Date()).setUTCHours(0, 0, 0, 0);
|
|
179
|
+
const startDateStr = new Date(startDate).toISOString();
|
|
180
|
+
const { equity, unrealisedPnl } = wallet;
|
|
181
|
+
const {
|
|
182
|
+
dailyStartingEquity,
|
|
183
|
+
dailyMaxEquity,
|
|
184
|
+
dailyMinEquity,
|
|
185
|
+
dailyStartingUpdatedAt,
|
|
186
|
+
dailyMaxUpdatedAt,
|
|
187
|
+
dailyMinUpdatedAt
|
|
188
|
+
} = progress;
|
|
189
|
+
let isSameDay = isSameUtcDay(dailyStartingUpdatedAt, startDateStr);
|
|
190
|
+
const newDailyStartingUpdatedAt = isSameDay ? dailyStartingUpdatedAt : startDateStr;
|
|
191
|
+
const newDailyStartingEquity = isSameDay ? dailyStartingEquity : equity;
|
|
192
|
+
isSameDay = isSameUtcDay(dailyMaxUpdatedAt, today);
|
|
193
|
+
let newMaxUpdatedAt = isSameDay ? dailyMaxUpdatedAt : today;
|
|
194
|
+
const newdailyMaxEquity = Math.max(isSameDay ? dailyMaxEquity : equity, equity);
|
|
195
|
+
isSameDay = isSameUtcDay(dailyMinUpdatedAt, today);
|
|
196
|
+
const newMinUpdatedAt = isSameDay ? dailyMinUpdatedAt : today;
|
|
197
|
+
const newdailyMinEquity = Math.min(isSameDay ? dailyMinEquity : equity, equity);
|
|
198
|
+
const dailyEquityDrawdown = equity - newdailyMaxEquity;
|
|
199
|
+
return {
|
|
200
|
+
currentEquity: equity,
|
|
201
|
+
dailyDrawdown: dailyEquityDrawdown,
|
|
202
|
+
dailyStartingEquity: newDailyStartingEquity,
|
|
203
|
+
dailyStartingUpdatedAt: newDailyStartingUpdatedAt.slice(0, 10),
|
|
204
|
+
dailyMaxEquity: newdailyMaxEquity,
|
|
205
|
+
dailyMaxUpdatedAt: newMaxUpdatedAt,
|
|
206
|
+
dailyMinEquity: newdailyMinEquity,
|
|
207
|
+
dailyMinUpdatedAt: newMinUpdatedAt
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
exports.createDefaultProgress = createDefaultProgress;
|
|
212
|
+
exports.createDefaultWallet = createDefaultWallet;
|
|
213
|
+
exports.currentDailyEquity = currentDailyEquity;
|
|
214
|
+
exports.getBybitTimestamp = getBybitTimestamp;
|
|
215
|
+
exports.isSameUtcDay = isSameUtcDay;
|
|
216
|
+
exports.parseNumber = parseNumber;
|
|
217
|
+
exports.signBybitRequest = signBybitRequest;
|
|
218
|
+
exports.syncBybitServerTime = syncBybitServerTime;
|
|
219
|
+
exports.toIsoDate = toIsoDate;
|
|
220
|
+
exports.tradingDaysCountCalculation = tradingDaysCountCalculation;
|
|
221
|
+
//# sourceMappingURL=index.cjs.map
|
|
222
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/bybit/constants.ts","../../src/providers/bybit/get-server-time.ts","../../src/utils/bybitHelper.ts","../../src/utils/helper.ts","../../src/utils/challengeHelper.ts"],"names":["env","createHmac"],"mappings":"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","file":"index.cjs","sourcesContent":["export const BYBIT_CONSTANTS = {\n baseUrl: process.env.BYBIT_BASE_URL || \"https://api-demo.bybit.com\",\n fetchTimeoutMs: Number(process.env.BYBIT_FETCH_TIMEOUT_MS) || 10000,\n recvWindowTimeoutMs: process.env.BYBIT_RECV_WINDOW_TIMEOUT_MS || \"20000\",\n}","import { BYBIT_CONSTANTS } from \"./constants\";\nimport { IBybitServerTime, IBybitApiResponse } from \"../../types/bybit\";\n\nexport async function getServerTime(): Promise<IBybitApiResponse<IBybitServerTime>> {\n let bybitRes: Response;\n try {\n bybitRes = await fetch(`${BYBIT_CONSTANTS.baseUrl}/v5/market/time`,\n {\n cache: \"no-store\",\n }\n );\n } catch (error) {\n console.error(\"ByBit Server Time network error\", error);\n throw new Error(\"ByBit Server Time network error\", { cause: error });\n }\n\n if (!bybitRes.ok) {\n console.error(\"ByBit Server Time request failed\", bybitRes.status, bybitRes.statusText);\n throw new Error(`ByBit Server Time request failed: ${bybitRes.status}`);\n }\n\n let bybitJson: IBybitApiResponse<IBybitServerTime>;\n\n try {\n bybitJson = (await bybitRes.json()) as IBybitApiResponse<IBybitServerTime>;\n } catch (error) {\n console.error(\"Invalid ByBit Server Time response\", error);\n throw new Error(\"Invalid ByBit Server Time response\", { cause: error });\n }\n\n if (!bybitJson) {\n throw new Error(\"Invalid ByBit Server Time response\");\n }\n\n if (bybitJson.retCode !== 0) {\n console.error(\"ByBit Server Time API error\", bybitJson);\n throw new Error(bybitJson.retMsg ?? \"ByBit server time error\");\n }\n\n return bybitJson;\n}","import { createHmac } from \"crypto\";\nimport { env } from \"node:process\";\nimport { getServerTime } from \"../providers/bybit\";\nimport type { IBybitServerTime, IBybitSignRequest } from \"../types/bybit\";\n\nconst BYBIT_RECV_WINDOW_TIMEOUT_MS =\n env.NEXT_PUBLIC_BYBIT_RECV_WINDOW_TIMEOUT_MS ?? \"20000\";\n\nexport function signBybitRequest(request: IBybitSignRequest) {\n const { credentials, queryString, timeOffset } = request;\n const { apiSecret, apiKey } = credentials;\n\n const timestamp = getBybitTimestamp(timeOffset);\n console.log(\"Bybit server time timestamp:\", timestamp);\n const payload = `${timestamp}${apiKey}${BYBIT_RECV_WINDOW_TIMEOUT_MS}${queryString ?? \"\"}`;\n const signature = createHmac(\"sha256\", apiSecret)\n .update(payload)\n .digest(\"hex\");\n\n return { signature, timestamp };\n}\n\nexport async function syncBybitServerTime(): Promise<number> {\n const requestStart = Date.now();\n const { result } = await getServerTime();\n const requestEnd = Date.now();\n const serverTime = Number(result.timeSecond) * 1000;\n\n // Estimate the local time at which Bybit generated\n // the response by using the midpoint.\n const localMidpoint = requestStart + (requestEnd - requestStart) / 2;\n\n const bybitTimeOffset = serverTime - localMidpoint;\n\n console.log({\n serverTime,\n requestStart,\n requestEnd,\n latency: requestEnd - requestStart,\n bybitTimeOffset,\n });\n\n return bybitTimeOffset;\n}\n\nexport function getBybitTimestamp(timeOffset: number = 0): string {\n // Small safety margin: keep request slightly behind server.\n return String(Date.now() + timeOffset - 250);\n}","export const parseNumber = (\n value: number | string | null | undefined,\n): number | null => {\n if (value === null || value === undefined) {\n return null;\n }\n\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nexport const toIsoDate = (\n value: string | number | null | undefined,\n): string | null => {\n const parsed = parseNumber(value);\n if (parsed === null || parsed <= 0) {\n return null;\n }\n\n const date = new Date(parsed);\n if (Number.isNaN(date.getTime())) {\n return null;\n }\n\n return date.toISOString();\n};\n\nexport const isSameUtcDay = (\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean => {\n if (!left || !right) {\n return false;\n }\n\n const normalizedLeft = left.trim();\n const normalizedRight = right.trim();\n\n if (!normalizedLeft || !normalizedRight) {\n return false;\n }\n\n const leftDate = new Date(normalizedLeft);\n const rightDate = new Date(normalizedRight);\n\n if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) {\n return false;\n }\n\n return (\n leftDate.toISOString().slice(0, 10) === rightDate.toISOString().slice(0, 10)\n );\n};\n","import {\n TChallengeClosedPnl,\n TChallengeProgress,\n TChallengeWalletBalance,\n} from \"../types/challenge\";\nimport { IBybitAccountType, IBybitCoinType } from \"../types/bybit/enums\";\nimport { isSameUtcDay } from \"./helper\";\n\nexport const createDefaultWallet = (\n challengeId: string = \"\",\n capital: number = 0,\n): TChallengeWalletBalance =>\n ({\n challengeId,\n accountType: IBybitAccountType.UNIFIED,\n totalEquity: 0,\n totalPerpUpl: 0,\n totalWalletBalance: 0,\n totalAvailableBalance: 0,\n capital,\n\n equity: 0,\n usdValue: 0,\n unrealisedPnl: 0,\n walletBalance: 0,\n availableToWithdraw: 0,\n coin: IBybitCoinType.USDT,\n updatedAt: new Date().toISOString(),\n }) as TChallengeWalletBalance;\n\nexport const createDefaultProgress = (\n challengeId: string = \"\",\n currentEquity: number = 0,\n): TChallengeProgress =>\n ({\n id: new Date().getTime().toString(),\n challengeId,\n currentEquity,\n totalLoss: 0,\n tradingDays: 0,\n dailyDrawdown: 0,\n profitTarget: 0,\n dailyStartingEquity: 0,\n dailyStartingUpdatedAt: new Date().toISOString(),\n dailyMaxEquity: 0,\n dailyMinEquity: 0,\n dailyMaxUpdatedAt: new Date().toISOString(),\n dailyMinUpdatedAt: new Date().toISOString(),\n }) as TChallengeProgress;\n\n // A trading day counts if you open and close at least one trade \n// that day with a position size ≥ 5% of the initial balance and a PnL of ±1% or more.\nexport const tradingDaysCountCalculation = async (\n closedPnlData: TChallengeClosedPnl[] | null,\n minPositionSize: number,\n): Promise<number> => {\n if (!closedPnlData || closedPnlData.length === 0) {\n return 0;\n }\n\n const closedPnlGrouped = closedPnlData.reduce(\n (acc, trade) => {\n const day = trade.updatedTime.split(\"T\")[0];\n if (!acc[day]) {\n acc[day] = [];\n }\n acc[day].push(trade);\n return acc;\n },\n {} as Record<string, TChallengeClosedPnl[]>,\n );\n\n return await Object.values(closedPnlGrouped).reduce((count, dayTrades) => {\n // Check if any trade closed today met the minimum size requirement\n const hasQualifyingTrade = dayTrades.some((trade) => {\n const entryValue = trade.cumEntryValue;\n const closedPnL = trade.closedPnl;\n\n // 1. Position size must be >= 5% of initial balance\n const passesSize = entryValue >= minPositionSize;\n\n // 2. PnL must be >= 1% of the position size itself\n const minRequiredPnL = entryValue * 0.01;\n const passesPnL = Math.abs(closedPnL) >= minRequiredPnL;\n\n return passesSize && passesPnL;\n });\n\n return hasQualifyingTrade ? count + 1 : count;\n }, 0);\n};\n\nexport const currentDailyEquity = (\n wallet: TChallengeWalletBalance,\n progress: TChallengeProgress\n) => {\n const today = new Date().toISOString();\n const startDate = new Date().setUTCHours(0, 0, 0, 0);\n const startDateStr = new Date(startDate).toISOString();\n\n const { equity, unrealisedPnl } = wallet;\n const { dailyStartingEquity, dailyMaxEquity, dailyMinEquity, \n dailyStartingUpdatedAt, dailyMaxUpdatedAt, dailyMinUpdatedAt } = progress;\n \n // Determine if the daily starting equity should be updated based on whether it's a new day\n let isSameDay = isSameUtcDay(dailyStartingUpdatedAt, startDateStr)\n const newDailyStartingUpdatedAt = isSameDay ? dailyStartingUpdatedAt : startDateStr;\n const newDailyStartingEquity = isSameDay ? dailyStartingEquity : equity;\n\n // Determine if the max and min daily equity should be updated based on whether it's a new day\n isSameDay = isSameUtcDay(dailyMaxUpdatedAt, today);\n let newMaxUpdatedAt = isSameDay ? dailyMaxUpdatedAt : today;\n const newdailyMaxEquity = Math.max(isSameDay ? dailyMaxEquity : equity , equity);\n \n // Determine if the min daily equity should be updated based on whether it's a new day\n isSameDay = isSameUtcDay(dailyMinUpdatedAt, today);\n const newMinUpdatedAt = isSameDay ? dailyMinUpdatedAt : today;\n const newdailyMinEquity = Math.min(isSameDay ? dailyMinEquity : equity, equity);\n\n //Trailing Drawdown: The difference between the day’s highest equity and the lowest equity reached afterward, both including unrealized P&L.\n const dailyEquityDrawdown = equity - newdailyMaxEquity;\n \n return {\n currentEquity: equity,\n dailyDrawdown: dailyEquityDrawdown,\n\n dailyStartingEquity: newDailyStartingEquity,\n dailyStartingUpdatedAt: newDailyStartingUpdatedAt.slice(0, 10),\n\n dailyMaxEquity: newdailyMaxEquity,\n dailyMaxUpdatedAt: newMaxUpdatedAt,\n\n dailyMinEquity: newdailyMinEquity,\n dailyMinUpdatedAt: newMinUpdatedAt,\n };\n};"]}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import { IBybitSignRequest } from '../types/bybit/index.cjs';
|
|
1
2
|
import { a as TChallengeProgress, b as TChallengeWalletBalance, T as TChallengeClosedPnl } from '../TChallengeProgress-C_DBsbUa.cjs';
|
|
2
3
|
import '../enums--bdw39rp.cjs';
|
|
3
4
|
|
|
5
|
+
declare function signBybitRequest(request: IBybitSignRequest): {
|
|
6
|
+
signature: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
};
|
|
9
|
+
declare function syncBybitServerTime(): Promise<number>;
|
|
10
|
+
declare function getBybitTimestamp(timeOffset?: number): string;
|
|
11
|
+
|
|
4
12
|
declare const createDefaultWallet: (challengeId?: string, capital?: number) => TChallengeWalletBalance;
|
|
5
13
|
declare const createDefaultProgress: (challengeId?: string, currentEquity?: number) => TChallengeProgress;
|
|
6
14
|
declare const tradingDaysCountCalculation: (closedPnlData: TChallengeClosedPnl[] | null, minPositionSize: number) => Promise<number>;
|
|
@@ -15,4 +23,8 @@ declare const currentDailyEquity: (wallet: TChallengeWalletBalance, progress: TC
|
|
|
15
23
|
dailyMinUpdatedAt: string;
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
declare const parseNumber: (value: number | string | null | undefined) => number | null;
|
|
27
|
+
declare const toIsoDate: (value: string | number | null | undefined) => string | null;
|
|
28
|
+
declare const isSameUtcDay: (left: string | null | undefined, right: string | null | undefined) => boolean;
|
|
29
|
+
|
|
30
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, getBybitTimestamp, isSameUtcDay, parseNumber, signBybitRequest, syncBybitServerTime, toIsoDate, tradingDaysCountCalculation };
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import { IBybitSignRequest } from '../types/bybit/index.js';
|
|
1
2
|
import { a as TChallengeProgress, b as TChallengeWalletBalance, T as TChallengeClosedPnl } from '../TChallengeProgress-UmIOnrHy.js';
|
|
2
3
|
import '../enums--bdw39rp.js';
|
|
3
4
|
|
|
5
|
+
declare function signBybitRequest(request: IBybitSignRequest): {
|
|
6
|
+
signature: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
};
|
|
9
|
+
declare function syncBybitServerTime(): Promise<number>;
|
|
10
|
+
declare function getBybitTimestamp(timeOffset?: number): string;
|
|
11
|
+
|
|
4
12
|
declare const createDefaultWallet: (challengeId?: string, capital?: number) => TChallengeWalletBalance;
|
|
5
13
|
declare const createDefaultProgress: (challengeId?: string, currentEquity?: number) => TChallengeProgress;
|
|
6
14
|
declare const tradingDaysCountCalculation: (closedPnlData: TChallengeClosedPnl[] | null, minPositionSize: number) => Promise<number>;
|
|
@@ -15,4 +23,8 @@ declare const currentDailyEquity: (wallet: TChallengeWalletBalance, progress: TC
|
|
|
15
23
|
dailyMinUpdatedAt: string;
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
declare const parseNumber: (value: number | string | null | undefined) => number | null;
|
|
27
|
+
declare const toIsoDate: (value: string | number | null | undefined) => string | null;
|
|
28
|
+
declare const isSameUtcDay: (left: string | null | undefined, right: string | null | undefined) => boolean;
|
|
29
|
+
|
|
30
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, getBybitTimestamp, isSameUtcDay, parseNumber, signBybitRequest, syncBybitServerTime, toIsoDate, tradingDaysCountCalculation };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, isSameUtcDay, parseNumber, toIsoDate, tradingDaysCountCalculation } from '../chunk-6R5UUXX4.js';
|
|
2
|
+
import '../chunk-2KHIGJJV.js';
|
|
3
|
+
export { getBybitTimestamp, signBybitRequest, syncBybitServerTime } from '../chunk-Q6DF2HKM.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/package.json
CHANGED
package/dist/chunk-GIWOOWDE.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// src/utils/helper.ts
|
|
2
|
-
var parseNumber = (value) => {
|
|
3
|
-
if (value === null || value === void 0) {
|
|
4
|
-
return null;
|
|
5
|
-
}
|
|
6
|
-
const parsed = Number(value);
|
|
7
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
8
|
-
};
|
|
9
|
-
var toIsoDate = (value) => {
|
|
10
|
-
const parsed = parseNumber(value);
|
|
11
|
-
if (parsed === null || parsed <= 0) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const date = new Date(parsed);
|
|
15
|
-
if (Number.isNaN(date.getTime())) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return date.toISOString();
|
|
19
|
-
};
|
|
20
|
-
var isSameUtcDay = (left, right) => {
|
|
21
|
-
if (!left || !right) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const normalizedLeft = left.trim();
|
|
25
|
-
const normalizedRight = right.trim();
|
|
26
|
-
if (!normalizedLeft || !normalizedRight) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
const leftDate = new Date(normalizedLeft);
|
|
30
|
-
const rightDate = new Date(normalizedRight);
|
|
31
|
-
if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return leftDate.toISOString().slice(0, 10) === rightDate.toISOString().slice(0, 10);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export { isSameUtcDay, parseNumber, toIsoDate };
|
|
38
|
-
//# sourceMappingURL=chunk-GIWOOWDE.js.map
|
|
39
|
-
//# sourceMappingURL=chunk-GIWOOWDE.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/helper.ts"],"names":[],"mappings":";AAAO,IAAM,WAAA,GAAc,CACzB,KAAA,KACkB;AAClB,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,GAAI,MAAA,GAAS,IAAA;AAC5C;AAEO,IAAM,SAAA,GAAY,CACvB,KAAA,KACkB;AAClB,EAAA,MAAM,MAAA,GAAS,YAAY,KAAK,CAAA;AAChC,EAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,IAAU,CAAA,EAAG;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,MAAM,CAAA;AAC5B,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAK,WAAA,EAAY;AAC1B;AAEO,IAAM,YAAA,GAAe,CAC1B,IAAA,EACA,KAAA,KACY;AACZ,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,KAAA,EAAO;AACnB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAA,GAAiB,KAAK,IAAA,EAAK;AACjC,EAAA,MAAM,eAAA,GAAkB,MAAM,IAAA,EAAK;AAEnC,EAAA,IAAI,CAAC,cAAA,IAAkB,CAAC,eAAA,EAAiB;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GAAW,IAAI,IAAA,CAAK,cAAc,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,eAAe,CAAA;AAE1C,EAAA,IAAI,MAAA,CAAO,KAAA,CAAM,QAAA,CAAS,OAAA,EAAS,CAAA,IAAK,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,OAAA,EAAS,CAAA,EAAG;AACzE,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OACE,QAAA,CAAS,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,KAAM,SAAA,CAAU,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAE/E","file":"chunk-GIWOOWDE.js","sourcesContent":["export const parseNumber = (\n value: number | string | null | undefined,\n): number | null => {\n if (value === null || value === undefined) {\n return null;\n }\n\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nexport const toIsoDate = (\n value: string | number | null | undefined,\n): string | null => {\n const parsed = parseNumber(value);\n if (parsed === null || parsed <= 0) {\n return null;\n }\n\n const date = new Date(parsed);\n if (Number.isNaN(date.getTime())) {\n return null;\n }\n\n return date.toISOString();\n};\n\nexport const isSameUtcDay = (\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean => {\n if (!left || !right) {\n return false;\n }\n\n const normalizedLeft = left.trim();\n const normalizedRight = right.trim();\n\n if (!normalizedLeft || !normalizedRight) {\n return false;\n }\n\n const leftDate = new Date(normalizedLeft);\n const rightDate = new Date(normalizedRight);\n\n if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) {\n return false;\n }\n\n return (\n leftDate.toISOString().slice(0, 10) === rightDate.toISOString().slice(0, 10)\n );\n};\n"]}
|
package/dist/chunk-LMNE5WZX.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { isSameUtcDay } from './chunk-GIWOOWDE.js';
|
|
2
|
-
|
|
3
|
-
// src/utils/challengeHelper.ts
|
|
4
|
-
var createDefaultWallet = (challengeId = "", capital = 0) => ({
|
|
5
|
-
challengeId,
|
|
6
|
-
accountType: "UNIFIED" /* UNIFIED */,
|
|
7
|
-
totalEquity: 0,
|
|
8
|
-
totalPerpUpl: 0,
|
|
9
|
-
totalWalletBalance: 0,
|
|
10
|
-
totalAvailableBalance: 0,
|
|
11
|
-
capital,
|
|
12
|
-
equity: 0,
|
|
13
|
-
usdValue: 0,
|
|
14
|
-
unrealisedPnl: 0,
|
|
15
|
-
walletBalance: 0,
|
|
16
|
-
availableToWithdraw: 0,
|
|
17
|
-
coin: "USDT" /* USDT */,
|
|
18
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
19
|
-
});
|
|
20
|
-
var createDefaultProgress = (challengeId = "", currentEquity = 0) => ({
|
|
21
|
-
id: (/* @__PURE__ */ new Date()).getTime().toString(),
|
|
22
|
-
challengeId,
|
|
23
|
-
currentEquity,
|
|
24
|
-
totalLoss: 0,
|
|
25
|
-
tradingDays: 0,
|
|
26
|
-
dailyDrawdown: 0,
|
|
27
|
-
profitTarget: 0,
|
|
28
|
-
dailyStartingEquity: 0,
|
|
29
|
-
dailyStartingUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30
|
-
dailyMaxEquity: 0,
|
|
31
|
-
dailyMinEquity: 0,
|
|
32
|
-
dailyMaxUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33
|
-
dailyMinUpdatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34
|
-
});
|
|
35
|
-
var tradingDaysCountCalculation = async (closedPnlData, minPositionSize) => {
|
|
36
|
-
if (!closedPnlData || closedPnlData.length === 0) {
|
|
37
|
-
return 0;
|
|
38
|
-
}
|
|
39
|
-
const closedPnlGrouped = closedPnlData.reduce(
|
|
40
|
-
(acc, trade) => {
|
|
41
|
-
const day = trade.updatedTime.split("T")[0];
|
|
42
|
-
if (!acc[day]) {
|
|
43
|
-
acc[day] = [];
|
|
44
|
-
}
|
|
45
|
-
acc[day].push(trade);
|
|
46
|
-
return acc;
|
|
47
|
-
},
|
|
48
|
-
{}
|
|
49
|
-
);
|
|
50
|
-
return await Object.values(closedPnlGrouped).reduce((count, dayTrades) => {
|
|
51
|
-
const hasQualifyingTrade = dayTrades.some((trade) => {
|
|
52
|
-
const entryValue = trade.cumEntryValue;
|
|
53
|
-
const closedPnL = trade.closedPnl;
|
|
54
|
-
const passesSize = entryValue >= minPositionSize;
|
|
55
|
-
const minRequiredPnL = entryValue * 0.01;
|
|
56
|
-
const passesPnL = Math.abs(closedPnL) >= minRequiredPnL;
|
|
57
|
-
return passesSize && passesPnL;
|
|
58
|
-
});
|
|
59
|
-
return hasQualifyingTrade ? count + 1 : count;
|
|
60
|
-
}, 0);
|
|
61
|
-
};
|
|
62
|
-
var currentDailyEquity = (wallet, progress) => {
|
|
63
|
-
const today = (/* @__PURE__ */ new Date()).toISOString();
|
|
64
|
-
const startDate = (/* @__PURE__ */ new Date()).setUTCHours(0, 0, 0, 0);
|
|
65
|
-
const startDateStr = new Date(startDate).toISOString();
|
|
66
|
-
const { equity, unrealisedPnl } = wallet;
|
|
67
|
-
const {
|
|
68
|
-
dailyStartingEquity,
|
|
69
|
-
dailyMaxEquity,
|
|
70
|
-
dailyMinEquity,
|
|
71
|
-
dailyStartingUpdatedAt,
|
|
72
|
-
dailyMaxUpdatedAt,
|
|
73
|
-
dailyMinUpdatedAt
|
|
74
|
-
} = progress;
|
|
75
|
-
let isSameDay = isSameUtcDay(dailyStartingUpdatedAt, startDateStr);
|
|
76
|
-
const newDailyStartingUpdatedAt = isSameDay ? dailyStartingUpdatedAt : startDateStr;
|
|
77
|
-
const newDailyStartingEquity = isSameDay ? dailyStartingEquity : equity;
|
|
78
|
-
isSameDay = isSameUtcDay(dailyMaxUpdatedAt, today);
|
|
79
|
-
let newMaxUpdatedAt = isSameDay ? dailyMaxUpdatedAt : today;
|
|
80
|
-
const newdailyMaxEquity = Math.max(isSameDay ? dailyMaxEquity : equity, equity);
|
|
81
|
-
isSameDay = isSameUtcDay(dailyMinUpdatedAt, today);
|
|
82
|
-
const newMinUpdatedAt = isSameDay ? dailyMinUpdatedAt : today;
|
|
83
|
-
const newdailyMinEquity = Math.min(isSameDay ? dailyMinEquity : equity, equity);
|
|
84
|
-
const dailyEquityDrawdown = equity - newdailyMaxEquity;
|
|
85
|
-
return {
|
|
86
|
-
currentEquity: equity,
|
|
87
|
-
dailyDrawdown: dailyEquityDrawdown,
|
|
88
|
-
dailyStartingEquity: newDailyStartingEquity,
|
|
89
|
-
dailyStartingUpdatedAt: newDailyStartingUpdatedAt.slice(0, 10),
|
|
90
|
-
dailyMaxEquity: newdailyMaxEquity,
|
|
91
|
-
dailyMaxUpdatedAt: newMaxUpdatedAt,
|
|
92
|
-
dailyMinEquity: newdailyMinEquity,
|
|
93
|
-
dailyMinUpdatedAt: newMinUpdatedAt
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export { createDefaultProgress, createDefaultWallet, currentDailyEquity, tradingDaysCountCalculation };
|
|
98
|
-
//# sourceMappingURL=chunk-LMNE5WZX.js.map
|
|
99
|
-
//# sourceMappingURL=chunk-LMNE5WZX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/challengeHelper.ts"],"names":[],"mappings":"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","file":"chunk-LMNE5WZX.js","sourcesContent":["import {\n TChallengeClosedPnl,\n TChallengeProgress,\n TChallengeWalletBalance,\n} from \"../types/challenge\";\nimport { IBybitAccountType, IBybitCoinType } from \"../types/bybit/enums\";\nimport { isSameUtcDay } from \"./helper\";\n\nexport const createDefaultWallet = (\n challengeId: string = \"\",\n capital: number = 0,\n): TChallengeWalletBalance =>\n ({\n challengeId,\n accountType: IBybitAccountType.UNIFIED,\n totalEquity: 0,\n totalPerpUpl: 0,\n totalWalletBalance: 0,\n totalAvailableBalance: 0,\n capital,\n\n equity: 0,\n usdValue: 0,\n unrealisedPnl: 0,\n walletBalance: 0,\n availableToWithdraw: 0,\n coin: IBybitCoinType.USDT,\n updatedAt: new Date().toISOString(),\n }) as TChallengeWalletBalance;\n\nexport const createDefaultProgress = (\n challengeId: string = \"\",\n currentEquity: number = 0,\n): TChallengeProgress =>\n ({\n id: new Date().getTime().toString(),\n challengeId,\n currentEquity,\n totalLoss: 0,\n tradingDays: 0,\n dailyDrawdown: 0,\n profitTarget: 0,\n dailyStartingEquity: 0,\n dailyStartingUpdatedAt: new Date().toISOString(),\n dailyMaxEquity: 0,\n dailyMinEquity: 0,\n dailyMaxUpdatedAt: new Date().toISOString(),\n dailyMinUpdatedAt: new Date().toISOString(),\n }) as TChallengeProgress;\n\n // A trading day counts if you open and close at least one trade \n// that day with a position size ≥ 5% of the initial balance and a PnL of ±1% or more.\nexport const tradingDaysCountCalculation = async (\n closedPnlData: TChallengeClosedPnl[] | null,\n minPositionSize: number,\n): Promise<number> => {\n if (!closedPnlData || closedPnlData.length === 0) {\n return 0;\n }\n\n const closedPnlGrouped = closedPnlData.reduce(\n (acc, trade) => {\n const day = trade.updatedTime.split(\"T\")[0];\n if (!acc[day]) {\n acc[day] = [];\n }\n acc[day].push(trade);\n return acc;\n },\n {} as Record<string, TChallengeClosedPnl[]>,\n );\n\n return await Object.values(closedPnlGrouped).reduce((count, dayTrades) => {\n // Check if any trade closed today met the minimum size requirement\n const hasQualifyingTrade = dayTrades.some((trade) => {\n const entryValue = trade.cumEntryValue;\n const closedPnL = trade.closedPnl;\n\n // 1. Position size must be >= 5% of initial balance\n const passesSize = entryValue >= minPositionSize;\n\n // 2. PnL must be >= 1% of the position size itself\n const minRequiredPnL = entryValue * 0.01;\n const passesPnL = Math.abs(closedPnL) >= minRequiredPnL;\n\n return passesSize && passesPnL;\n });\n\n return hasQualifyingTrade ? count + 1 : count;\n }, 0);\n};\n\nexport const currentDailyEquity = (\n wallet: TChallengeWalletBalance,\n progress: TChallengeProgress\n) => {\n const today = new Date().toISOString();\n const startDate = new Date().setUTCHours(0, 0, 0, 0);\n const startDateStr = new Date(startDate).toISOString();\n\n const { equity, unrealisedPnl } = wallet;\n const { dailyStartingEquity, dailyMaxEquity, dailyMinEquity, \n dailyStartingUpdatedAt, dailyMaxUpdatedAt, dailyMinUpdatedAt } = progress;\n \n // Determine if the daily starting equity should be updated based on whether it's a new day\n let isSameDay = isSameUtcDay(dailyStartingUpdatedAt, startDateStr)\n const newDailyStartingUpdatedAt = isSameDay ? dailyStartingUpdatedAt : startDateStr;\n const newDailyStartingEquity = isSameDay ? dailyStartingEquity : equity;\n\n // Determine if the max and min daily equity should be updated based on whether it's a new day\n isSameDay = isSameUtcDay(dailyMaxUpdatedAt, today);\n let newMaxUpdatedAt = isSameDay ? dailyMaxUpdatedAt : today;\n const newdailyMaxEquity = Math.max(isSameDay ? dailyMaxEquity : equity , equity);\n \n // Determine if the min daily equity should be updated based on whether it's a new day\n isSameDay = isSameUtcDay(dailyMinUpdatedAt, today);\n const newMinUpdatedAt = isSameDay ? dailyMinUpdatedAt : today;\n const newdailyMinEquity = Math.min(isSameDay ? dailyMinEquity : equity, equity);\n\n //Trailing Drawdown: The difference between the day’s highest equity and the lowest equity reached afterward, both including unrealized P&L.\n const dailyEquityDrawdown = equity - newdailyMaxEquity;\n \n return {\n currentEquity: equity,\n dailyDrawdown: dailyEquityDrawdown,\n\n dailyStartingEquity: newDailyStartingEquity,\n dailyStartingUpdatedAt: newDailyStartingUpdatedAt.slice(0, 10),\n\n dailyMaxEquity: newdailyMaxEquity,\n dailyMaxUpdatedAt: newMaxUpdatedAt,\n\n dailyMinEquity: newdailyMinEquity,\n dailyMinUpdatedAt: newMinUpdatedAt,\n };\n};"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/bybit/constants.ts","../../src/providers/bybit/get-server-time.ts","../../src/utils/bybitHelper.ts"],"names":["env","createHmac"],"mappings":"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","file":"bybitHelper.cjs","sourcesContent":["export const BYBIT_CONSTANTS = {\n baseUrl: process.env.BYBIT_BASE_URL || \"https://api-demo.bybit.com\",\n fetchTimeoutMs: Number(process.env.BYBIT_FETCH_TIMEOUT_MS) || 10000,\n recvWindowTimeoutMs: process.env.BYBIT_RECV_WINDOW_TIMEOUT_MS || \"20000\",\n}","import { BYBIT_CONSTANTS } from \"./constants\";\nimport { IBybitServerTime, IBybitApiResponse } from \"../../types/bybit\";\n\nexport async function getServerTime(): Promise<IBybitApiResponse<IBybitServerTime>> {\n let bybitRes: Response;\n try {\n bybitRes = await fetch(`${BYBIT_CONSTANTS.baseUrl}/v5/market/time`,\n {\n cache: \"no-store\",\n }\n );\n } catch (error) {\n console.error(\"ByBit Server Time network error\", error);\n throw new Error(\"ByBit Server Time network error\", { cause: error });\n }\n\n if (!bybitRes.ok) {\n console.error(\"ByBit Server Time request failed\", bybitRes.status, bybitRes.statusText);\n throw new Error(`ByBit Server Time request failed: ${bybitRes.status}`);\n }\n\n let bybitJson: IBybitApiResponse<IBybitServerTime>;\n\n try {\n bybitJson = (await bybitRes.json()) as IBybitApiResponse<IBybitServerTime>;\n } catch (error) {\n console.error(\"Invalid ByBit Server Time response\", error);\n throw new Error(\"Invalid ByBit Server Time response\", { cause: error });\n }\n\n if (!bybitJson) {\n throw new Error(\"Invalid ByBit Server Time response\");\n }\n\n if (bybitJson.retCode !== 0) {\n console.error(\"ByBit Server Time API error\", bybitJson);\n throw new Error(bybitJson.retMsg ?? \"ByBit server time error\");\n }\n\n return bybitJson;\n}","import { createHmac } from \"crypto\";\nimport { env } from \"node:process\";\nimport { getServerTime } from \"../providers/bybit\";\nimport type { IBybitServerTime, IBybitSignRequest } from \"../types/bybit\";\n\nconst BYBIT_RECV_WINDOW_TIMEOUT_MS =\n env.NEXT_PUBLIC_BYBIT_RECV_WINDOW_TIMEOUT_MS ?? \"20000\";\n\nexport function signBybitRequest(request: IBybitSignRequest) {\n const { credentials, queryString, timeOffset } = request;\n const { apiSecret, apiKey } = credentials;\n\n const timestamp = getBybitTimestamp(timeOffset);\n console.log(\"Bybit server time timestamp:\", timestamp);\n const payload = `${timestamp}${apiKey}${BYBIT_RECV_WINDOW_TIMEOUT_MS}${queryString ?? \"\"}`;\n const signature = createHmac(\"sha256\", apiSecret)\n .update(payload)\n .digest(\"hex\");\n\n return { signature, timestamp };\n}\n\nexport async function syncBybitServerTime(): Promise<number> {\n const requestStart = Date.now();\n const { result } = await getServerTime();\n const requestEnd = Date.now();\n const serverTime = Number(result.timeSecond) * 1000;\n\n // Estimate the local time at which Bybit generated\n // the response by using the midpoint.\n const localMidpoint = requestStart + (requestEnd - requestStart) / 2;\n\n const bybitTimeOffset = serverTime - localMidpoint;\n\n console.log({\n serverTime,\n requestStart,\n requestEnd,\n latency: requestEnd - requestStart,\n bybitTimeOffset,\n });\n\n return bybitTimeOffset;\n}\n\nexport function getBybitTimestamp(timeOffset: number = 0): string {\n // Small safety margin: keep request slightly behind server.\n return String(Date.now() + timeOffset - 250);\n}"]}
|