@gbozee/ultimate 0.0.2-1 → 0.0.2-10
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/index.d.ts +95 -4
- package/dist/index.js +316 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
4
4
|
import PocketBase from 'pocketbase';
|
|
5
|
+
import { RecordModel } from 'pocketbase';
|
|
5
6
|
import { SocksProxyAgent } from 'socks-proxy-agent';
|
|
6
7
|
|
|
7
8
|
interface Position$1 {
|
|
8
9
|
id: number;
|
|
9
|
-
kind:
|
|
10
|
+
kind: "long" | "short";
|
|
10
11
|
entry: number;
|
|
11
12
|
symbol: string;
|
|
12
13
|
quantity: number;
|
|
@@ -16,6 +17,9 @@ interface Position$1 {
|
|
|
16
17
|
take_profit: number;
|
|
17
18
|
tp_quantity: number;
|
|
18
19
|
stop_quantity: number;
|
|
20
|
+
target_pnl?: number;
|
|
21
|
+
reduce_ratio?: number;
|
|
22
|
+
use_full?: boolean;
|
|
19
23
|
}
|
|
20
24
|
export interface Account {
|
|
21
25
|
id: number | string;
|
|
@@ -113,10 +117,11 @@ export interface BaseExchange {
|
|
|
113
117
|
price_places?: string;
|
|
114
118
|
decimal_places?: string;
|
|
115
119
|
}): Promise<any>;
|
|
120
|
+
setLeverage(payload: {
|
|
121
|
+
symbol: string;
|
|
122
|
+
leverage: number;
|
|
123
|
+
}): Promise<any>;
|
|
116
124
|
}
|
|
117
|
-
/**
|
|
118
|
-
* TypeScript type definitions for PocketBase collections and views
|
|
119
|
-
*/
|
|
120
125
|
export interface BaseSystemFields {
|
|
121
126
|
id: string;
|
|
122
127
|
created: string;
|
|
@@ -204,6 +209,15 @@ export interface PositionsView {
|
|
|
204
209
|
avg_liquidation?: any;
|
|
205
210
|
balance?: any;
|
|
206
211
|
}
|
|
212
|
+
export interface BullishMarket extends RecordModel {
|
|
213
|
+
id: string;
|
|
214
|
+
symbol: string;
|
|
215
|
+
risk: number;
|
|
216
|
+
}
|
|
217
|
+
export interface WindingDownMarket extends RecordModel {
|
|
218
|
+
id: string;
|
|
219
|
+
symbol: string;
|
|
220
|
+
}
|
|
207
221
|
export type ExchangeType = {
|
|
208
222
|
owner: string;
|
|
209
223
|
exchange: string;
|
|
@@ -211,7 +225,19 @@ export type ExchangeType = {
|
|
|
211
225
|
export declare class AppDatabase {
|
|
212
226
|
private pb;
|
|
213
227
|
constructor(pb: PocketBase);
|
|
228
|
+
createOrUpdateLiveExchangeInstance(payload: {
|
|
229
|
+
account: ExchangeType;
|
|
230
|
+
symbol: string;
|
|
231
|
+
data?: any;
|
|
232
|
+
}): Promise<import("pocketbase").RecordModel>;
|
|
233
|
+
getLiveExchangeInstance(payload: {
|
|
234
|
+
account: ExchangeType;
|
|
235
|
+
symbol: string;
|
|
236
|
+
data?: any;
|
|
237
|
+
}): Promise<import("pocketbase").RecordModel>;
|
|
214
238
|
getProxyForAccount(account: ExchangeType): Promise<HttpsProxyAgent<`http://${string}`> | SocksProxyAgent>;
|
|
239
|
+
getAccounts(): Promise<ExchangeAccount[]>;
|
|
240
|
+
getAllSymbolConfigs(with_positions?: boolean): Promise<SymbolConfig[]>;
|
|
215
241
|
get_exchange_db_instance(account: ExchangeType): Promise<ExchangeAccount & {
|
|
216
242
|
expand?: {
|
|
217
243
|
proxy: Proxy$1;
|
|
@@ -302,6 +328,33 @@ export declare class AppDatabase {
|
|
|
302
328
|
strategy_instance: Strategy;
|
|
303
329
|
focus_account: ExchangeAccount;
|
|
304
330
|
}>;
|
|
331
|
+
createOrUpdateWindingDownMarket(symbol: string): Promise<import("pocketbase").RecordModel>;
|
|
332
|
+
getWindingDownMarkets(): Promise<WindingDownMarket[]>;
|
|
333
|
+
getBullishMarkets(options?: {
|
|
334
|
+
new_markets: Array<{
|
|
335
|
+
symbol: string;
|
|
336
|
+
percent: number;
|
|
337
|
+
}>;
|
|
338
|
+
totalRisk: number;
|
|
339
|
+
}): Promise<{
|
|
340
|
+
updated_bullish: BullishMarket[];
|
|
341
|
+
moved_to_winding: WindingDownMarket[];
|
|
342
|
+
}>;
|
|
343
|
+
updateSymbolConfigs(payload?: {
|
|
344
|
+
configs: Array<{
|
|
345
|
+
symbol: string;
|
|
346
|
+
support: number;
|
|
347
|
+
leverage: number;
|
|
348
|
+
min_size: number;
|
|
349
|
+
resistance: number;
|
|
350
|
+
price_places: string;
|
|
351
|
+
decimal_places: string;
|
|
352
|
+
}>;
|
|
353
|
+
}): Promise<{
|
|
354
|
+
updated: number;
|
|
355
|
+
created: number;
|
|
356
|
+
} | SymbolConfig[]>;
|
|
357
|
+
unwindSymbolFromDB(symbol: string): Promise<void>;
|
|
305
358
|
}
|
|
306
359
|
export interface CodeNode {
|
|
307
360
|
minimum_pnl: number;
|
|
@@ -347,6 +400,17 @@ declare class ExchangeAccount$1 {
|
|
|
347
400
|
exchange: BaseExchange;
|
|
348
401
|
app_db: AppDatabase;
|
|
349
402
|
});
|
|
403
|
+
/**
|
|
404
|
+
*In order to avoid rate limiting issues, we cache the live exchange
|
|
405
|
+
details for each symbol for an account in the database with an option
|
|
406
|
+
to refresh.
|
|
407
|
+
*/
|
|
408
|
+
getLiveExchangeInstance(payload: {
|
|
409
|
+
symbol: string;
|
|
410
|
+
refresh?: boolean;
|
|
411
|
+
price_places?: string;
|
|
412
|
+
decimal_places?: string;
|
|
413
|
+
}): Promise<import("pocketbase").RecordModel>;
|
|
350
414
|
getActiveAccount(symbol: string, full?: boolean): Promise<Account | {
|
|
351
415
|
liquidation: {
|
|
352
416
|
long: number;
|
|
@@ -361,6 +425,7 @@ declare class ExchangeAccount$1 {
|
|
|
361
425
|
kind?: "long" | "short";
|
|
362
426
|
update?: boolean;
|
|
363
427
|
as_view?: boolean;
|
|
428
|
+
leverage?: number;
|
|
364
429
|
}): Promise<(PositionsView & {
|
|
365
430
|
expand?: {
|
|
366
431
|
config: ScheduledTrade;
|
|
@@ -599,6 +664,32 @@ declare class App {
|
|
|
599
664
|
kind: "long" | "short";
|
|
600
665
|
revert?: boolean;
|
|
601
666
|
}): Promise<import("pocketbase").RecordModel[]>;
|
|
667
|
+
updateTopMovers(payload?: {
|
|
668
|
+
new_markets: {
|
|
669
|
+
symbol: string;
|
|
670
|
+
percent: number;
|
|
671
|
+
}[];
|
|
672
|
+
totalRisk: number;
|
|
673
|
+
}): Promise<{
|
|
674
|
+
updated_bullish: BullishMarket[];
|
|
675
|
+
moved_to_winding: WindingDownMarket[];
|
|
676
|
+
}>;
|
|
677
|
+
getWindingDownMarkets(): Promise<WindingDownMarket[]>;
|
|
678
|
+
updateSymbolConfigs(payload: {
|
|
679
|
+
configs: {
|
|
680
|
+
symbol: string;
|
|
681
|
+
support: number;
|
|
682
|
+
leverage: number;
|
|
683
|
+
min_size: number;
|
|
684
|
+
resistance: number;
|
|
685
|
+
price_places: string;
|
|
686
|
+
decimal_places: string;
|
|
687
|
+
}[];
|
|
688
|
+
}): Promise<SymbolConfig[] | {
|
|
689
|
+
updated: number;
|
|
690
|
+
created: number;
|
|
691
|
+
}>;
|
|
692
|
+
updateAllAccountWithSymbols(with_positions?: boolean): Promise<void>;
|
|
602
693
|
}
|
|
603
694
|
export declare function initApp(payload: {
|
|
604
695
|
db: {
|
package/dist/index.js
CHANGED
|
@@ -31646,6 +31646,31 @@ class AppDatabase {
|
|
|
31646
31646
|
constructor(pb) {
|
|
31647
31647
|
this.pb = pb;
|
|
31648
31648
|
}
|
|
31649
|
+
async createOrUpdateLiveExchangeInstance(payload) {
|
|
31650
|
+
const result = await this.getLiveExchangeInstance(payload);
|
|
31651
|
+
if (result) {
|
|
31652
|
+
return await this.pb.collection("live_exchange_details").update(result.id, {
|
|
31653
|
+
data: payload.data
|
|
31654
|
+
});
|
|
31655
|
+
} else {
|
|
31656
|
+
const exchange_account = await this.get_exchange_db_instance(payload.account);
|
|
31657
|
+
return await this.pb.collection("live_exchange_details").create({
|
|
31658
|
+
symbol: payload.symbol,
|
|
31659
|
+
account: exchange_account.id,
|
|
31660
|
+
data: payload.data
|
|
31661
|
+
});
|
|
31662
|
+
}
|
|
31663
|
+
}
|
|
31664
|
+
async getLiveExchangeInstance(payload) {
|
|
31665
|
+
const result = await this.pb.collection("live_exchange_details").getFullList({
|
|
31666
|
+
filter: `account.owner:lower="${payload.account.owner.toLowerCase()}" && account.exchange:lower="${payload.account.exchange.toLowerCase()}" && symbol:lower="${payload.symbol.toLowerCase()}"`,
|
|
31667
|
+
expand: "account"
|
|
31668
|
+
});
|
|
31669
|
+
if (result.length > 0) {
|
|
31670
|
+
return result[0];
|
|
31671
|
+
}
|
|
31672
|
+
return null;
|
|
31673
|
+
}
|
|
31649
31674
|
async getProxyForAccount(account) {
|
|
31650
31675
|
const result = await this.get_exchange_db_instance(account);
|
|
31651
31676
|
if (result?.expand?.proxy) {
|
|
@@ -31660,6 +31685,22 @@ class AppDatabase {
|
|
|
31660
31685
|
}
|
|
31661
31686
|
return null;
|
|
31662
31687
|
}
|
|
31688
|
+
async getAccounts() {
|
|
31689
|
+
return await this.pb.collection("exchange_accounts").getFullList();
|
|
31690
|
+
}
|
|
31691
|
+
async getAllSymbolConfigs(with_positions) {
|
|
31692
|
+
if (with_positions) {
|
|
31693
|
+
const positions = await this.pb.collection("positions").getFullList({
|
|
31694
|
+
fields: `symbol`
|
|
31695
|
+
});
|
|
31696
|
+
const symbol_set = new Set(positions.map((p) => p.symbol));
|
|
31697
|
+
const filter = Array.from(symbol_set).map((s2) => `symbol:lower="${s2.toLowerCase()}"`).join(" || ");
|
|
31698
|
+
return await this.pb.collection("symbol_configs").getFullList({
|
|
31699
|
+
filter
|
|
31700
|
+
});
|
|
31701
|
+
}
|
|
31702
|
+
return await this.pb.collection("symbol_configs").getFullList();
|
|
31703
|
+
}
|
|
31663
31704
|
async get_exchange_db_instance(account) {
|
|
31664
31705
|
const result = await this.pb.collection("exchange_accounts").getFirstListItem(`owner="${account.owner}" && exchange="${account.exchange}"`, {
|
|
31665
31706
|
expand: "proxy"
|
|
@@ -31920,6 +31961,214 @@ class AppDatabase {
|
|
|
31920
31961
|
}
|
|
31921
31962
|
return null;
|
|
31922
31963
|
}
|
|
31964
|
+
async createOrUpdateWindingDownMarket(symbol) {
|
|
31965
|
+
const existing_winding_down_market = await this.pb.collection("winding_down_markets").getFullList({
|
|
31966
|
+
filter: `symbol:lower="${symbol.toLowerCase()}"`
|
|
31967
|
+
});
|
|
31968
|
+
if (existing_winding_down_market.length > 0) {
|
|
31969
|
+
return existing_winding_down_market[0];
|
|
31970
|
+
}
|
|
31971
|
+
return await this.pb.collection("winding_down_markets").create({ symbol });
|
|
31972
|
+
}
|
|
31973
|
+
async getWindingDownMarkets() {
|
|
31974
|
+
return await this.pb.collection("winding_down_markets").getFullList();
|
|
31975
|
+
}
|
|
31976
|
+
async getBullishMarkets(options) {
|
|
31977
|
+
if (!options) {
|
|
31978
|
+
return {
|
|
31979
|
+
updated_bullish: await this.pb.collection("bullish_markets").getFullList(),
|
|
31980
|
+
moved_to_winding: []
|
|
31981
|
+
};
|
|
31982
|
+
}
|
|
31983
|
+
const { new_markets, totalRisk } = options;
|
|
31984
|
+
const newMarketSymbols = new Set(new_markets.map((m) => m.symbol));
|
|
31985
|
+
console.log(`Processing ${new_markets.length} new top movers with total risk ${totalRisk}`);
|
|
31986
|
+
let currentBullish = [];
|
|
31987
|
+
try {
|
|
31988
|
+
currentBullish = await this.pb.collection("bullish_markets").getFullList();
|
|
31989
|
+
console.log(`Found ${currentBullish.length} existing bullish markets.`);
|
|
31990
|
+
} catch (error) {
|
|
31991
|
+
console.error("Error fetching current bullish markets:", error);
|
|
31992
|
+
currentBullish = [];
|
|
31993
|
+
}
|
|
31994
|
+
const currentBullishSymbols = new Set(currentBullish.map((m) => m.symbol));
|
|
31995
|
+
const moved_to_winding = [];
|
|
31996
|
+
const recordsToDeleteFromBullish = [];
|
|
31997
|
+
let windDownCreatedCount = 0;
|
|
31998
|
+
let currentWindingDown = [];
|
|
31999
|
+
let currentWindingDownSymbols = new Set;
|
|
32000
|
+
try {
|
|
32001
|
+
currentWindingDown = await this.getWindingDownMarkets();
|
|
32002
|
+
currentWindingDownSymbols = new Set(currentWindingDown.map((m) => m.symbol));
|
|
32003
|
+
console.log(`Found ${currentWindingDown.length} existing winding down markets.`);
|
|
32004
|
+
} catch (error) {
|
|
32005
|
+
console.error("Error fetching current winding down markets:", error);
|
|
32006
|
+
}
|
|
32007
|
+
console.log("Processing markets to potentially move to winding down...");
|
|
32008
|
+
for (const market of currentBullish) {
|
|
32009
|
+
if (!newMarketSymbols.has(market.symbol)) {
|
|
32010
|
+
console.log(`Processing ${market.symbol} for winding down.`);
|
|
32011
|
+
recordsToDeleteFromBullish.push(market.id);
|
|
32012
|
+
try {
|
|
32013
|
+
const windingDownRecord = await this.createOrUpdateWindingDownMarket(market.symbol);
|
|
32014
|
+
if (windingDownRecord) {
|
|
32015
|
+
moved_to_winding.push(windingDownRecord);
|
|
32016
|
+
windDownCreatedCount++;
|
|
32017
|
+
}
|
|
32018
|
+
} catch (windDownError) {
|
|
32019
|
+
console.error(`Error creating/updating winding down market for ${market.symbol} sequentially:`, windDownError);
|
|
32020
|
+
}
|
|
32021
|
+
}
|
|
32022
|
+
}
|
|
32023
|
+
console.log(`Finished processing potential winding down markets. ${windDownCreatedCount} processed.`);
|
|
32024
|
+
let deletedCount = 0;
|
|
32025
|
+
if (recordsToDeleteFromBullish.length > 0) {
|
|
32026
|
+
console.log(`Attempting to delete ${recordsToDeleteFromBullish.length} records sequentially from bullish_markets.`);
|
|
32027
|
+
for (const id of recordsToDeleteFromBullish) {
|
|
32028
|
+
try {
|
|
32029
|
+
await this.pb.collection("bullish_markets").delete(id);
|
|
32030
|
+
deletedCount++;
|
|
32031
|
+
} catch (deleteError) {
|
|
32032
|
+
console.error(`Error deleting bullish market record ${id} sequentially:`, deleteError);
|
|
32033
|
+
}
|
|
32034
|
+
}
|
|
32035
|
+
console.log(`Finished sequential deletion. Successfully deleted ${deletedCount} of ${recordsToDeleteFromBullish.length} records.`);
|
|
32036
|
+
}
|
|
32037
|
+
let updatedCount = 0;
|
|
32038
|
+
let createdMarkets = [];
|
|
32039
|
+
const recordsToDeleteFromWindingDown = [];
|
|
32040
|
+
if (totalRisk <= 0) {
|
|
32041
|
+
console.warn("Total percent movement is zero or negative. Cannot allocate risk.");
|
|
32042
|
+
} else {
|
|
32043
|
+
for (const newMarket of new_markets) {
|
|
32044
|
+
const calculatedRisk = newMarket.percent / totalRisk * totalRisk;
|
|
32045
|
+
if (currentWindingDownSymbols.has(newMarket.symbol)) {
|
|
32046
|
+
console.log(`Marking ${newMarket.symbol} for removal from winding down markets as it is now bullish.`);
|
|
32047
|
+
const windingDownRecord = currentWindingDown.find((w) => w.symbol === newMarket.symbol);
|
|
32048
|
+
if (windingDownRecord) {
|
|
32049
|
+
recordsToDeleteFromWindingDown.push(windingDownRecord.id);
|
|
32050
|
+
currentWindingDownSymbols.delete(newMarket.symbol);
|
|
32051
|
+
}
|
|
32052
|
+
}
|
|
32053
|
+
const existingMarket = currentBullish.find((m) => m.symbol === newMarket.symbol);
|
|
32054
|
+
if (existingMarket && !recordsToDeleteFromBullish.includes(existingMarket.id)) {
|
|
32055
|
+
if (existingMarket.risk !== calculatedRisk) {
|
|
32056
|
+
console.log(`Updating existing bullish market sequentially: ${newMarket.symbol} with risk ${calculatedRisk}`);
|
|
32057
|
+
try {
|
|
32058
|
+
await this.pb.collection("bullish_markets").update(existingMarket.id, {
|
|
32059
|
+
risk: calculatedRisk
|
|
32060
|
+
});
|
|
32061
|
+
updatedCount++;
|
|
32062
|
+
} catch (updateError) {
|
|
32063
|
+
console.error(`Error updating bullish market ${newMarket.symbol} sequentially:`, updateError);
|
|
32064
|
+
}
|
|
32065
|
+
}
|
|
32066
|
+
} else if (!currentBullishSymbols.has(newMarket.symbol)) {
|
|
32067
|
+
console.log(`Creating new bullish market sequentially: ${newMarket.symbol} with risk ${calculatedRisk}`);
|
|
32068
|
+
try {
|
|
32069
|
+
const createdMarket = await this.pb.collection("bullish_markets").create({
|
|
32070
|
+
symbol: newMarket.symbol,
|
|
32071
|
+
risk: calculatedRisk
|
|
32072
|
+
});
|
|
32073
|
+
createdMarkets.push(createdMarket);
|
|
32074
|
+
} catch (createError) {
|
|
32075
|
+
console.error(`Error creating bullish market ${newMarket.symbol} sequentially:`, createError);
|
|
32076
|
+
}
|
|
32077
|
+
}
|
|
32078
|
+
}
|
|
32079
|
+
}
|
|
32080
|
+
let windingDownDeletedCount = 0;
|
|
32081
|
+
if (recordsToDeleteFromWindingDown.length > 0) {
|
|
32082
|
+
console.log(`Attempting to delete ${recordsToDeleteFromWindingDown.length} records sequentially from winding_down_markets.`);
|
|
32083
|
+
for (const id of recordsToDeleteFromWindingDown) {
|
|
32084
|
+
try {
|
|
32085
|
+
await this.pb.collection("winding_down_markets").delete(id);
|
|
32086
|
+
windingDownDeletedCount++;
|
|
32087
|
+
} catch (deleteError) {
|
|
32088
|
+
console.error(`Error deleting winding down market record ${id} sequentially:`, deleteError);
|
|
32089
|
+
}
|
|
32090
|
+
}
|
|
32091
|
+
console.log(`Finished sequential deletion from winding down. Successfully deleted ${windingDownDeletedCount} of ${recordsToDeleteFromWindingDown.length} records.`);
|
|
32092
|
+
}
|
|
32093
|
+
console.log(`Successfully updated ${updatedCount} bullish markets sequentially.`);
|
|
32094
|
+
console.log(`Successfully created ${createdMarkets.length} bullish markets sequentially.`);
|
|
32095
|
+
const updated_bullish = await this.pb.collection("bullish_markets").getFullList();
|
|
32096
|
+
return { updated_bullish, moved_to_winding };
|
|
32097
|
+
}
|
|
32098
|
+
async updateSymbolConfigs(payload) {
|
|
32099
|
+
if (!payload || !payload.configs) {
|
|
32100
|
+
console.log("No payload provided. Fetching all symbol configs...");
|
|
32101
|
+
try {
|
|
32102
|
+
const allConfigs = await this.pb.collection("symbol_configs").getFullList();
|
|
32103
|
+
console.log(`Found ${allConfigs.length} symbol configs.`);
|
|
32104
|
+
return allConfigs;
|
|
32105
|
+
} catch (error) {
|
|
32106
|
+
console.error("Error fetching all symbol configs:", error);
|
|
32107
|
+
throw error;
|
|
32108
|
+
}
|
|
32109
|
+
}
|
|
32110
|
+
console.log(`Processing ${payload.configs.length} symbol config updates/creates...`);
|
|
32111
|
+
let existingConfigsMap = new Map;
|
|
32112
|
+
try {
|
|
32113
|
+
const existingConfigsList = await this.pb.collection("symbol_configs").getFullList();
|
|
32114
|
+
existingConfigsMap = new Map(existingConfigsList.map((c) => [c.symbol.toLowerCase(), c]));
|
|
32115
|
+
console.log(`Found ${existingConfigsMap.size} existing symbol configs in DB.`);
|
|
32116
|
+
} catch (error) {
|
|
32117
|
+
console.error("Error fetching existing symbol configs:", error);
|
|
32118
|
+
}
|
|
32119
|
+
let updatedCount = 0;
|
|
32120
|
+
let createdCount = 0;
|
|
32121
|
+
for (const config of payload.configs) {
|
|
32122
|
+
const lowerCaseSymbol = config.symbol.toLowerCase();
|
|
32123
|
+
const existingConfig = existingConfigsMap.get(lowerCaseSymbol);
|
|
32124
|
+
const dataToUpsert = {
|
|
32125
|
+
symbol: config.symbol,
|
|
32126
|
+
support: config.support,
|
|
32127
|
+
resistance: config.resistance,
|
|
32128
|
+
leverage: config.leverage,
|
|
32129
|
+
min_size: config.min_size,
|
|
32130
|
+
price_places: config.price_places,
|
|
32131
|
+
decimal_places: config.decimal_places
|
|
32132
|
+
};
|
|
32133
|
+
if (existingConfig) {
|
|
32134
|
+
try {
|
|
32135
|
+
if (Object.keys(dataToUpsert).some((key) => dataToUpsert[key] !== existingConfig[key])) {
|
|
32136
|
+
console.log(`Updating symbol config for: ${config.symbol}`);
|
|
32137
|
+
await this.pb.collection("symbol_configs").update(existingConfig.id, dataToUpsert);
|
|
32138
|
+
updatedCount++;
|
|
32139
|
+
} else {
|
|
32140
|
+
console.log(`No changes detected for symbol config: ${config.symbol}. Skipping update.`);
|
|
32141
|
+
}
|
|
32142
|
+
} catch (updateError) {
|
|
32143
|
+
console.error(`Error updating symbol config for ${config.symbol}:`, updateError);
|
|
32144
|
+
}
|
|
32145
|
+
} else {
|
|
32146
|
+
try {
|
|
32147
|
+
console.log(`Creating new symbol config for: ${config.symbol}`);
|
|
32148
|
+
await this.pb.collection("symbol_configs").create(dataToUpsert);
|
|
32149
|
+
createdCount++;
|
|
32150
|
+
} catch (createError) {
|
|
32151
|
+
console.error(`Error creating symbol config for ${config.symbol}:`, createError);
|
|
32152
|
+
}
|
|
32153
|
+
}
|
|
32154
|
+
}
|
|
32155
|
+
console.log(`Finished processing symbol configs. Updated: ${updatedCount}, Created: ${createdCount}`);
|
|
32156
|
+
return { updated: updatedCount, created: createdCount };
|
|
32157
|
+
}
|
|
32158
|
+
async unwindSymbolFromDB(symbol) {
|
|
32159
|
+
const symbol_configs = await this.pb.collection("symbol_configs").getFullList({
|
|
32160
|
+
filter: `symbol:lower="${symbol.toLowerCase()}"`
|
|
32161
|
+
});
|
|
32162
|
+
if (symbol_configs.length > 0) {
|
|
32163
|
+
await this.pb.collection("symbol_configs").delete(symbol_configs[0].id);
|
|
32164
|
+
}
|
|
32165
|
+
const found_unwinding_market = await this.pb.collection("unwinding_markets").getFullList({
|
|
32166
|
+
filter: `symbol:lower="${symbol.toLowerCase()}"`
|
|
32167
|
+
});
|
|
32168
|
+
if (found_unwinding_market.length > 0) {
|
|
32169
|
+
await this.pb.collection("unwinding_markets").delete(found_unwinding_market[0].id);
|
|
32170
|
+
}
|
|
32171
|
+
}
|
|
31923
32172
|
}
|
|
31924
32173
|
|
|
31925
32174
|
// src/exchanges/binance.ts
|
|
@@ -33490,6 +33739,9 @@ class BinanceExchange {
|
|
|
33490
33739
|
decimal_places: payload.decimal_places
|
|
33491
33740
|
});
|
|
33492
33741
|
}
|
|
33742
|
+
async setLeverage(payload) {
|
|
33743
|
+
return await this.client.setLeverage(payload);
|
|
33744
|
+
}
|
|
33493
33745
|
}
|
|
33494
33746
|
|
|
33495
33747
|
// src/exchanges/bybit.ts
|
|
@@ -34094,6 +34346,14 @@ class BybitExchange {
|
|
|
34094
34346
|
decimal_places: payload.decimal_places
|
|
34095
34347
|
});
|
|
34096
34348
|
}
|
|
34349
|
+
async setLeverage(payload) {
|
|
34350
|
+
return await this.client.setLeverage({
|
|
34351
|
+
category: "linear",
|
|
34352
|
+
symbol: payload.symbol,
|
|
34353
|
+
buyLeverage: payload.leverage.toString(),
|
|
34354
|
+
sellLeverage: payload.leverage.toString()
|
|
34355
|
+
});
|
|
34356
|
+
}
|
|
34097
34357
|
}
|
|
34098
34358
|
|
|
34099
34359
|
// src/helpers/accounts.ts
|
|
@@ -34753,9 +35013,33 @@ class ExchangeAccount {
|
|
|
34753
35013
|
this.exchange = options.exchange;
|
|
34754
35014
|
this.app_db = options.app_db;
|
|
34755
35015
|
}
|
|
35016
|
+
async getLiveExchangeInstance(payload) {
|
|
35017
|
+
const result = await this.app_db.getLiveExchangeInstance({
|
|
35018
|
+
account: this.instance,
|
|
35019
|
+
symbol: payload.symbol
|
|
35020
|
+
});
|
|
35021
|
+
if (payload.refresh || !result) {
|
|
35022
|
+
const data = await this.exchange.getExchangeAccountInfo(this.instance, payload.symbol);
|
|
35023
|
+
if (payload.price_places) {
|
|
35024
|
+
data.config.price_places = payload.price_places;
|
|
35025
|
+
}
|
|
35026
|
+
if (payload.decimal_places) {
|
|
35027
|
+
data.config.decimal_places = payload.decimal_places;
|
|
35028
|
+
}
|
|
35029
|
+
return await this.app_db.createOrUpdateLiveExchangeInstance({
|
|
35030
|
+
account: this.instance,
|
|
35031
|
+
symbol: payload.symbol,
|
|
35032
|
+
data
|
|
35033
|
+
});
|
|
35034
|
+
}
|
|
35035
|
+
return result;
|
|
35036
|
+
}
|
|
34756
35037
|
async getActiveAccount(symbol, full) {
|
|
34757
35038
|
const symbol_config = await this.app_db.getSymbolConfigFromDB(symbol);
|
|
34758
|
-
const
|
|
35039
|
+
const live_exchange_instance = await this.getLiveExchangeInstance({
|
|
35040
|
+
symbol
|
|
35041
|
+
});
|
|
35042
|
+
const raw_active_account = live_exchange_instance.data;
|
|
34759
35043
|
const _all = get_active_accounts({
|
|
34760
35044
|
active_account: raw_active_account,
|
|
34761
35045
|
symbol_config
|
|
@@ -34779,6 +35063,9 @@ class ExchangeAccount {
|
|
|
34779
35063
|
return db_positions2;
|
|
34780
35064
|
}
|
|
34781
35065
|
const active_account = await this.getActiveAccount(symbol);
|
|
35066
|
+
if (options.leverage) {
|
|
35067
|
+
await this.exchange.setLeverage({ symbol, leverage: options.leverage });
|
|
35068
|
+
}
|
|
34782
35069
|
const db_positions = await this.app_db.createOrUpdatePositions(this.instance, {
|
|
34783
35070
|
symbol,
|
|
34784
35071
|
long_position: active_account.position.long,
|
|
@@ -35426,6 +35713,34 @@ class App {
|
|
|
35426
35713
|
});
|
|
35427
35714
|
}
|
|
35428
35715
|
}
|
|
35716
|
+
async updateTopMovers(payload) {
|
|
35717
|
+
return await this.app_db.getBullishMarkets(payload);
|
|
35718
|
+
}
|
|
35719
|
+
async getWindingDownMarkets() {
|
|
35720
|
+
return await this.app_db.getWindingDownMarkets();
|
|
35721
|
+
}
|
|
35722
|
+
async updateSymbolConfigs(payload) {
|
|
35723
|
+
return await this.app_db.updateSymbolConfigs(payload);
|
|
35724
|
+
}
|
|
35725
|
+
async updateAllAccountWithSymbols(with_positions) {
|
|
35726
|
+
const [accounts, symbol_configs] = await Promise.all([
|
|
35727
|
+
this.app_db.getAccounts(),
|
|
35728
|
+
this.app_db.getAllSymbolConfigs(with_positions)
|
|
35729
|
+
]);
|
|
35730
|
+
for (const account of accounts) {
|
|
35731
|
+
for (const symbol_config of symbol_configs) {
|
|
35732
|
+
const exchange_account = await this.getExchangeAccount(account);
|
|
35733
|
+
await exchange_account.getLiveExchangeInstance({
|
|
35734
|
+
symbol: symbol_config.symbol,
|
|
35735
|
+
price_places: symbol_config.price_places,
|
|
35736
|
+
decimal_places: symbol_config.decimal_places,
|
|
35737
|
+
refresh: true
|
|
35738
|
+
});
|
|
35739
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
35740
|
+
}
|
|
35741
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
35742
|
+
}
|
|
35743
|
+
}
|
|
35429
35744
|
}
|
|
35430
35745
|
async function initApp(payload) {
|
|
35431
35746
|
const pb = await initPocketBaseClient(payload.db);
|