@gbozee/ultimate 0.0.2-93 → 0.0.2-95
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/frontend-index.d.ts +32 -0
- package/dist/frontend-index.js +38 -0
- package/dist/index.cjs +174 -8
- package/dist/index.d.ts +122 -24
- package/dist/index.js +174 -8
- package/dist/mcp-server.cjs +173 -8
- package/dist/mcp-server.js +173 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51558,7 +51558,7 @@ class AppDatabase {
|
|
|
51558
51558
|
table: "positions_view",
|
|
51559
51559
|
params: {
|
|
51560
51560
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
51561
|
-
expand: "config"
|
|
51561
|
+
expand: "config, account_strategy, p_account"
|
|
51562
51562
|
}
|
|
51563
51563
|
} : {
|
|
51564
51564
|
table: "positions",
|
|
@@ -53795,6 +53795,43 @@ function getRiskReward(payload) {
|
|
|
53795
53795
|
});
|
|
53796
53796
|
return risk_reward;
|
|
53797
53797
|
}
|
|
53798
|
+
function computeProfitDetail(payload) {
|
|
53799
|
+
const {
|
|
53800
|
+
focus_position,
|
|
53801
|
+
strategy,
|
|
53802
|
+
price_places = "%.1f",
|
|
53803
|
+
reduce_position,
|
|
53804
|
+
decimal_places
|
|
53805
|
+
} = payload;
|
|
53806
|
+
let reward_factor = strategy.reward_factor;
|
|
53807
|
+
let risk = strategy.risk;
|
|
53808
|
+
if (strategy.max_reward_factor === 0) {
|
|
53809
|
+
reward_factor = strategy.reward_factor;
|
|
53810
|
+
}
|
|
53811
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
53812
|
+
reward_factor = focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty;
|
|
53813
|
+
} else {
|
|
53814
|
+
reward_factor = strategy.reward_factor;
|
|
53815
|
+
}
|
|
53816
|
+
const full_pnl = reward_factor * risk;
|
|
53817
|
+
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
53818
|
+
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
53819
|
+
const diff = pnl / focus_position.quantity;
|
|
53820
|
+
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
53821
|
+
const loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
53822
|
+
const ratio = pnl / loss;
|
|
53823
|
+
const quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
53824
|
+
return {
|
|
53825
|
+
pnl,
|
|
53826
|
+
reward_factor,
|
|
53827
|
+
profit_percent,
|
|
53828
|
+
kind: focus_position.kind,
|
|
53829
|
+
sell_price: to_f2(sell_price, price_places),
|
|
53830
|
+
quantity,
|
|
53831
|
+
price_places,
|
|
53832
|
+
decimal_places
|
|
53833
|
+
};
|
|
53834
|
+
}
|
|
53798
53835
|
|
|
53799
53836
|
// src/helpers/strategy.ts
|
|
53800
53837
|
class Strategy {
|
|
@@ -54201,6 +54238,54 @@ class Strategy {
|
|
|
54201
54238
|
|
|
54202
54239
|
// src/exchanges/binance.ts
|
|
54203
54240
|
var import_binance = __toESM(require_lib2(), 1);
|
|
54241
|
+
|
|
54242
|
+
// src/types/index.ts
|
|
54243
|
+
class BaseExchange {
|
|
54244
|
+
client;
|
|
54245
|
+
constructor(client) {
|
|
54246
|
+
this.client = client;
|
|
54247
|
+
}
|
|
54248
|
+
async customStopLoss(payload) {
|
|
54249
|
+
const {
|
|
54250
|
+
symbol,
|
|
54251
|
+
kind,
|
|
54252
|
+
stop: _stop,
|
|
54253
|
+
quantity,
|
|
54254
|
+
increase = false,
|
|
54255
|
+
price_places,
|
|
54256
|
+
decimal_places
|
|
54257
|
+
} = payload;
|
|
54258
|
+
const spread = 1.00005;
|
|
54259
|
+
const stop = kind === "long" ? _stop * spread ** -1 : _stop * spread;
|
|
54260
|
+
const order = [
|
|
54261
|
+
{
|
|
54262
|
+
kind,
|
|
54263
|
+
side: kind === "long" ? "sell" : "buy",
|
|
54264
|
+
price: stop,
|
|
54265
|
+
quantity,
|
|
54266
|
+
stop: _stop,
|
|
54267
|
+
is_market: false
|
|
54268
|
+
}
|
|
54269
|
+
];
|
|
54270
|
+
if (increase) {
|
|
54271
|
+
order.push({
|
|
54272
|
+
kind,
|
|
54273
|
+
price: stop,
|
|
54274
|
+
side: kind === "long" ? "buy" : "sell",
|
|
54275
|
+
quantity,
|
|
54276
|
+
is_market: false
|
|
54277
|
+
});
|
|
54278
|
+
}
|
|
54279
|
+
return this.rawCreateLimitPurchaseOrders({
|
|
54280
|
+
orders: order,
|
|
54281
|
+
symbol,
|
|
54282
|
+
price_places,
|
|
54283
|
+
decimal_places
|
|
54284
|
+
});
|
|
54285
|
+
}
|
|
54286
|
+
}
|
|
54287
|
+
|
|
54288
|
+
// src/exchanges/binance.ts
|
|
54204
54289
|
var CONSTANTS = {
|
|
54205
54290
|
SPOT_TO_FIAT: "MAIN_C2C",
|
|
54206
54291
|
SPOT_TO_USDT_FUTURE: "MAIN_UMFUTURE",
|
|
@@ -54971,12 +55056,13 @@ async function getAllOpenOrders(payload) {
|
|
|
54971
55056
|
return response;
|
|
54972
55057
|
}
|
|
54973
55058
|
|
|
54974
|
-
class BinanceExchange {
|
|
55059
|
+
class BinanceExchange extends BaseExchange {
|
|
54975
55060
|
client;
|
|
54976
55061
|
main_client;
|
|
54977
55062
|
getCredentials;
|
|
54978
55063
|
proxyAgent;
|
|
54979
55064
|
constructor(client, main_client) {
|
|
55065
|
+
super(client);
|
|
54980
55066
|
this.client = client;
|
|
54981
55067
|
this.main_client = main_client;
|
|
54982
55068
|
}
|
|
@@ -55288,6 +55374,10 @@ class BinanceExchange {
|
|
|
55288
55374
|
}
|
|
55289
55375
|
]);
|
|
55290
55376
|
}
|
|
55377
|
+
async rawCreateLimitPurchaseOrders(payload) {
|
|
55378
|
+
const { symbol, orders, price_places, decimal_places } = payload;
|
|
55379
|
+
return createLimitPurchaseOrders(this.client, symbol, price_places, decimal_places, orders);
|
|
55380
|
+
}
|
|
55291
55381
|
}
|
|
55292
55382
|
function getPricePlaces(target) {
|
|
55293
55383
|
const numStr = target.toString();
|
|
@@ -55785,10 +55875,11 @@ async function analyzeCharts2(params) {
|
|
|
55785
55875
|
return finalPairs;
|
|
55786
55876
|
}
|
|
55787
55877
|
|
|
55788
|
-
class BybitExchange {
|
|
55878
|
+
class BybitExchange extends BaseExchange {
|
|
55789
55879
|
client;
|
|
55790
55880
|
main_client;
|
|
55791
55881
|
constructor(client, main_client) {
|
|
55882
|
+
super(client);
|
|
55792
55883
|
this.client = client;
|
|
55793
55884
|
this.main_client = main_client;
|
|
55794
55885
|
}
|
|
@@ -55962,6 +56053,10 @@ class BybitExchange {
|
|
|
55962
56053
|
}
|
|
55963
56054
|
async placeMarketOrder(payload) {
|
|
55964
56055
|
}
|
|
56056
|
+
async rawCreateLimitPurchaseOrders(payload) {
|
|
56057
|
+
const { symbol, orders, price_places, decimal_places } = payload;
|
|
56058
|
+
return createLimitPurchaseOrders2(this.client, symbol, price_places, decimal_places, orders);
|
|
56059
|
+
}
|
|
55965
56060
|
}
|
|
55966
56061
|
|
|
55967
56062
|
// src/helpers/accounts.ts
|
|
@@ -58726,15 +58821,19 @@ class ExchangeAccount {
|
|
|
58726
58821
|
async profitWithinGapStrategy(payload) {
|
|
58727
58822
|
const { symbol } = payload;
|
|
58728
58823
|
let reward_factor = 1;
|
|
58729
|
-
const strategy = await this.getAccountStrategy({ symbol });
|
|
58730
|
-
if (!strategy) {
|
|
58731
|
-
return;
|
|
58732
|
-
}
|
|
58733
58824
|
console.log("Fetching positions for ", symbol);
|
|
58734
58825
|
const positions = await this.syncAccount({
|
|
58735
58826
|
symbol,
|
|
58736
58827
|
as_view: true
|
|
58737
58828
|
});
|
|
58829
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
58830
|
+
if (!focus_position) {
|
|
58831
|
+
return;
|
|
58832
|
+
}
|
|
58833
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
58834
|
+
if (!strategy) {
|
|
58835
|
+
return;
|
|
58836
|
+
}
|
|
58738
58837
|
const risk = strategy.risk;
|
|
58739
58838
|
const kind = strategy.kind;
|
|
58740
58839
|
const support = strategy.support;
|
|
@@ -58743,7 +58842,6 @@ class ExchangeAccount {
|
|
|
58743
58842
|
const long_position = positions.find((k) => k.kind === "long");
|
|
58744
58843
|
const short_position = positions.find((k) => k.kind === "short");
|
|
58745
58844
|
console.log("Getting focus position for ", symbol, kind);
|
|
58746
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
58747
58845
|
const reverse_position = kind === "long" ? short_position : long_position;
|
|
58748
58846
|
if (strategy.max_reward_factor === 0) {
|
|
58749
58847
|
reward_factor = strategy.reward_factor;
|
|
@@ -58923,6 +59021,47 @@ class ExchangeAccount {
|
|
|
58923
59021
|
}
|
|
58924
59022
|
};
|
|
58925
59023
|
}
|
|
59024
|
+
async getSellPriceFromStrategy(payload) {
|
|
59025
|
+
const { symbol, reduce_position } = payload;
|
|
59026
|
+
const symbol_config = await this.recomputeSymbolConfig({
|
|
59027
|
+
symbol
|
|
59028
|
+
});
|
|
59029
|
+
const positions = await this.syncAccount({
|
|
59030
|
+
symbol,
|
|
59031
|
+
as_view: true
|
|
59032
|
+
});
|
|
59033
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
59034
|
+
if (!focus_position) {
|
|
59035
|
+
return;
|
|
59036
|
+
}
|
|
59037
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
59038
|
+
if (!strategy) {
|
|
59039
|
+
return;
|
|
59040
|
+
}
|
|
59041
|
+
return computeProfitDetail({
|
|
59042
|
+
focus_position: {
|
|
59043
|
+
kind: focus_position.kind,
|
|
59044
|
+
entry: focus_position.entry,
|
|
59045
|
+
quantity: focus_position.quantity,
|
|
59046
|
+
avg_price: focus_position.avg_price,
|
|
59047
|
+
avg_qty: focus_position.avg_qty
|
|
59048
|
+
},
|
|
59049
|
+
strategy: {
|
|
59050
|
+
reward_factor: strategy.reward_factor,
|
|
59051
|
+
risk: strategy.risk,
|
|
59052
|
+
max_reward_factor: strategy.max_reward_factor
|
|
59053
|
+
},
|
|
59054
|
+
reduce_position: {
|
|
59055
|
+
kind: reduce_position.kind,
|
|
59056
|
+
entry: reduce_position.entry,
|
|
59057
|
+
quantity: reduce_position.quantity,
|
|
59058
|
+
avg_price: reduce_position.avg_price,
|
|
59059
|
+
avg_qty: reduce_position.avg_qty
|
|
59060
|
+
},
|
|
59061
|
+
price_places: symbol_config.price_places,
|
|
59062
|
+
decimal_places: symbol_config.decimal_places
|
|
59063
|
+
});
|
|
59064
|
+
}
|
|
58926
59065
|
}
|
|
58927
59066
|
function getExchangeKlass(exchange) {
|
|
58928
59067
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
@@ -59255,6 +59394,32 @@ class App {
|
|
|
59255
59394
|
});
|
|
59256
59395
|
return result;
|
|
59257
59396
|
}
|
|
59397
|
+
async reduceExistingPosition(payload) {
|
|
59398
|
+
const { main_account, reduce_account, kind, place, increase } = payload;
|
|
59399
|
+
const main_exchange_account = await this.getExchangeAccount(main_account);
|
|
59400
|
+
const reduce_exchange_account = await this.getExchangeAccount(reduce_account);
|
|
59401
|
+
const reduce_position = await reduce_exchange_account.syncAccount({
|
|
59402
|
+
symbol: reduce_account.symbol,
|
|
59403
|
+
kind,
|
|
59404
|
+
as_view: true
|
|
59405
|
+
});
|
|
59406
|
+
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
59407
|
+
symbol: main_account.symbol,
|
|
59408
|
+
reduce_position
|
|
59409
|
+
});
|
|
59410
|
+
if (place) {
|
|
59411
|
+
return reduce_exchange_account.exchange.customStopLoss({
|
|
59412
|
+
symbol: reduce_account.symbol,
|
|
59413
|
+
kind: reduce_position.kind,
|
|
59414
|
+
stop: result.sell_price,
|
|
59415
|
+
quantity: result.quantity,
|
|
59416
|
+
price_places: result.price_places,
|
|
59417
|
+
decimal_places: result.decimal_places,
|
|
59418
|
+
increase
|
|
59419
|
+
});
|
|
59420
|
+
}
|
|
59421
|
+
return result;
|
|
59422
|
+
}
|
|
59258
59423
|
}
|
|
59259
59424
|
async function initApp(payload) {
|
|
59260
59425
|
const pb = await initPocketBaseClient(payload.db);
|
|
@@ -59361,6 +59526,7 @@ export {
|
|
|
59361
59526
|
exports_database as database,
|
|
59362
59527
|
createArray,
|
|
59363
59528
|
computeRiskReward,
|
|
59529
|
+
computeProfitDetail,
|
|
59364
59530
|
buildConfig,
|
|
59365
59531
|
buildAvg,
|
|
59366
59532
|
buildAppConfig,
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -58314,7 +58314,7 @@ class AppDatabase {
|
|
|
58314
58314
|
table: "positions_view",
|
|
58315
58315
|
params: {
|
|
58316
58316
|
filter: `symbol:lower="${symbol.toLowerCase()}" && account:lower="${account.owner.toLowerCase()} ${account.exchange.toLowerCase()}"`,
|
|
58317
|
-
expand: "config"
|
|
58317
|
+
expand: "config, account_strategy, p_account"
|
|
58318
58318
|
}
|
|
58319
58319
|
} : {
|
|
58320
58320
|
table: "positions",
|
|
@@ -60531,6 +60531,43 @@ function getRiskReward(payload) {
|
|
|
60531
60531
|
});
|
|
60532
60532
|
return risk_reward;
|
|
60533
60533
|
}
|
|
60534
|
+
function computeProfitDetail(payload) {
|
|
60535
|
+
const {
|
|
60536
|
+
focus_position,
|
|
60537
|
+
strategy,
|
|
60538
|
+
price_places = "%.1f",
|
|
60539
|
+
reduce_position,
|
|
60540
|
+
decimal_places
|
|
60541
|
+
} = payload;
|
|
60542
|
+
let reward_factor = strategy.reward_factor;
|
|
60543
|
+
let risk = strategy.risk;
|
|
60544
|
+
if (strategy.max_reward_factor === 0) {
|
|
60545
|
+
reward_factor = strategy.reward_factor;
|
|
60546
|
+
}
|
|
60547
|
+
if (focus_position.avg_qty >= focus_position.quantity && strategy.max_reward_factor) {
|
|
60548
|
+
reward_factor = focus_position.quantity * strategy.max_reward_factor / focus_position.avg_qty;
|
|
60549
|
+
} else {
|
|
60550
|
+
reward_factor = strategy.reward_factor;
|
|
60551
|
+
}
|
|
60552
|
+
const full_pnl = reward_factor * risk;
|
|
60553
|
+
const profit_percent = to_f2(full_pnl * 100 / (focus_position.avg_price * focus_position.avg_qty), "%.4f");
|
|
60554
|
+
const pnl = to_f2(focus_position.entry * focus_position.quantity * profit_percent / 100, "%.2f");
|
|
60555
|
+
const diff = pnl / focus_position.quantity;
|
|
60556
|
+
const sell_price = to_f2(focus_position.kind === "long" ? focus_position.entry + diff : focus_position.entry - diff, price_places);
|
|
60557
|
+
const loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
60558
|
+
const ratio = pnl / loss;
|
|
60559
|
+
const quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
60560
|
+
return {
|
|
60561
|
+
pnl,
|
|
60562
|
+
reward_factor,
|
|
60563
|
+
profit_percent,
|
|
60564
|
+
kind: focus_position.kind,
|
|
60565
|
+
sell_price: to_f2(sell_price, price_places),
|
|
60566
|
+
quantity,
|
|
60567
|
+
price_places,
|
|
60568
|
+
decimal_places
|
|
60569
|
+
};
|
|
60570
|
+
}
|
|
60534
60571
|
|
|
60535
60572
|
// src/helpers/strategy.ts
|
|
60536
60573
|
class Strategy {
|
|
@@ -60937,6 +60974,54 @@ class Strategy {
|
|
|
60937
60974
|
|
|
60938
60975
|
// src/exchanges/binance.ts
|
|
60939
60976
|
var import_binance = __toESM(require_lib2());
|
|
60977
|
+
|
|
60978
|
+
// src/types/index.ts
|
|
60979
|
+
class BaseExchange {
|
|
60980
|
+
client;
|
|
60981
|
+
constructor(client) {
|
|
60982
|
+
this.client = client;
|
|
60983
|
+
}
|
|
60984
|
+
async customStopLoss(payload) {
|
|
60985
|
+
const {
|
|
60986
|
+
symbol,
|
|
60987
|
+
kind,
|
|
60988
|
+
stop: _stop,
|
|
60989
|
+
quantity,
|
|
60990
|
+
increase = false,
|
|
60991
|
+
price_places,
|
|
60992
|
+
decimal_places
|
|
60993
|
+
} = payload;
|
|
60994
|
+
const spread = 1.00005;
|
|
60995
|
+
const stop = kind === "long" ? _stop * spread ** -1 : _stop * spread;
|
|
60996
|
+
const order = [
|
|
60997
|
+
{
|
|
60998
|
+
kind,
|
|
60999
|
+
side: kind === "long" ? "sell" : "buy",
|
|
61000
|
+
price: stop,
|
|
61001
|
+
quantity,
|
|
61002
|
+
stop: _stop,
|
|
61003
|
+
is_market: false
|
|
61004
|
+
}
|
|
61005
|
+
];
|
|
61006
|
+
if (increase) {
|
|
61007
|
+
order.push({
|
|
61008
|
+
kind,
|
|
61009
|
+
price: stop,
|
|
61010
|
+
side: kind === "long" ? "buy" : "sell",
|
|
61011
|
+
quantity,
|
|
61012
|
+
is_market: false
|
|
61013
|
+
});
|
|
61014
|
+
}
|
|
61015
|
+
return this.rawCreateLimitPurchaseOrders({
|
|
61016
|
+
orders: order,
|
|
61017
|
+
symbol,
|
|
61018
|
+
price_places,
|
|
61019
|
+
decimal_places
|
|
61020
|
+
});
|
|
61021
|
+
}
|
|
61022
|
+
}
|
|
61023
|
+
|
|
61024
|
+
// src/exchanges/binance.ts
|
|
60940
61025
|
var CONSTANTS = {
|
|
60941
61026
|
SPOT_TO_FIAT: "MAIN_C2C",
|
|
60942
61027
|
SPOT_TO_USDT_FUTURE: "MAIN_UMFUTURE",
|
|
@@ -61707,12 +61792,13 @@ async function getAllOpenOrders(payload) {
|
|
|
61707
61792
|
return response;
|
|
61708
61793
|
}
|
|
61709
61794
|
|
|
61710
|
-
class BinanceExchange {
|
|
61795
|
+
class BinanceExchange extends BaseExchange {
|
|
61711
61796
|
client;
|
|
61712
61797
|
main_client;
|
|
61713
61798
|
getCredentials;
|
|
61714
61799
|
proxyAgent;
|
|
61715
61800
|
constructor(client, main_client) {
|
|
61801
|
+
super(client);
|
|
61716
61802
|
this.client = client;
|
|
61717
61803
|
this.main_client = main_client;
|
|
61718
61804
|
}
|
|
@@ -62024,6 +62110,10 @@ class BinanceExchange {
|
|
|
62024
62110
|
}
|
|
62025
62111
|
]);
|
|
62026
62112
|
}
|
|
62113
|
+
async rawCreateLimitPurchaseOrders(payload) {
|
|
62114
|
+
const { symbol, orders, price_places, decimal_places } = payload;
|
|
62115
|
+
return createLimitPurchaseOrders(this.client, symbol, price_places, decimal_places, orders);
|
|
62116
|
+
}
|
|
62027
62117
|
}
|
|
62028
62118
|
function getPricePlaces(target) {
|
|
62029
62119
|
const numStr = target.toString();
|
|
@@ -62521,10 +62611,11 @@ async function analyzeCharts2(params) {
|
|
|
62521
62611
|
return finalPairs;
|
|
62522
62612
|
}
|
|
62523
62613
|
|
|
62524
|
-
class BybitExchange {
|
|
62614
|
+
class BybitExchange extends BaseExchange {
|
|
62525
62615
|
client;
|
|
62526
62616
|
main_client;
|
|
62527
62617
|
constructor(client, main_client) {
|
|
62618
|
+
super(client);
|
|
62528
62619
|
this.client = client;
|
|
62529
62620
|
this.main_client = main_client;
|
|
62530
62621
|
}
|
|
@@ -62698,6 +62789,10 @@ class BybitExchange {
|
|
|
62698
62789
|
}
|
|
62699
62790
|
async placeMarketOrder(payload) {
|
|
62700
62791
|
}
|
|
62792
|
+
async rawCreateLimitPurchaseOrders(payload) {
|
|
62793
|
+
const { symbol, orders, price_places, decimal_places } = payload;
|
|
62794
|
+
return createLimitPurchaseOrders2(this.client, symbol, price_places, decimal_places, orders);
|
|
62795
|
+
}
|
|
62701
62796
|
}
|
|
62702
62797
|
|
|
62703
62798
|
// src/helpers/accounts.ts
|
|
@@ -65462,15 +65557,19 @@ class ExchangeAccount {
|
|
|
65462
65557
|
async profitWithinGapStrategy(payload) {
|
|
65463
65558
|
const { symbol } = payload;
|
|
65464
65559
|
let reward_factor = 1;
|
|
65465
|
-
const strategy = await this.getAccountStrategy({ symbol });
|
|
65466
|
-
if (!strategy) {
|
|
65467
|
-
return;
|
|
65468
|
-
}
|
|
65469
65560
|
console.log("Fetching positions for ", symbol);
|
|
65470
65561
|
const positions = await this.syncAccount({
|
|
65471
65562
|
symbol,
|
|
65472
65563
|
as_view: true
|
|
65473
65564
|
});
|
|
65565
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
65566
|
+
if (!focus_position) {
|
|
65567
|
+
return;
|
|
65568
|
+
}
|
|
65569
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
65570
|
+
if (!strategy) {
|
|
65571
|
+
return;
|
|
65572
|
+
}
|
|
65474
65573
|
const risk = strategy.risk;
|
|
65475
65574
|
const kind = strategy.kind;
|
|
65476
65575
|
const support = strategy.support;
|
|
@@ -65479,7 +65578,6 @@ class ExchangeAccount {
|
|
|
65479
65578
|
const long_position = positions.find((k) => k.kind === "long");
|
|
65480
65579
|
const short_position = positions.find((k) => k.kind === "short");
|
|
65481
65580
|
console.log("Getting focus position for ", symbol, kind);
|
|
65482
|
-
const focus_position = kind === "long" ? long_position : short_position;
|
|
65483
65581
|
const reverse_position = kind === "long" ? short_position : long_position;
|
|
65484
65582
|
if (strategy.max_reward_factor === 0) {
|
|
65485
65583
|
reward_factor = strategy.reward_factor;
|
|
@@ -65659,6 +65757,47 @@ class ExchangeAccount {
|
|
|
65659
65757
|
}
|
|
65660
65758
|
};
|
|
65661
65759
|
}
|
|
65760
|
+
async getSellPriceFromStrategy(payload) {
|
|
65761
|
+
const { symbol, reduce_position } = payload;
|
|
65762
|
+
const symbol_config = await this.recomputeSymbolConfig({
|
|
65763
|
+
symbol
|
|
65764
|
+
});
|
|
65765
|
+
const positions = await this.syncAccount({
|
|
65766
|
+
symbol,
|
|
65767
|
+
as_view: true
|
|
65768
|
+
});
|
|
65769
|
+
const focus_position = positions.find((k) => k.expand?.account_strategy);
|
|
65770
|
+
if (!focus_position) {
|
|
65771
|
+
return;
|
|
65772
|
+
}
|
|
65773
|
+
const strategy = focus_position?.expand?.account_strategy;
|
|
65774
|
+
if (!strategy) {
|
|
65775
|
+
return;
|
|
65776
|
+
}
|
|
65777
|
+
return computeProfitDetail({
|
|
65778
|
+
focus_position: {
|
|
65779
|
+
kind: focus_position.kind,
|
|
65780
|
+
entry: focus_position.entry,
|
|
65781
|
+
quantity: focus_position.quantity,
|
|
65782
|
+
avg_price: focus_position.avg_price,
|
|
65783
|
+
avg_qty: focus_position.avg_qty
|
|
65784
|
+
},
|
|
65785
|
+
strategy: {
|
|
65786
|
+
reward_factor: strategy.reward_factor,
|
|
65787
|
+
risk: strategy.risk,
|
|
65788
|
+
max_reward_factor: strategy.max_reward_factor
|
|
65789
|
+
},
|
|
65790
|
+
reduce_position: {
|
|
65791
|
+
kind: reduce_position.kind,
|
|
65792
|
+
entry: reduce_position.entry,
|
|
65793
|
+
quantity: reduce_position.quantity,
|
|
65794
|
+
avg_price: reduce_position.avg_price,
|
|
65795
|
+
avg_qty: reduce_position.avg_qty
|
|
65796
|
+
},
|
|
65797
|
+
price_places: symbol_config.price_places,
|
|
65798
|
+
decimal_places: symbol_config.decimal_places
|
|
65799
|
+
});
|
|
65800
|
+
}
|
|
65662
65801
|
}
|
|
65663
65802
|
function getExchangeKlass(exchange) {
|
|
65664
65803
|
const func = exchange === "binance" ? BinanceExchange : BybitExchange;
|
|
@@ -65991,6 +66130,32 @@ class App {
|
|
|
65991
66130
|
});
|
|
65992
66131
|
return result;
|
|
65993
66132
|
}
|
|
66133
|
+
async reduceExistingPosition(payload) {
|
|
66134
|
+
const { main_account, reduce_account, kind, place, increase } = payload;
|
|
66135
|
+
const main_exchange_account = await this.getExchangeAccount(main_account);
|
|
66136
|
+
const reduce_exchange_account = await this.getExchangeAccount(reduce_account);
|
|
66137
|
+
const reduce_position = await reduce_exchange_account.syncAccount({
|
|
66138
|
+
symbol: reduce_account.symbol,
|
|
66139
|
+
kind,
|
|
66140
|
+
as_view: true
|
|
66141
|
+
});
|
|
66142
|
+
const result = await main_exchange_account.getSellPriceFromStrategy({
|
|
66143
|
+
symbol: main_account.symbol,
|
|
66144
|
+
reduce_position
|
|
66145
|
+
});
|
|
66146
|
+
if (place) {
|
|
66147
|
+
return reduce_exchange_account.exchange.customStopLoss({
|
|
66148
|
+
symbol: reduce_account.symbol,
|
|
66149
|
+
kind: reduce_position.kind,
|
|
66150
|
+
stop: result.sell_price,
|
|
66151
|
+
quantity: result.quantity,
|
|
66152
|
+
price_places: result.price_places,
|
|
66153
|
+
decimal_places: result.decimal_places,
|
|
66154
|
+
increase
|
|
66155
|
+
});
|
|
66156
|
+
}
|
|
66157
|
+
return result;
|
|
66158
|
+
}
|
|
65994
66159
|
}
|
|
65995
66160
|
async function initApp(payload) {
|
|
65996
66161
|
const pb = await initPocketBaseClient(payload.db);
|