@strkfarm/sdk 2.0.0-dev.6 → 2.0.0-dev.8
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.browser.global.js +438 -111
- package/dist/index.browser.mjs +438 -111
- package/dist/index.d.ts +7 -1
- package/dist/index.js +438 -111
- package/dist/index.mjs +438 -111
- package/package.json +1 -1
- package/src/strategies/universal-adapters/avnu-adapter.ts +2 -3
- package/src/strategies/universal-adapters/extended-adapter.ts +221 -61
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +3 -1
- package/src/strategies/universal-lst-muliplier-strategy.tsx +2 -1
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +1 -1
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +297 -58
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
WithdrawParams,
|
|
5
5
|
BaseAdapterConfig,
|
|
6
6
|
} from "./baseAdapter";
|
|
7
|
-
import {
|
|
7
|
+
import { toBigInt } from "./adapter-utils";
|
|
8
8
|
import { Protocols } from "@/interfaces";
|
|
9
9
|
import { MAX_DELAY } from "../vesu-extended-strategy/utils/constants";
|
|
10
10
|
import { SupportedPosition } from "./baseAdapter";
|
|
@@ -13,14 +13,13 @@ import { Web3Number } from "@/dataTypes";
|
|
|
13
13
|
import { PositionInfo } from "./baseAdapter";
|
|
14
14
|
import { ManageCall } from "./baseAdapter";
|
|
15
15
|
import { ContractAddr } from "@/dataTypes";
|
|
16
|
-
import { TokenInfo } from "@/interfaces";
|
|
17
16
|
import { AVNU_EXCHANGE } from "./adapter-utils";
|
|
18
17
|
import { MAX_RETRIES } from "../vesu-extended-strategy/utils/constants";
|
|
19
18
|
import { Quote } from "@avnu/avnu-sdk";
|
|
20
19
|
import { hash, uint256 } from "starknet";
|
|
21
20
|
import { AvnuWrapper } from "@/modules/avnu";
|
|
22
21
|
import axios from "axios";
|
|
23
|
-
import {
|
|
22
|
+
import {SIMPLE_SANITIZER } from "./adapter-utils";
|
|
24
23
|
import { returnFormattedAmount } from "../vesu-extended-strategy/utils/helper";
|
|
25
24
|
import { logger } from "@/utils";
|
|
26
25
|
export interface AvnuAdapterConfig extends BaseAdapterConfig {
|
|
@@ -45,6 +45,8 @@ export interface ExtendedAdapterConfig extends BaseAdapterConfig {
|
|
|
45
45
|
extendedMarketName: string;
|
|
46
46
|
extendedPrecision: number;
|
|
47
47
|
avnuAdapter: AvnuAdapter;
|
|
48
|
+
retryDelayForOrderStatus: number;
|
|
49
|
+
minimumExtendedMovementAmount: number;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
export class ExtendedAdapter extends BaseAdapter<
|
|
@@ -53,6 +55,8 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
53
55
|
> {
|
|
54
56
|
readonly config: ExtendedAdapterConfig;
|
|
55
57
|
readonly client: ExtendedWrapper;
|
|
58
|
+
readonly retryDelayForOrderStatus: number;
|
|
59
|
+
readonly minimumExtendedMovementAmount: number;
|
|
56
60
|
|
|
57
61
|
constructor(config: ExtendedAdapterConfig) {
|
|
58
62
|
super(config, ExtendedAdapter.name, Protocols.EXTENDED);
|
|
@@ -63,7 +67,11 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
63
67
|
timeout: this.config.extendedTimeout,
|
|
64
68
|
retries: this.config.extendedRetries,
|
|
65
69
|
});
|
|
70
|
+
this.minimumExtendedMovementAmount =
|
|
71
|
+
this.config.minimumExtendedMovementAmount ?? 5; //5 usdc
|
|
66
72
|
this.client = client;
|
|
73
|
+
this.retryDelayForOrderStatus =
|
|
74
|
+
this.config.retryDelayForOrderStatus ?? 3000;
|
|
67
75
|
}
|
|
68
76
|
//abstract means the method has no implementation in this class; instead, child classes must implement it.
|
|
69
77
|
protected async getAPY(
|
|
@@ -410,11 +418,58 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
410
418
|
async withdrawFromExtended(amount: Web3Number): Promise<boolean> {
|
|
411
419
|
try {
|
|
412
420
|
if (!this.client) {
|
|
413
|
-
|
|
421
|
+
logger.error("Client not initialized");
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
if (amount.lessThanOrEqualTo(0)) {
|
|
425
|
+
logger.error(
|
|
426
|
+
`Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
|
|
427
|
+
);
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
|
|
431
|
+
logger.warn(
|
|
432
|
+
`Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
|
|
433
|
+
);
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
const holdings = await this.getExtendedDepositAmount();
|
|
437
|
+
if (!holdings) {
|
|
438
|
+
logger.error(
|
|
439
|
+
"Cannot get holdings - unable to validate withdrawal amount"
|
|
440
|
+
);
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const availableForWithdrawal = parseFloat(
|
|
445
|
+
holdings.availableForWithdrawal
|
|
446
|
+
);
|
|
447
|
+
if (
|
|
448
|
+
!Number.isFinite(availableForWithdrawal) ||
|
|
449
|
+
availableForWithdrawal < 0
|
|
450
|
+
) {
|
|
451
|
+
logger.error(
|
|
452
|
+
`Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
|
|
453
|
+
);
|
|
454
|
+
return false;
|
|
414
455
|
}
|
|
456
|
+
|
|
457
|
+
const withdrawalAmount = amount.toNumber();
|
|
458
|
+
if (withdrawalAmount > availableForWithdrawal) {
|
|
459
|
+
logger.error(
|
|
460
|
+
`Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
|
|
461
|
+
);
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
logger.info(
|
|
466
|
+
`Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
|
|
467
|
+
);
|
|
468
|
+
|
|
415
469
|
const withdrawalRequest = await this.client.withdrawUSDC(
|
|
416
470
|
amount.toFixed(2)
|
|
417
471
|
);
|
|
472
|
+
|
|
418
473
|
if (withdrawalRequest.status === "OK") {
|
|
419
474
|
const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
|
|
420
475
|
withdrawalRequest.data,
|
|
@@ -422,6 +477,10 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
422
477
|
);
|
|
423
478
|
return withdrawalStatus;
|
|
424
479
|
}
|
|
480
|
+
|
|
481
|
+
logger.error(
|
|
482
|
+
`Withdrawal request failed with status: ${withdrawalRequest.status}`
|
|
483
|
+
);
|
|
425
484
|
return false;
|
|
426
485
|
} catch (error) {
|
|
427
486
|
logger.error(`Error creating Withdraw Call: ${error}`);
|
|
@@ -434,21 +493,47 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
434
493
|
}
|
|
435
494
|
|
|
436
495
|
async getExtendedDepositAmount(): Promise<Balance | undefined> {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
496
|
+
try {
|
|
497
|
+
if (this.client === null) {
|
|
498
|
+
logger.error("error initializing client - client is null");
|
|
499
|
+
return undefined; // Error: client not initialized
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const result = await this.client.getHoldings();
|
|
503
|
+
if (!result) {
|
|
504
|
+
logger.error("error getting holdings - API returned null/undefined");
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (result.status && result.status !== "OK") {
|
|
509
|
+
logger.error(
|
|
510
|
+
`error getting holdings - API returned status: ${result.status}`
|
|
511
|
+
);
|
|
512
|
+
return undefined;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const holdings = result.data;
|
|
516
|
+
if (!holdings) {
|
|
517
|
+
logger.warn(
|
|
518
|
+
"holdings data is null/undefined - treating as zero balance"
|
|
519
|
+
);
|
|
520
|
+
return {
|
|
521
|
+
collateral_name: "",
|
|
522
|
+
balance: "0",
|
|
523
|
+
equity: "0",
|
|
524
|
+
availableForTrade: "0",
|
|
525
|
+
availableForWithdrawal: "0",
|
|
526
|
+
unrealisedPnl: "0",
|
|
527
|
+
initialMargin: "0",
|
|
528
|
+
marginRatio: "0",
|
|
529
|
+
updatedTime: Date.now(),
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
return holdings;
|
|
533
|
+
} catch (error) {
|
|
534
|
+
logger.error(`error getting holdings - exception: ${error}`);
|
|
449
535
|
return undefined;
|
|
450
536
|
}
|
|
451
|
-
return holdings;
|
|
452
537
|
}
|
|
453
538
|
|
|
454
539
|
async setLeverage(leverage: string, marketName: string): Promise<boolean> {
|
|
@@ -497,50 +582,29 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
497
582
|
orderId: string,
|
|
498
583
|
marketName: string
|
|
499
584
|
): Promise<OpenOrder | null> {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
let orderhistory = await this.getOrderHistory(marketName);
|
|
505
|
-
|
|
506
|
-
if (!orderhistory || orderhistory.length === 0) {
|
|
507
|
-
logger.error(`error getting order history: ${orderId}`);
|
|
508
|
-
} else {
|
|
509
|
-
const order = orderhistory
|
|
510
|
-
.slice(0, 5)
|
|
511
|
-
.find((order) => order.id.toString() === orderId);
|
|
512
|
-
if (order) {
|
|
513
|
-
return order;
|
|
585
|
+
try {
|
|
586
|
+
if (this.client === null) {
|
|
587
|
+
logger.error("error initializing client");
|
|
588
|
+
return null;
|
|
514
589
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
// Retry logic: 3 more attempts with 3 second delay each
|
|
518
|
-
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
519
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
520
|
-
orderhistory = await this.getOrderHistory(marketName);
|
|
590
|
+
const orderhistory = await this.getOrderHistory(marketName);
|
|
521
591
|
|
|
522
592
|
if (!orderhistory || orderhistory.length === 0) {
|
|
523
|
-
|
|
524
|
-
`error getting order history on retry ${attempt}: ${orderId}`
|
|
525
|
-
);
|
|
526
|
-
continue;
|
|
593
|
+
return null;
|
|
527
594
|
}
|
|
528
|
-
|
|
529
595
|
const order = orderhistory
|
|
530
|
-
.slice(0,
|
|
596
|
+
.slice(0, 20)
|
|
531
597
|
.find((order) => order.id.toString() === orderId);
|
|
532
598
|
|
|
533
599
|
if (order) {
|
|
534
600
|
return order;
|
|
535
601
|
}
|
|
536
602
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
);
|
|
603
|
+
return null; // Order not found
|
|
604
|
+
} catch (error) {
|
|
605
|
+
logger.error(`error getting order status: ${error}`);
|
|
606
|
+
return null;
|
|
540
607
|
}
|
|
541
|
-
|
|
542
|
-
logger.error(`error getting order after all retries: ${orderId}`);
|
|
543
|
-
return null;
|
|
544
608
|
}
|
|
545
609
|
|
|
546
610
|
async fetchOrderBookBTCUSDC(): Promise<{
|
|
@@ -602,16 +666,60 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
602
666
|
logger.error("error depositing or setting leverage");
|
|
603
667
|
return null;
|
|
604
668
|
}
|
|
605
|
-
const
|
|
606
|
-
if (
|
|
669
|
+
const { ask, bid } = await this.fetchOrderBookBTCUSDC();
|
|
670
|
+
if (
|
|
671
|
+
!ask ||
|
|
672
|
+
!bid ||
|
|
673
|
+
ask.lessThanOrEqualTo(0) ||
|
|
674
|
+
bid.lessThanOrEqualTo(0)
|
|
675
|
+
) {
|
|
676
|
+
logger.error(
|
|
677
|
+
`Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
|
|
678
|
+
);
|
|
607
679
|
return null;
|
|
608
680
|
}
|
|
609
|
-
|
|
681
|
+
|
|
610
682
|
const spread = ask.minus(bid);
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
683
|
+
const midPrice = ask.plus(bid).div(2);
|
|
684
|
+
/** Maximum deviation: 50% of spread (to prevent extremely unfavorable prices) */
|
|
685
|
+
const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
|
|
686
|
+
const priceAdjustmentMultiplier = Math.min(
|
|
687
|
+
0.2 * attempt,
|
|
688
|
+
MAX_PRICE_DEVIATION_MULTIPLIER
|
|
689
|
+
);
|
|
690
|
+
const priceAdjustment = spread.times(priceAdjustmentMultiplier);
|
|
691
|
+
|
|
692
|
+
let price = midPrice;
|
|
693
|
+
if (side === OrderSide.SELL) {
|
|
694
|
+
price = midPrice.minus(priceAdjustment);
|
|
695
|
+
} else {
|
|
696
|
+
price = midPrice.plus(priceAdjustment);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/** Validate price is still reasonable (within 50% of mid price) */
|
|
700
|
+
const maxDeviation = midPrice.times(0.5);
|
|
701
|
+
if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
|
|
702
|
+
logger.error(
|
|
703
|
+
`Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price
|
|
704
|
+
.minus(midPrice)
|
|
705
|
+
.abs()
|
|
706
|
+
.toNumber()}`
|
|
707
|
+
);
|
|
708
|
+
if (attempt >= maxAttempts) {
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
price =
|
|
712
|
+
side === OrderSide.SELL
|
|
713
|
+
? midPrice.minus(maxDeviation)
|
|
714
|
+
: midPrice.plus(maxDeviation);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
logger.info(
|
|
718
|
+
`createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${
|
|
719
|
+
priceAdjustmentMultiplier * 100
|
|
720
|
+
}%`
|
|
721
|
+
);
|
|
722
|
+
|
|
615
723
|
const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
|
|
616
724
|
this.config.extendedPrecision
|
|
617
725
|
); // gives the amount of wbtc
|
|
@@ -623,17 +731,66 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
623
731
|
price.toFixed(0),
|
|
624
732
|
side
|
|
625
733
|
);
|
|
626
|
-
if (!result) {
|
|
734
|
+
if (!result || !result.position_id) {
|
|
735
|
+
logger.error("Failed to create order - no position_id returned");
|
|
627
736
|
return null;
|
|
628
737
|
}
|
|
629
|
-
|
|
630
|
-
const
|
|
631
|
-
|
|
738
|
+
|
|
739
|
+
const positionId = result.position_id;
|
|
740
|
+
logger.info(
|
|
741
|
+
`Order created with position_id: ${positionId}. Waiting for API to update...`
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
let openOrder = await this.getOrderStatus(
|
|
745
|
+
positionId,
|
|
632
746
|
this.config.extendedMarketName
|
|
633
747
|
);
|
|
634
|
-
|
|
748
|
+
const maxStatusRetries = 3;
|
|
749
|
+
const statusRetryDelay = 5000;
|
|
750
|
+
|
|
751
|
+
if (!openOrder) {
|
|
752
|
+
logger.warn(
|
|
753
|
+
`Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
|
|
754
|
+
);
|
|
755
|
+
for (
|
|
756
|
+
let statusRetry = 1;
|
|
757
|
+
statusRetry <= maxStatusRetries;
|
|
758
|
+
statusRetry++
|
|
759
|
+
) {
|
|
760
|
+
await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
|
|
761
|
+
openOrder = await this.getOrderStatus(
|
|
762
|
+
positionId,
|
|
763
|
+
this.config.extendedMarketName
|
|
764
|
+
);
|
|
765
|
+
if (openOrder) {
|
|
766
|
+
logger.info(
|
|
767
|
+
`Order ${positionId} found after ${statusRetry} status retry(ies)`
|
|
768
|
+
);
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
logger.warn(
|
|
772
|
+
`Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (openOrder && openOrder.status === OrderStatus.FILLED) {
|
|
778
|
+
logger.info(
|
|
779
|
+
`Order ${positionId} successfully filled with quantity ${openOrder.qty}`
|
|
780
|
+
);
|
|
781
|
+
return {
|
|
782
|
+
position_id: positionId,
|
|
783
|
+
btc_exposure: openOrder.qty,
|
|
784
|
+
};
|
|
785
|
+
} else if (openOrder && openOrder.status !== OrderStatus.FILLED) {
|
|
786
|
+
// Order found but NOT FILLED - retry (recreate)
|
|
787
|
+
logger.warn(
|
|
788
|
+
`Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
|
|
789
|
+
);
|
|
635
790
|
if (attempt >= maxAttempts) {
|
|
636
|
-
logger.error(
|
|
791
|
+
logger.error(
|
|
792
|
+
`Max retries reached — order ${positionId} status is ${openOrder.status}, not FILLED`
|
|
793
|
+
);
|
|
637
794
|
return null;
|
|
638
795
|
} else {
|
|
639
796
|
const backoff = 2000 * attempt;
|
|
@@ -647,9 +804,12 @@ export class ExtendedAdapter extends BaseAdapter<
|
|
|
647
804
|
);
|
|
648
805
|
}
|
|
649
806
|
} else {
|
|
807
|
+
logger.warn(
|
|
808
|
+
`Order ${positionId} not found in API after ${maxStatusRetries} status retries (API update delayed ~30s). We got position_id from creation, so order exists. Returning position_id - status will be checked in next loop iteration.`
|
|
809
|
+
);
|
|
650
810
|
return {
|
|
651
|
-
position_id:
|
|
652
|
-
btc_exposure:
|
|
811
|
+
position_id: positionId,
|
|
812
|
+
btc_exposure: amount_in_token,
|
|
653
813
|
};
|
|
654
814
|
}
|
|
655
815
|
} catch (err: any) {
|
|
@@ -50,6 +50,7 @@ export interface VesuMultiplyAdapterConfig extends BaseAdapterConfig {
|
|
|
50
50
|
targetHealthFactor: number;
|
|
51
51
|
minHealthFactor: number;
|
|
52
52
|
quoteAmountToFetchPrice: Web3Number;
|
|
53
|
+
minimumVesuMovementAmount: number;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export class VesuMultiplyAdapter extends BaseAdapter<
|
|
@@ -59,7 +60,7 @@ export class VesuMultiplyAdapter extends BaseAdapter<
|
|
|
59
60
|
readonly config: VesuMultiplyAdapterConfig;
|
|
60
61
|
readonly vesuAdapter: VesuAdapter;
|
|
61
62
|
readonly tokenMarketData: TokenMarketData;
|
|
62
|
-
|
|
63
|
+
readonly minimumVesuMovementAmount: number;
|
|
63
64
|
constructor(config: VesuMultiplyAdapterConfig) {
|
|
64
65
|
super(config, VesuMultiplyAdapter.name, Protocols.VESU);
|
|
65
66
|
this.config = config;
|
|
@@ -70,6 +71,7 @@ export class VesuMultiplyAdapter extends BaseAdapter<
|
|
|
70
71
|
vaultAllocator: config.vaultAllocator,
|
|
71
72
|
id: "",
|
|
72
73
|
});
|
|
74
|
+
this.minimumVesuMovementAmount = config.minimumVesuMovementAmount ?? 5; //5 usdc
|
|
73
75
|
this.tokenMarketData = new TokenMarketData(
|
|
74
76
|
this.config.pricer,
|
|
75
77
|
this.config.networkConfig
|
|
@@ -786,7 +786,8 @@ function getLooperSettings(
|
|
|
786
786
|
minHealthFactor: vaultSettings.minHealthFactor,
|
|
787
787
|
quoteAmountToFetchPrice: vaultSettings.quoteAmountToFetchPrice,
|
|
788
788
|
...baseAdapterConfig,
|
|
789
|
-
supportedPositions: [{asset: lstToken, isDebt: false}, {asset: Global.getDefaultTokens().find(token => token.symbol === position)!, isDebt: true}]
|
|
789
|
+
supportedPositions: [{asset: lstToken, isDebt: false}, {asset: Global.getDefaultTokens().find(token => token.symbol === position)!, isDebt: true}],
|
|
790
|
+
minimumVesuMovementAmount: 0
|
|
790
791
|
}));
|
|
791
792
|
|
|
792
793
|
const unusedBalanceAdapter = new UnusedBalanceAdapter({
|
|
@@ -22,7 +22,7 @@ export const STRK_API_RPC = process.env.STRK_API_RPC ?? "https://mainnet.starkne
|
|
|
22
22
|
export const MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
|
|
23
23
|
export const MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
|
|
24
24
|
export const EXTEND_MARKET_NAME = "BTC-USD";
|
|
25
|
-
export const LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ??
|
|
25
|
+
export const LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 0.05);
|
|
26
26
|
export const REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 180000); //3 mins
|
|
27
27
|
export const WITHDRAWAL_INTERVAL = Number(process.env.WITHDRAWAL_INTERVAL ?? 18000000); //5 hours
|
|
28
28
|
export const INVESTING_INTERVAL = Number(process.env.INVESTING_INTERVAL ?? 180000); //3 mins
|