@gbozee/ultimate 0.0.2-174 → 0.0.2-176
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 +28 -0
- package/dist/frontend-index.js +94 -0
- package/dist/index.cjs +168 -1
- package/dist/index.d.ts +78 -0
- package/dist/index.js +168 -1
- package/dist/mcp-server.cjs +74 -1
- package/dist/mcp-server.js +74 -1
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -703,6 +703,34 @@ export declare function generateGapTp(payload: {
|
|
|
703
703
|
gap: number;
|
|
704
704
|
gap_loss: number;
|
|
705
705
|
};
|
|
706
|
+
export declare function calculateFactorFromTakeProfit(payload: {
|
|
707
|
+
long: {
|
|
708
|
+
entry: number;
|
|
709
|
+
quantity: number;
|
|
710
|
+
};
|
|
711
|
+
short: {
|
|
712
|
+
entry: number;
|
|
713
|
+
quantity: number;
|
|
714
|
+
};
|
|
715
|
+
knownTp: number;
|
|
716
|
+
tpType: "long" | "short";
|
|
717
|
+
price_places?: string;
|
|
718
|
+
}): number;
|
|
719
|
+
export declare function calculateFactorFromSellQuantity(payload: {
|
|
720
|
+
long: {
|
|
721
|
+
entry: number;
|
|
722
|
+
quantity: number;
|
|
723
|
+
};
|
|
724
|
+
short: {
|
|
725
|
+
entry: number;
|
|
726
|
+
quantity: number;
|
|
727
|
+
};
|
|
728
|
+
knownSellQuantity: number;
|
|
729
|
+
sellType: "long" | "short";
|
|
730
|
+
sell_factor?: number;
|
|
731
|
+
price_places?: string;
|
|
732
|
+
decimal_places?: string;
|
|
733
|
+
}): number;
|
|
706
734
|
export declare function determineRewardFactor(payload: {
|
|
707
735
|
quantity: number;
|
|
708
736
|
avg_qty: number;
|
package/dist/frontend-index.js
CHANGED
|
@@ -2299,6 +2299,98 @@ function calculate_factor(payload) {
|
|
|
2299
2299
|
calculated_factor = to_f(calculated_factor, places);
|
|
2300
2300
|
return calculated_factor;
|
|
2301
2301
|
}
|
|
2302
|
+
function calculateFactorFromTakeProfit(payload) {
|
|
2303
|
+
const { long, short, knownTp, tpType, price_places = "%.4f" } = payload;
|
|
2304
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
2305
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
2306
|
+
const gapLoss = gap * max_quantity;
|
|
2307
|
+
if (gapLoss === 0) {
|
|
2308
|
+
return 0;
|
|
2309
|
+
}
|
|
2310
|
+
let factor;
|
|
2311
|
+
if (tpType === "long") {
|
|
2312
|
+
const longPercent = knownTp / long.entry - 1;
|
|
2313
|
+
factor = longPercent * short.entry * short.quantity / gapLoss;
|
|
2314
|
+
} else {
|
|
2315
|
+
const shortPercent = short.entry / knownTp - 1;
|
|
2316
|
+
factor = shortPercent * long.entry * long.quantity / gapLoss;
|
|
2317
|
+
}
|
|
2318
|
+
return to_f(factor, price_places);
|
|
2319
|
+
}
|
|
2320
|
+
function calculateFactorFromSellQuantity(payload) {
|
|
2321
|
+
const {
|
|
2322
|
+
long,
|
|
2323
|
+
short,
|
|
2324
|
+
knownSellQuantity,
|
|
2325
|
+
sellType,
|
|
2326
|
+
sell_factor = 1,
|
|
2327
|
+
price_places = "%.4f"
|
|
2328
|
+
} = payload;
|
|
2329
|
+
if (knownSellQuantity < 0.00001) {
|
|
2330
|
+
return 0;
|
|
2331
|
+
}
|
|
2332
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
2333
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
2334
|
+
const gapLoss = gap * max_quantity;
|
|
2335
|
+
if (gapLoss === 0) {
|
|
2336
|
+
return 0;
|
|
2337
|
+
}
|
|
2338
|
+
let low_factor = 0.001;
|
|
2339
|
+
let high_factor = 1;
|
|
2340
|
+
let best_factor = 0;
|
|
2341
|
+
let best_diff = Infinity;
|
|
2342
|
+
const tolerance = 0.00001;
|
|
2343
|
+
const max_iterations = 150;
|
|
2344
|
+
let expansions = 0;
|
|
2345
|
+
const max_expansions = 15;
|
|
2346
|
+
let iterations = 0;
|
|
2347
|
+
while (iterations < max_iterations) {
|
|
2348
|
+
iterations++;
|
|
2349
|
+
const mid_factor = (low_factor + high_factor) / 2;
|
|
2350
|
+
const testResult = generateGapTp({
|
|
2351
|
+
long,
|
|
2352
|
+
short,
|
|
2353
|
+
factor: mid_factor,
|
|
2354
|
+
sell_factor,
|
|
2355
|
+
price_places: "%.8f",
|
|
2356
|
+
decimal_places: "%.8f"
|
|
2357
|
+
});
|
|
2358
|
+
const testSellQty = sellType === "long" ? testResult.sell_quantity.long : testResult.sell_quantity.short;
|
|
2359
|
+
const diff = Math.abs(testSellQty - knownSellQuantity);
|
|
2360
|
+
if (diff < best_diff) {
|
|
2361
|
+
best_diff = diff;
|
|
2362
|
+
best_factor = mid_factor;
|
|
2363
|
+
}
|
|
2364
|
+
if (diff < tolerance) {
|
|
2365
|
+
return to_f(mid_factor, price_places);
|
|
2366
|
+
}
|
|
2367
|
+
if (testSellQty < knownSellQuantity) {
|
|
2368
|
+
low_factor = mid_factor;
|
|
2369
|
+
if (mid_factor > high_factor * 0.9 && expansions < max_expansions) {
|
|
2370
|
+
const ratio = knownSellQuantity / testSellQty;
|
|
2371
|
+
if (ratio > 2) {
|
|
2372
|
+
high_factor = high_factor * Math.min(ratio, 10);
|
|
2373
|
+
} else {
|
|
2374
|
+
high_factor = high_factor * 2;
|
|
2375
|
+
}
|
|
2376
|
+
expansions++;
|
|
2377
|
+
continue;
|
|
2378
|
+
}
|
|
2379
|
+
} else {
|
|
2380
|
+
high_factor = mid_factor;
|
|
2381
|
+
}
|
|
2382
|
+
if (Math.abs(high_factor - low_factor) < 0.00001 && diff > tolerance) {
|
|
2383
|
+
if (testSellQty < knownSellQuantity && expansions < max_expansions) {
|
|
2384
|
+
high_factor = high_factor * 1.1;
|
|
2385
|
+
expansions++;
|
|
2386
|
+
continue;
|
|
2387
|
+
} else {
|
|
2388
|
+
break;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
return to_f(best_factor, price_places);
|
|
2393
|
+
}
|
|
2302
2394
|
function determineRewardFactor(payload) {
|
|
2303
2395
|
const { quantity, avg_qty, minimum_pnl, risk } = payload;
|
|
2304
2396
|
const reward_factor = minimum_pnl / risk;
|
|
@@ -3084,6 +3176,8 @@ export {
|
|
|
3084
3176
|
computeSellZones,
|
|
3085
3177
|
computeRiskReward,
|
|
3086
3178
|
computeProfitDetail,
|
|
3179
|
+
calculateFactorFromTakeProfit,
|
|
3180
|
+
calculateFactorFromSellQuantity,
|
|
3087
3181
|
buildConfig,
|
|
3088
3182
|
buildAvg,
|
|
3089
3183
|
buildAppConfig,
|
package/dist/index.cjs
CHANGED
|
@@ -44901,6 +44901,8 @@ __export(exports_src, {
|
|
|
44901
44901
|
constructAppConfig: () => constructAppConfig,
|
|
44902
44902
|
computeRiskReward: () => computeRiskReward,
|
|
44903
44903
|
computeProfitDetail: () => computeProfitDetail,
|
|
44904
|
+
calculateFactorFromTakeProfit: () => calculateFactorFromTakeProfit,
|
|
44905
|
+
calculateFactorFromSellQuantity: () => calculateFactorFromSellQuantity,
|
|
44904
44906
|
buildConfig: () => buildConfig,
|
|
44905
44907
|
buildAvg: () => buildAvg,
|
|
44906
44908
|
buildAppConfig: () => buildAppConfig,
|
|
@@ -55515,6 +55517,33 @@ class AppDatabase {
|
|
|
55515
55517
|
parent: config_id
|
|
55516
55518
|
});
|
|
55517
55519
|
}
|
|
55520
|
+
async getCompoundInstance(payload) {
|
|
55521
|
+
const { position } = payload;
|
|
55522
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
55523
|
+
filter: `position.id = "${position.id}"`,
|
|
55524
|
+
expand: `ref`
|
|
55525
|
+
});
|
|
55526
|
+
if (found.length == 0) {
|
|
55527
|
+
return;
|
|
55528
|
+
}
|
|
55529
|
+
const item = found[0];
|
|
55530
|
+
return item;
|
|
55531
|
+
}
|
|
55532
|
+
async getSupportTable(payload) {
|
|
55533
|
+
const { symbol, kind } = payload;
|
|
55534
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
55535
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
55536
|
+
});
|
|
55537
|
+
if (found.length === 0) {
|
|
55538
|
+
return;
|
|
55539
|
+
}
|
|
55540
|
+
const item = found[0];
|
|
55541
|
+
return item;
|
|
55542
|
+
}
|
|
55543
|
+
async updateCompoundInstance(payload) {
|
|
55544
|
+
const { id, params } = payload;
|
|
55545
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
55546
|
+
}
|
|
55518
55547
|
}
|
|
55519
55548
|
|
|
55520
55549
|
// src/exchange-account.ts
|
|
@@ -57617,6 +57646,98 @@ function calculate_factor(payload) {
|
|
|
57617
57646
|
calculated_factor = to_f(calculated_factor, places);
|
|
57618
57647
|
return calculated_factor;
|
|
57619
57648
|
}
|
|
57649
|
+
function calculateFactorFromTakeProfit(payload) {
|
|
57650
|
+
const { long, short, knownTp, tpType, price_places = "%.4f" } = payload;
|
|
57651
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
57652
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
57653
|
+
const gapLoss = gap * max_quantity;
|
|
57654
|
+
if (gapLoss === 0) {
|
|
57655
|
+
return 0;
|
|
57656
|
+
}
|
|
57657
|
+
let factor;
|
|
57658
|
+
if (tpType === "long") {
|
|
57659
|
+
const longPercent = knownTp / long.entry - 1;
|
|
57660
|
+
factor = longPercent * short.entry * short.quantity / gapLoss;
|
|
57661
|
+
} else {
|
|
57662
|
+
const shortPercent = short.entry / knownTp - 1;
|
|
57663
|
+
factor = shortPercent * long.entry * long.quantity / gapLoss;
|
|
57664
|
+
}
|
|
57665
|
+
return to_f(factor, price_places);
|
|
57666
|
+
}
|
|
57667
|
+
function calculateFactorFromSellQuantity(payload) {
|
|
57668
|
+
const {
|
|
57669
|
+
long,
|
|
57670
|
+
short,
|
|
57671
|
+
knownSellQuantity,
|
|
57672
|
+
sellType,
|
|
57673
|
+
sell_factor = 1,
|
|
57674
|
+
price_places = "%.4f"
|
|
57675
|
+
} = payload;
|
|
57676
|
+
if (knownSellQuantity < 0.00001) {
|
|
57677
|
+
return 0;
|
|
57678
|
+
}
|
|
57679
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
57680
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
57681
|
+
const gapLoss = gap * max_quantity;
|
|
57682
|
+
if (gapLoss === 0) {
|
|
57683
|
+
return 0;
|
|
57684
|
+
}
|
|
57685
|
+
let low_factor = 0.001;
|
|
57686
|
+
let high_factor = 1;
|
|
57687
|
+
let best_factor = 0;
|
|
57688
|
+
let best_diff = Infinity;
|
|
57689
|
+
const tolerance = 0.00001;
|
|
57690
|
+
const max_iterations = 150;
|
|
57691
|
+
let expansions = 0;
|
|
57692
|
+
const max_expansions = 15;
|
|
57693
|
+
let iterations = 0;
|
|
57694
|
+
while (iterations < max_iterations) {
|
|
57695
|
+
iterations++;
|
|
57696
|
+
const mid_factor = (low_factor + high_factor) / 2;
|
|
57697
|
+
const testResult = generateGapTp({
|
|
57698
|
+
long,
|
|
57699
|
+
short,
|
|
57700
|
+
factor: mid_factor,
|
|
57701
|
+
sell_factor,
|
|
57702
|
+
price_places: "%.8f",
|
|
57703
|
+
decimal_places: "%.8f"
|
|
57704
|
+
});
|
|
57705
|
+
const testSellQty = sellType === "long" ? testResult.sell_quantity.long : testResult.sell_quantity.short;
|
|
57706
|
+
const diff = Math.abs(testSellQty - knownSellQuantity);
|
|
57707
|
+
if (diff < best_diff) {
|
|
57708
|
+
best_diff = diff;
|
|
57709
|
+
best_factor = mid_factor;
|
|
57710
|
+
}
|
|
57711
|
+
if (diff < tolerance) {
|
|
57712
|
+
return to_f(mid_factor, price_places);
|
|
57713
|
+
}
|
|
57714
|
+
if (testSellQty < knownSellQuantity) {
|
|
57715
|
+
low_factor = mid_factor;
|
|
57716
|
+
if (mid_factor > high_factor * 0.9 && expansions < max_expansions) {
|
|
57717
|
+
const ratio = knownSellQuantity / testSellQty;
|
|
57718
|
+
if (ratio > 2) {
|
|
57719
|
+
high_factor = high_factor * Math.min(ratio, 10);
|
|
57720
|
+
} else {
|
|
57721
|
+
high_factor = high_factor * 2;
|
|
57722
|
+
}
|
|
57723
|
+
expansions++;
|
|
57724
|
+
continue;
|
|
57725
|
+
}
|
|
57726
|
+
} else {
|
|
57727
|
+
high_factor = mid_factor;
|
|
57728
|
+
}
|
|
57729
|
+
if (Math.abs(high_factor - low_factor) < 0.00001 && diff > tolerance) {
|
|
57730
|
+
if (testSellQty < knownSellQuantity && expansions < max_expansions) {
|
|
57731
|
+
high_factor = high_factor * 1.1;
|
|
57732
|
+
expansions++;
|
|
57733
|
+
continue;
|
|
57734
|
+
} else {
|
|
57735
|
+
break;
|
|
57736
|
+
}
|
|
57737
|
+
}
|
|
57738
|
+
}
|
|
57739
|
+
return to_f(best_factor, price_places);
|
|
57740
|
+
}
|
|
57620
57741
|
function determineRewardFactor(payload) {
|
|
57621
57742
|
const { quantity, avg_qty, minimum_pnl, risk } = payload;
|
|
57622
57743
|
const reward_factor = minimum_pnl / risk;
|
|
@@ -60790,7 +60911,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
60790
60911
|
// src/position.ts
|
|
60791
60912
|
var import_https_proxy_agent2 = __toESM(require_dist2());
|
|
60792
60913
|
var import_socks_proxy_agent2 = __toESM(require_dist3());
|
|
60793
|
-
|
|
60794
60914
|
class ExchangePosition {
|
|
60795
60915
|
exchange;
|
|
60796
60916
|
symbol_config;
|
|
@@ -61835,6 +61955,53 @@ class ExchangePosition {
|
|
|
61835
61955
|
increase: false
|
|
61836
61956
|
});
|
|
61837
61957
|
}
|
|
61958
|
+
async isActiveTrade() {
|
|
61959
|
+
const config2 = await this.getConfig();
|
|
61960
|
+
const supportTable = await this.app_db.getSupportTable({
|
|
61961
|
+
symbol: this.symbol,
|
|
61962
|
+
kind: this.kind
|
|
61963
|
+
});
|
|
61964
|
+
return {
|
|
61965
|
+
config: config2,
|
|
61966
|
+
condition: supportTable?.price === config2.stop,
|
|
61967
|
+
supportTable
|
|
61968
|
+
};
|
|
61969
|
+
}
|
|
61970
|
+
async updateCompound(payload) {
|
|
61971
|
+
const pb = this.app_db.pb;
|
|
61972
|
+
const item = await this.app_db.getCompoundInstance({
|
|
61973
|
+
position: this.instance
|
|
61974
|
+
});
|
|
61975
|
+
const {
|
|
61976
|
+
expand: { ref }
|
|
61977
|
+
} = item;
|
|
61978
|
+
const risk = item.risk;
|
|
61979
|
+
const percent = ref.profit_percent / 100;
|
|
61980
|
+
const new_risk = risk * (1 + percent);
|
|
61981
|
+
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
61982
|
+
if (payload?.place && condition) {
|
|
61983
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
61984
|
+
risk: new_risk
|
|
61985
|
+
});
|
|
61986
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
61987
|
+
profit: to_f(new_risk * percent, "%.3f")
|
|
61988
|
+
});
|
|
61989
|
+
}
|
|
61990
|
+
return {
|
|
61991
|
+
support: supportTable.price,
|
|
61992
|
+
counter: supportTable.counter,
|
|
61993
|
+
new_risk
|
|
61994
|
+
};
|
|
61995
|
+
}
|
|
61996
|
+
async cleanOnActiveCompoundInstance() {
|
|
61997
|
+
const item = await this.app_db.getCompoundInstance({
|
|
61998
|
+
position: this.instance
|
|
61999
|
+
});
|
|
62000
|
+
const { condition } = await this.isActiveTrade();
|
|
62001
|
+
if (item && condition && this.instance.quantity === 0) {
|
|
62002
|
+
await this.cancelOrders({ limit: true });
|
|
62003
|
+
}
|
|
62004
|
+
}
|
|
61838
62005
|
}
|
|
61839
62006
|
function convert_to_exchange_order(order) {
|
|
61840
62007
|
return {
|
package/dist/index.d.ts
CHANGED
|
@@ -155,6 +155,28 @@ export interface WindingDownMarket extends RecordModel {
|
|
|
155
155
|
symbol: string;
|
|
156
156
|
risk_reward: number;
|
|
157
157
|
}
|
|
158
|
+
export interface Compounder extends BaseSystemFields {
|
|
159
|
+
risk?: number;
|
|
160
|
+
profit_percent?: number;
|
|
161
|
+
owner?: string;
|
|
162
|
+
completed?: boolean;
|
|
163
|
+
start_balance?: number;
|
|
164
|
+
starting_risk?: number;
|
|
165
|
+
fee_rate?: number;
|
|
166
|
+
}
|
|
167
|
+
export interface CompoundInstance extends BaseSystemFields {
|
|
168
|
+
ref?: string;
|
|
169
|
+
position?: string;
|
|
170
|
+
risk?: number;
|
|
171
|
+
hedged?: boolean;
|
|
172
|
+
}
|
|
173
|
+
export interface SupportTable extends BaseSystemFields {
|
|
174
|
+
symbol?: string;
|
|
175
|
+
price?: number;
|
|
176
|
+
counter?: number;
|
|
177
|
+
last_updated?: string;
|
|
178
|
+
kind?: "long" | "short";
|
|
179
|
+
}
|
|
158
180
|
export interface BotInstance extends BaseSystemFields {
|
|
159
181
|
asset: string;
|
|
160
182
|
main_account?: string;
|
|
@@ -848,6 +870,21 @@ export declare class AppDatabase {
|
|
|
848
870
|
profit_percent: number;
|
|
849
871
|
};
|
|
850
872
|
}): Promise<void>;
|
|
873
|
+
getCompoundInstance(payload: {
|
|
874
|
+
position: Position$1;
|
|
875
|
+
}): Promise<CompoundInstance & {
|
|
876
|
+
expand: {
|
|
877
|
+
ref: Compounder;
|
|
878
|
+
};
|
|
879
|
+
}>;
|
|
880
|
+
getSupportTable(payload: {
|
|
881
|
+
symbol: string;
|
|
882
|
+
kind: "long" | "short";
|
|
883
|
+
}): Promise<SupportTable>;
|
|
884
|
+
updateCompoundInstance(payload: {
|
|
885
|
+
id: string;
|
|
886
|
+
params: any;
|
|
887
|
+
}): Promise<import("pocketbase").RecordModel>;
|
|
851
888
|
}
|
|
852
889
|
export type StrategyPosition = {
|
|
853
890
|
entry: number;
|
|
@@ -1596,6 +1633,34 @@ export declare function generateGapTp(payload: {
|
|
|
1596
1633
|
gap: number;
|
|
1597
1634
|
gap_loss: number;
|
|
1598
1635
|
};
|
|
1636
|
+
export declare function calculateFactorFromTakeProfit(payload: {
|
|
1637
|
+
long: {
|
|
1638
|
+
entry: number;
|
|
1639
|
+
quantity: number;
|
|
1640
|
+
};
|
|
1641
|
+
short: {
|
|
1642
|
+
entry: number;
|
|
1643
|
+
quantity: number;
|
|
1644
|
+
};
|
|
1645
|
+
knownTp: number;
|
|
1646
|
+
tpType: "long" | "short";
|
|
1647
|
+
price_places?: string;
|
|
1648
|
+
}): number;
|
|
1649
|
+
export declare function calculateFactorFromSellQuantity(payload: {
|
|
1650
|
+
long: {
|
|
1651
|
+
entry: number;
|
|
1652
|
+
quantity: number;
|
|
1653
|
+
};
|
|
1654
|
+
short: {
|
|
1655
|
+
entry: number;
|
|
1656
|
+
quantity: number;
|
|
1657
|
+
};
|
|
1658
|
+
knownSellQuantity: number;
|
|
1659
|
+
sellType: "long" | "short";
|
|
1660
|
+
sell_factor?: number;
|
|
1661
|
+
price_places?: string;
|
|
1662
|
+
decimal_places?: string;
|
|
1663
|
+
}): number;
|
|
1599
1664
|
export declare function determineRewardFactor(payload: {
|
|
1600
1665
|
quantity: number;
|
|
1601
1666
|
avg_qty: number;
|
|
@@ -2115,6 +2180,19 @@ export declare class ExchangePosition {
|
|
|
2115
2180
|
fee_percent?: number;
|
|
2116
2181
|
place?: boolean;
|
|
2117
2182
|
}): Promise<any>;
|
|
2183
|
+
isActiveTrade(): Promise<{
|
|
2184
|
+
config: import("pocketbase").RecordModel | ScheduledTrade;
|
|
2185
|
+
condition: boolean;
|
|
2186
|
+
supportTable: SupportTable;
|
|
2187
|
+
}>;
|
|
2188
|
+
updateCompound(payload?: {
|
|
2189
|
+
place?: boolean;
|
|
2190
|
+
}): Promise<{
|
|
2191
|
+
support: number;
|
|
2192
|
+
counter: number;
|
|
2193
|
+
new_risk: number;
|
|
2194
|
+
}>;
|
|
2195
|
+
cleanOnActiveCompoundInstance(): Promise<void>;
|
|
2118
2196
|
}
|
|
2119
2197
|
declare class ExchangeAccount$1 {
|
|
2120
2198
|
instance: {
|
package/dist/index.js
CHANGED
|
@@ -55455,6 +55455,33 @@ class AppDatabase {
|
|
|
55455
55455
|
parent: config_id
|
|
55456
55456
|
});
|
|
55457
55457
|
}
|
|
55458
|
+
async getCompoundInstance(payload) {
|
|
55459
|
+
const { position } = payload;
|
|
55460
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
55461
|
+
filter: `position.id = "${position.id}"`,
|
|
55462
|
+
expand: `ref`
|
|
55463
|
+
});
|
|
55464
|
+
if (found.length == 0) {
|
|
55465
|
+
return;
|
|
55466
|
+
}
|
|
55467
|
+
const item = found[0];
|
|
55468
|
+
return item;
|
|
55469
|
+
}
|
|
55470
|
+
async getSupportTable(payload) {
|
|
55471
|
+
const { symbol, kind } = payload;
|
|
55472
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
55473
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
55474
|
+
});
|
|
55475
|
+
if (found.length === 0) {
|
|
55476
|
+
return;
|
|
55477
|
+
}
|
|
55478
|
+
const item = found[0];
|
|
55479
|
+
return item;
|
|
55480
|
+
}
|
|
55481
|
+
async updateCompoundInstance(payload) {
|
|
55482
|
+
const { id, params } = payload;
|
|
55483
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
55484
|
+
}
|
|
55458
55485
|
}
|
|
55459
55486
|
|
|
55460
55487
|
// src/exchange-account.ts
|
|
@@ -57557,6 +57584,98 @@ function calculate_factor(payload) {
|
|
|
57557
57584
|
calculated_factor = to_f(calculated_factor, places);
|
|
57558
57585
|
return calculated_factor;
|
|
57559
57586
|
}
|
|
57587
|
+
function calculateFactorFromTakeProfit(payload) {
|
|
57588
|
+
const { long, short, knownTp, tpType, price_places = "%.4f" } = payload;
|
|
57589
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
57590
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
57591
|
+
const gapLoss = gap * max_quantity;
|
|
57592
|
+
if (gapLoss === 0) {
|
|
57593
|
+
return 0;
|
|
57594
|
+
}
|
|
57595
|
+
let factor;
|
|
57596
|
+
if (tpType === "long") {
|
|
57597
|
+
const longPercent = knownTp / long.entry - 1;
|
|
57598
|
+
factor = longPercent * short.entry * short.quantity / gapLoss;
|
|
57599
|
+
} else {
|
|
57600
|
+
const shortPercent = short.entry / knownTp - 1;
|
|
57601
|
+
factor = shortPercent * long.entry * long.quantity / gapLoss;
|
|
57602
|
+
}
|
|
57603
|
+
return to_f(factor, price_places);
|
|
57604
|
+
}
|
|
57605
|
+
function calculateFactorFromSellQuantity(payload) {
|
|
57606
|
+
const {
|
|
57607
|
+
long,
|
|
57608
|
+
short,
|
|
57609
|
+
knownSellQuantity,
|
|
57610
|
+
sellType,
|
|
57611
|
+
sell_factor = 1,
|
|
57612
|
+
price_places = "%.4f"
|
|
57613
|
+
} = payload;
|
|
57614
|
+
if (knownSellQuantity < 0.00001) {
|
|
57615
|
+
return 0;
|
|
57616
|
+
}
|
|
57617
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
57618
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
57619
|
+
const gapLoss = gap * max_quantity;
|
|
57620
|
+
if (gapLoss === 0) {
|
|
57621
|
+
return 0;
|
|
57622
|
+
}
|
|
57623
|
+
let low_factor = 0.001;
|
|
57624
|
+
let high_factor = 1;
|
|
57625
|
+
let best_factor = 0;
|
|
57626
|
+
let best_diff = Infinity;
|
|
57627
|
+
const tolerance = 0.00001;
|
|
57628
|
+
const max_iterations = 150;
|
|
57629
|
+
let expansions = 0;
|
|
57630
|
+
const max_expansions = 15;
|
|
57631
|
+
let iterations = 0;
|
|
57632
|
+
while (iterations < max_iterations) {
|
|
57633
|
+
iterations++;
|
|
57634
|
+
const mid_factor = (low_factor + high_factor) / 2;
|
|
57635
|
+
const testResult = generateGapTp({
|
|
57636
|
+
long,
|
|
57637
|
+
short,
|
|
57638
|
+
factor: mid_factor,
|
|
57639
|
+
sell_factor,
|
|
57640
|
+
price_places: "%.8f",
|
|
57641
|
+
decimal_places: "%.8f"
|
|
57642
|
+
});
|
|
57643
|
+
const testSellQty = sellType === "long" ? testResult.sell_quantity.long : testResult.sell_quantity.short;
|
|
57644
|
+
const diff = Math.abs(testSellQty - knownSellQuantity);
|
|
57645
|
+
if (diff < best_diff) {
|
|
57646
|
+
best_diff = diff;
|
|
57647
|
+
best_factor = mid_factor;
|
|
57648
|
+
}
|
|
57649
|
+
if (diff < tolerance) {
|
|
57650
|
+
return to_f(mid_factor, price_places);
|
|
57651
|
+
}
|
|
57652
|
+
if (testSellQty < knownSellQuantity) {
|
|
57653
|
+
low_factor = mid_factor;
|
|
57654
|
+
if (mid_factor > high_factor * 0.9 && expansions < max_expansions) {
|
|
57655
|
+
const ratio = knownSellQuantity / testSellQty;
|
|
57656
|
+
if (ratio > 2) {
|
|
57657
|
+
high_factor = high_factor * Math.min(ratio, 10);
|
|
57658
|
+
} else {
|
|
57659
|
+
high_factor = high_factor * 2;
|
|
57660
|
+
}
|
|
57661
|
+
expansions++;
|
|
57662
|
+
continue;
|
|
57663
|
+
}
|
|
57664
|
+
} else {
|
|
57665
|
+
high_factor = mid_factor;
|
|
57666
|
+
}
|
|
57667
|
+
if (Math.abs(high_factor - low_factor) < 0.00001 && diff > tolerance) {
|
|
57668
|
+
if (testSellQty < knownSellQuantity && expansions < max_expansions) {
|
|
57669
|
+
high_factor = high_factor * 1.1;
|
|
57670
|
+
expansions++;
|
|
57671
|
+
continue;
|
|
57672
|
+
} else {
|
|
57673
|
+
break;
|
|
57674
|
+
}
|
|
57675
|
+
}
|
|
57676
|
+
}
|
|
57677
|
+
return to_f(best_factor, price_places);
|
|
57678
|
+
}
|
|
57560
57679
|
function determineRewardFactor(payload) {
|
|
57561
57680
|
const { quantity, avg_qty, minimum_pnl, risk } = payload;
|
|
57562
57681
|
const reward_factor = minimum_pnl / risk;
|
|
@@ -60730,7 +60849,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
60730
60849
|
// src/position.ts
|
|
60731
60850
|
var import_https_proxy_agent2 = __toESM(require_dist2(), 1);
|
|
60732
60851
|
var import_socks_proxy_agent2 = __toESM(require_dist3(), 1);
|
|
60733
|
-
|
|
60734
60852
|
class ExchangePosition {
|
|
60735
60853
|
exchange;
|
|
60736
60854
|
symbol_config;
|
|
@@ -61775,6 +61893,53 @@ class ExchangePosition {
|
|
|
61775
61893
|
increase: false
|
|
61776
61894
|
});
|
|
61777
61895
|
}
|
|
61896
|
+
async isActiveTrade() {
|
|
61897
|
+
const config2 = await this.getConfig();
|
|
61898
|
+
const supportTable = await this.app_db.getSupportTable({
|
|
61899
|
+
symbol: this.symbol,
|
|
61900
|
+
kind: this.kind
|
|
61901
|
+
});
|
|
61902
|
+
return {
|
|
61903
|
+
config: config2,
|
|
61904
|
+
condition: supportTable?.price === config2.stop,
|
|
61905
|
+
supportTable
|
|
61906
|
+
};
|
|
61907
|
+
}
|
|
61908
|
+
async updateCompound(payload) {
|
|
61909
|
+
const pb = this.app_db.pb;
|
|
61910
|
+
const item = await this.app_db.getCompoundInstance({
|
|
61911
|
+
position: this.instance
|
|
61912
|
+
});
|
|
61913
|
+
const {
|
|
61914
|
+
expand: { ref }
|
|
61915
|
+
} = item;
|
|
61916
|
+
const risk = item.risk;
|
|
61917
|
+
const percent = ref.profit_percent / 100;
|
|
61918
|
+
const new_risk = risk * (1 + percent);
|
|
61919
|
+
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
61920
|
+
if (payload?.place && condition) {
|
|
61921
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
61922
|
+
risk: new_risk
|
|
61923
|
+
});
|
|
61924
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
61925
|
+
profit: to_f(new_risk * percent, "%.3f")
|
|
61926
|
+
});
|
|
61927
|
+
}
|
|
61928
|
+
return {
|
|
61929
|
+
support: supportTable.price,
|
|
61930
|
+
counter: supportTable.counter,
|
|
61931
|
+
new_risk
|
|
61932
|
+
};
|
|
61933
|
+
}
|
|
61934
|
+
async cleanOnActiveCompoundInstance() {
|
|
61935
|
+
const item = await this.app_db.getCompoundInstance({
|
|
61936
|
+
position: this.instance
|
|
61937
|
+
});
|
|
61938
|
+
const { condition } = await this.isActiveTrade();
|
|
61939
|
+
if (item && condition && this.instance.quantity === 0) {
|
|
61940
|
+
await this.cancelOrders({ limit: true });
|
|
61941
|
+
}
|
|
61942
|
+
}
|
|
61778
61943
|
}
|
|
61779
61944
|
function convert_to_exchange_order(order) {
|
|
61780
61945
|
return {
|
|
@@ -64060,6 +64225,8 @@ export {
|
|
|
64060
64225
|
constructAppConfig,
|
|
64061
64226
|
computeRiskReward,
|
|
64062
64227
|
computeProfitDetail,
|
|
64228
|
+
calculateFactorFromTakeProfit,
|
|
64229
|
+
calculateFactorFromSellQuantity,
|
|
64063
64230
|
buildConfig,
|
|
64064
64231
|
buildAvg,
|
|
64065
64232
|
buildAppConfig,
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -62211,6 +62211,33 @@ class AppDatabase {
|
|
|
62211
62211
|
parent: config_id
|
|
62212
62212
|
});
|
|
62213
62213
|
}
|
|
62214
|
+
async getCompoundInstance(payload) {
|
|
62215
|
+
const { position } = payload;
|
|
62216
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
62217
|
+
filter: `position.id = "${position.id}"`,
|
|
62218
|
+
expand: `ref`
|
|
62219
|
+
});
|
|
62220
|
+
if (found.length == 0) {
|
|
62221
|
+
return;
|
|
62222
|
+
}
|
|
62223
|
+
const item = found[0];
|
|
62224
|
+
return item;
|
|
62225
|
+
}
|
|
62226
|
+
async getSupportTable(payload) {
|
|
62227
|
+
const { symbol, kind } = payload;
|
|
62228
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
62229
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
62230
|
+
});
|
|
62231
|
+
if (found.length === 0) {
|
|
62232
|
+
return;
|
|
62233
|
+
}
|
|
62234
|
+
const item = found[0];
|
|
62235
|
+
return item;
|
|
62236
|
+
}
|
|
62237
|
+
async updateCompoundInstance(payload) {
|
|
62238
|
+
const { id, params } = payload;
|
|
62239
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
62240
|
+
}
|
|
62214
62241
|
}
|
|
62215
62242
|
|
|
62216
62243
|
// src/exchanges/binance/index.ts
|
|
@@ -67460,7 +67487,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
67460
67487
|
// src/position.ts
|
|
67461
67488
|
var import_https_proxy_agent2 = __toESM(require_dist2());
|
|
67462
67489
|
var import_socks_proxy_agent2 = __toESM(require_dist3());
|
|
67463
|
-
|
|
67464
67490
|
class ExchangePosition {
|
|
67465
67491
|
exchange;
|
|
67466
67492
|
symbol_config;
|
|
@@ -68505,6 +68531,53 @@ class ExchangePosition {
|
|
|
68505
68531
|
increase: false
|
|
68506
68532
|
});
|
|
68507
68533
|
}
|
|
68534
|
+
async isActiveTrade() {
|
|
68535
|
+
const config2 = await this.getConfig();
|
|
68536
|
+
const supportTable = await this.app_db.getSupportTable({
|
|
68537
|
+
symbol: this.symbol,
|
|
68538
|
+
kind: this.kind
|
|
68539
|
+
});
|
|
68540
|
+
return {
|
|
68541
|
+
config: config2,
|
|
68542
|
+
condition: supportTable?.price === config2.stop,
|
|
68543
|
+
supportTable
|
|
68544
|
+
};
|
|
68545
|
+
}
|
|
68546
|
+
async updateCompound(payload) {
|
|
68547
|
+
const pb = this.app_db.pb;
|
|
68548
|
+
const item = await this.app_db.getCompoundInstance({
|
|
68549
|
+
position: this.instance
|
|
68550
|
+
});
|
|
68551
|
+
const {
|
|
68552
|
+
expand: { ref }
|
|
68553
|
+
} = item;
|
|
68554
|
+
const risk = item.risk;
|
|
68555
|
+
const percent = ref.profit_percent / 100;
|
|
68556
|
+
const new_risk = risk * (1 + percent);
|
|
68557
|
+
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
68558
|
+
if (payload?.place && condition) {
|
|
68559
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
68560
|
+
risk: new_risk
|
|
68561
|
+
});
|
|
68562
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68563
|
+
profit: to_f(new_risk * percent, "%.3f")
|
|
68564
|
+
});
|
|
68565
|
+
}
|
|
68566
|
+
return {
|
|
68567
|
+
support: supportTable.price,
|
|
68568
|
+
counter: supportTable.counter,
|
|
68569
|
+
new_risk
|
|
68570
|
+
};
|
|
68571
|
+
}
|
|
68572
|
+
async cleanOnActiveCompoundInstance() {
|
|
68573
|
+
const item = await this.app_db.getCompoundInstance({
|
|
68574
|
+
position: this.instance
|
|
68575
|
+
});
|
|
68576
|
+
const { condition } = await this.isActiveTrade();
|
|
68577
|
+
if (item && condition && this.instance.quantity === 0) {
|
|
68578
|
+
await this.cancelOrders({ limit: true });
|
|
68579
|
+
}
|
|
68580
|
+
}
|
|
68508
68581
|
}
|
|
68509
68582
|
function convert_to_exchange_order(order) {
|
|
68510
68583
|
return {
|
package/dist/mcp-server.js
CHANGED
|
@@ -62184,6 +62184,33 @@ class AppDatabase {
|
|
|
62184
62184
|
parent: config_id
|
|
62185
62185
|
});
|
|
62186
62186
|
}
|
|
62187
|
+
async getCompoundInstance(payload) {
|
|
62188
|
+
const { position } = payload;
|
|
62189
|
+
const found = await this.pb.collection("compound_instances").getFullList({
|
|
62190
|
+
filter: `position.id = "${position.id}"`,
|
|
62191
|
+
expand: `ref`
|
|
62192
|
+
});
|
|
62193
|
+
if (found.length == 0) {
|
|
62194
|
+
return;
|
|
62195
|
+
}
|
|
62196
|
+
const item = found[0];
|
|
62197
|
+
return item;
|
|
62198
|
+
}
|
|
62199
|
+
async getSupportTable(payload) {
|
|
62200
|
+
const { symbol, kind } = payload;
|
|
62201
|
+
const found = await this.pb.collection("support_table").getFullList({
|
|
62202
|
+
filter: `symbol = "${symbol}" && kind = "${kind}"`
|
|
62203
|
+
});
|
|
62204
|
+
if (found.length === 0) {
|
|
62205
|
+
return;
|
|
62206
|
+
}
|
|
62207
|
+
const item = found[0];
|
|
62208
|
+
return item;
|
|
62209
|
+
}
|
|
62210
|
+
async updateCompoundInstance(payload) {
|
|
62211
|
+
const { id, params } = payload;
|
|
62212
|
+
return await this.pb.collection("compound_instances").update(id, params);
|
|
62213
|
+
}
|
|
62187
62214
|
}
|
|
62188
62215
|
|
|
62189
62216
|
// src/exchanges/binance/index.ts
|
|
@@ -67433,7 +67460,6 @@ async function reduceMajorPositionEntry(input, accountInfo, trigger2, exchange_i
|
|
|
67433
67460
|
// src/position.ts
|
|
67434
67461
|
var import_https_proxy_agent2 = __toESM(require_dist2(), 1);
|
|
67435
67462
|
var import_socks_proxy_agent2 = __toESM(require_dist3(), 1);
|
|
67436
|
-
|
|
67437
67463
|
class ExchangePosition {
|
|
67438
67464
|
exchange;
|
|
67439
67465
|
symbol_config;
|
|
@@ -68478,6 +68504,53 @@ class ExchangePosition {
|
|
|
68478
68504
|
increase: false
|
|
68479
68505
|
});
|
|
68480
68506
|
}
|
|
68507
|
+
async isActiveTrade() {
|
|
68508
|
+
const config2 = await this.getConfig();
|
|
68509
|
+
const supportTable = await this.app_db.getSupportTable({
|
|
68510
|
+
symbol: this.symbol,
|
|
68511
|
+
kind: this.kind
|
|
68512
|
+
});
|
|
68513
|
+
return {
|
|
68514
|
+
config: config2,
|
|
68515
|
+
condition: supportTable?.price === config2.stop,
|
|
68516
|
+
supportTable
|
|
68517
|
+
};
|
|
68518
|
+
}
|
|
68519
|
+
async updateCompound(payload) {
|
|
68520
|
+
const pb = this.app_db.pb;
|
|
68521
|
+
const item = await this.app_db.getCompoundInstance({
|
|
68522
|
+
position: this.instance
|
|
68523
|
+
});
|
|
68524
|
+
const {
|
|
68525
|
+
expand: { ref }
|
|
68526
|
+
} = item;
|
|
68527
|
+
const risk = item.risk;
|
|
68528
|
+
const percent = ref.profit_percent / 100;
|
|
68529
|
+
const new_risk = risk * (1 + percent);
|
|
68530
|
+
const { condition, supportTable, config: config2 } = await this.isActiveTrade();
|
|
68531
|
+
if (payload?.place && condition) {
|
|
68532
|
+
await pb.collection("compound_instances").update(item.id, {
|
|
68533
|
+
risk: new_risk
|
|
68534
|
+
});
|
|
68535
|
+
await pb.collection("scheduled_trades").update(config2.id, {
|
|
68536
|
+
profit: to_f(new_risk * percent, "%.3f")
|
|
68537
|
+
});
|
|
68538
|
+
}
|
|
68539
|
+
return {
|
|
68540
|
+
support: supportTable.price,
|
|
68541
|
+
counter: supportTable.counter,
|
|
68542
|
+
new_risk
|
|
68543
|
+
};
|
|
68544
|
+
}
|
|
68545
|
+
async cleanOnActiveCompoundInstance() {
|
|
68546
|
+
const item = await this.app_db.getCompoundInstance({
|
|
68547
|
+
position: this.instance
|
|
68548
|
+
});
|
|
68549
|
+
const { condition } = await this.isActiveTrade();
|
|
68550
|
+
if (item && condition && this.instance.quantity === 0) {
|
|
68551
|
+
await this.cancelOrders({ limit: true });
|
|
68552
|
+
}
|
|
68553
|
+
}
|
|
68481
68554
|
}
|
|
68482
68555
|
function convert_to_exchange_order(order) {
|
|
68483
68556
|
return {
|