@gbozee/ultimate 0.0.2-101 → 0.0.2-102
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 +9 -3
- package/dist/frontend-index.js +64 -15
- package/dist/index.cjs +64 -15
- package/dist/index.d.ts +9 -3
- package/dist/index.js +64 -15
- package/dist/mcp-server.cjs +64 -15
- package/dist/mcp-server.js +64 -15
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -450,6 +450,8 @@ export declare function generateGapTp(payload: {
|
|
|
450
450
|
entry: number;
|
|
451
451
|
quantity: number;
|
|
452
452
|
};
|
|
453
|
+
risk?: number;
|
|
454
|
+
kind?: "long" | "short";
|
|
453
455
|
factor?: number;
|
|
454
456
|
sell_factor?: number;
|
|
455
457
|
price_places?: string;
|
|
@@ -671,6 +673,8 @@ export declare class Strategy {
|
|
|
671
673
|
identifyGapConfig(payload: {
|
|
672
674
|
factor?: number;
|
|
673
675
|
sell_factor?: number;
|
|
676
|
+
kind?: "long" | "short";
|
|
677
|
+
risk?: number;
|
|
674
678
|
}): {
|
|
675
679
|
profit_percent: {
|
|
676
680
|
long: number;
|
|
@@ -717,8 +721,11 @@ export declare class Strategy {
|
|
|
717
721
|
decimal_places: string;
|
|
718
722
|
};
|
|
719
723
|
simulateGapReduction(payload: {
|
|
720
|
-
|
|
721
|
-
|
|
724
|
+
iterations?: number;
|
|
725
|
+
factor?: number;
|
|
726
|
+
direction: "long" | "short";
|
|
727
|
+
kind?: "long" | "short";
|
|
728
|
+
risk?: number;
|
|
722
729
|
sell_factor?: number;
|
|
723
730
|
}): {
|
|
724
731
|
results: {
|
|
@@ -751,7 +758,6 @@ export declare class Strategy {
|
|
|
751
758
|
};
|
|
752
759
|
}[];
|
|
753
760
|
quantity: number;
|
|
754
|
-
counter: number;
|
|
755
761
|
};
|
|
756
762
|
}
|
|
757
763
|
|
package/dist/frontend-index.js
CHANGED
|
@@ -1809,11 +1809,26 @@ function generateGapTp(payload) {
|
|
|
1809
1809
|
const {
|
|
1810
1810
|
long,
|
|
1811
1811
|
short,
|
|
1812
|
-
factor =
|
|
1812
|
+
factor: factor_value = 0,
|
|
1813
|
+
risk: desired_risk,
|
|
1813
1814
|
sell_factor = 1,
|
|
1815
|
+
kind,
|
|
1814
1816
|
price_places = "%.1f",
|
|
1815
1817
|
decimal_places = "%.3f"
|
|
1816
1818
|
} = payload;
|
|
1819
|
+
if (!factor_value && !desired_risk) {
|
|
1820
|
+
throw new Error("Either factor or risk must be provided");
|
|
1821
|
+
}
|
|
1822
|
+
if (desired_risk && !kind) {
|
|
1823
|
+
throw new Error("Kind must be provided when risk is provided");
|
|
1824
|
+
}
|
|
1825
|
+
let factor = factor_value || calculate_factor({
|
|
1826
|
+
long,
|
|
1827
|
+
short,
|
|
1828
|
+
risk: desired_risk,
|
|
1829
|
+
kind,
|
|
1830
|
+
sell_factor
|
|
1831
|
+
});
|
|
1817
1832
|
const gap = Math.abs(long.entry - short.entry);
|
|
1818
1833
|
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
1819
1834
|
const gapLoss = gap * max_quantity;
|
|
@@ -1826,7 +1841,7 @@ function generateGapTp(payload) {
|
|
|
1826
1841
|
const actualShortReduce = to_f(shortToReduce * sell_factor, "%.1f");
|
|
1827
1842
|
const actualLongReduce = to_f(longToReduce * sell_factor, "%.1f");
|
|
1828
1843
|
const short_quantity_to_sell = determine_amount_to_sell2(short.entry, short.quantity, longTp, actualShortReduce, "short", decimal_places);
|
|
1829
|
-
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp,
|
|
1844
|
+
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp, actualLongReduce, "long", decimal_places);
|
|
1830
1845
|
const risk_amount_short = to_f(shortToReduce - actualShortReduce, "%.2f");
|
|
1831
1846
|
const risk_amount_long = to_f(longToReduce - actualLongReduce, "%.2f");
|
|
1832
1847
|
const profit_percent_long = to_f(shortToReduce * 100 / (long.entry * long.quantity), "%.4f");
|
|
@@ -1860,6 +1875,32 @@ function generateGapTp(payload) {
|
|
|
1860
1875
|
gap_loss: to_f(gapLoss, "%.2f")
|
|
1861
1876
|
};
|
|
1862
1877
|
}
|
|
1878
|
+
function calculate_factor(payload) {
|
|
1879
|
+
const {
|
|
1880
|
+
long,
|
|
1881
|
+
short,
|
|
1882
|
+
risk: desired_risk,
|
|
1883
|
+
kind,
|
|
1884
|
+
sell_factor,
|
|
1885
|
+
places = "%.4f"
|
|
1886
|
+
} = payload;
|
|
1887
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
1888
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
1889
|
+
const gapLoss = gap * max_quantity;
|
|
1890
|
+
let calculated_factor;
|
|
1891
|
+
const long_notional = long.entry * long.quantity;
|
|
1892
|
+
const short_notional = short.entry * short.quantity;
|
|
1893
|
+
const target_to_reduce = desired_risk / (1 - sell_factor);
|
|
1894
|
+
if (kind === "short") {
|
|
1895
|
+
const calculate_longPercent = target_to_reduce / long_notional;
|
|
1896
|
+
calculated_factor = calculate_longPercent * short_notional / gapLoss;
|
|
1897
|
+
} else {
|
|
1898
|
+
const calculated_shortPercent = target_to_reduce / (short_notional - target_to_reduce);
|
|
1899
|
+
calculated_factor = calculated_shortPercent * long_notional / gapLoss;
|
|
1900
|
+
}
|
|
1901
|
+
calculated_factor = to_f(calculated_factor, places);
|
|
1902
|
+
return calculated_factor;
|
|
1903
|
+
}
|
|
1863
1904
|
// src/helpers/strategy.ts
|
|
1864
1905
|
class Strategy {
|
|
1865
1906
|
position;
|
|
@@ -2262,12 +2303,14 @@ class Strategy {
|
|
|
2262
2303
|
return { ...app_config, avg, loss: -expected_loss, profit_percent };
|
|
2263
2304
|
}
|
|
2264
2305
|
identifyGapConfig(payload) {
|
|
2265
|
-
const { factor = 1,
|
|
2306
|
+
const { factor, sell_factor = 1, kind, risk } = payload;
|
|
2266
2307
|
return generateGapTp({
|
|
2267
2308
|
long: this.position.long,
|
|
2268
2309
|
short: this.position.short,
|
|
2269
2310
|
factor,
|
|
2270
2311
|
sell_factor,
|
|
2312
|
+
kind,
|
|
2313
|
+
risk,
|
|
2271
2314
|
decimal_places: this.config.global_config.decimal_places,
|
|
2272
2315
|
price_places: this.config.global_config.price_places
|
|
2273
2316
|
});
|
|
@@ -2292,19 +2335,27 @@ class Strategy {
|
|
|
2292
2335
|
return result;
|
|
2293
2336
|
}
|
|
2294
2337
|
simulateGapReduction(payload) {
|
|
2295
|
-
const {
|
|
2338
|
+
const {
|
|
2339
|
+
factor,
|
|
2340
|
+
direction,
|
|
2341
|
+
sell_factor = 1,
|
|
2342
|
+
iterations = 10,
|
|
2343
|
+
risk: desired_risk,
|
|
2344
|
+
kind
|
|
2345
|
+
} = payload;
|
|
2296
2346
|
const results = [];
|
|
2297
2347
|
let params = {
|
|
2298
2348
|
long: this.position.long,
|
|
2299
2349
|
short: this.position.short,
|
|
2300
2350
|
config: this.config
|
|
2301
2351
|
};
|
|
2302
|
-
let
|
|
2303
|
-
while (true) {
|
|
2352
|
+
for (let i = 0;i < iterations; i++) {
|
|
2304
2353
|
const instance = new Strategy(params);
|
|
2305
2354
|
const { profit_percent, risk, take_profit, sell_quantity, gap_loss } = instance.identifyGapConfig({
|
|
2306
2355
|
factor,
|
|
2307
|
-
sell_factor
|
|
2356
|
+
sell_factor,
|
|
2357
|
+
kind,
|
|
2358
|
+
risk: desired_risk
|
|
2308
2359
|
});
|
|
2309
2360
|
const to_add = {
|
|
2310
2361
|
profit_percent,
|
|
@@ -2324,26 +2375,24 @@ class Strategy {
|
|
|
2324
2375
|
}
|
|
2325
2376
|
};
|
|
2326
2377
|
results.push(to_add);
|
|
2327
|
-
const sell_kind =
|
|
2378
|
+
const sell_kind = direction == "long" ? "short" : "long";
|
|
2328
2379
|
const remaining = this.to_df(params[sell_kind].quantity - sell_quantity[sell_kind]);
|
|
2329
2380
|
if (remaining <= 0) {
|
|
2330
2381
|
break;
|
|
2331
2382
|
}
|
|
2332
2383
|
params[sell_kind].quantity = remaining;
|
|
2333
|
-
params[
|
|
2334
|
-
entry: take_profit[
|
|
2384
|
+
params[direction] = {
|
|
2385
|
+
entry: take_profit[direction],
|
|
2335
2386
|
quantity: remaining
|
|
2336
2387
|
};
|
|
2337
|
-
counter++;
|
|
2338
2388
|
}
|
|
2339
2389
|
const last_gap_loss = results.at(-1)?.gap_loss;
|
|
2340
|
-
const last_tp = results.at(-1)?.take_profit[
|
|
2341
|
-
const entry = this.position[
|
|
2390
|
+
const last_tp = results.at(-1)?.take_profit[direction];
|
|
2391
|
+
const entry = this.position[direction].entry;
|
|
2342
2392
|
const quantity = this.to_df(Math.abs(last_tp - entry) / last_gap_loss);
|
|
2343
2393
|
return {
|
|
2344
2394
|
results,
|
|
2345
|
-
quantity
|
|
2346
|
-
counter
|
|
2395
|
+
quantity
|
|
2347
2396
|
};
|
|
2348
2397
|
}
|
|
2349
2398
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -53820,11 +53820,26 @@ function generateGapTp(payload) {
|
|
|
53820
53820
|
const {
|
|
53821
53821
|
long,
|
|
53822
53822
|
short,
|
|
53823
|
-
factor =
|
|
53823
|
+
factor: factor_value = 0,
|
|
53824
|
+
risk: desired_risk,
|
|
53824
53825
|
sell_factor = 1,
|
|
53826
|
+
kind,
|
|
53825
53827
|
price_places = "%.1f",
|
|
53826
53828
|
decimal_places = "%.3f"
|
|
53827
53829
|
} = payload;
|
|
53830
|
+
if (!factor_value && !desired_risk) {
|
|
53831
|
+
throw new Error("Either factor or risk must be provided");
|
|
53832
|
+
}
|
|
53833
|
+
if (desired_risk && !kind) {
|
|
53834
|
+
throw new Error("Kind must be provided when risk is provided");
|
|
53835
|
+
}
|
|
53836
|
+
let factor = factor_value || calculate_factor({
|
|
53837
|
+
long,
|
|
53838
|
+
short,
|
|
53839
|
+
risk: desired_risk,
|
|
53840
|
+
kind,
|
|
53841
|
+
sell_factor
|
|
53842
|
+
});
|
|
53828
53843
|
const gap = Math.abs(long.entry - short.entry);
|
|
53829
53844
|
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
53830
53845
|
const gapLoss = gap * max_quantity;
|
|
@@ -53837,7 +53852,7 @@ function generateGapTp(payload) {
|
|
|
53837
53852
|
const actualShortReduce = to_f2(shortToReduce * sell_factor, "%.1f");
|
|
53838
53853
|
const actualLongReduce = to_f2(longToReduce * sell_factor, "%.1f");
|
|
53839
53854
|
const short_quantity_to_sell = determine_amount_to_sell2(short.entry, short.quantity, longTp, actualShortReduce, "short", decimal_places);
|
|
53840
|
-
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp,
|
|
53855
|
+
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp, actualLongReduce, "long", decimal_places);
|
|
53841
53856
|
const risk_amount_short = to_f2(shortToReduce - actualShortReduce, "%.2f");
|
|
53842
53857
|
const risk_amount_long = to_f2(longToReduce - actualLongReduce, "%.2f");
|
|
53843
53858
|
const profit_percent_long = to_f2(shortToReduce * 100 / (long.entry * long.quantity), "%.4f");
|
|
@@ -53871,6 +53886,32 @@ function generateGapTp(payload) {
|
|
|
53871
53886
|
gap_loss: to_f2(gapLoss, "%.2f")
|
|
53872
53887
|
};
|
|
53873
53888
|
}
|
|
53889
|
+
function calculate_factor(payload) {
|
|
53890
|
+
const {
|
|
53891
|
+
long,
|
|
53892
|
+
short,
|
|
53893
|
+
risk: desired_risk,
|
|
53894
|
+
kind,
|
|
53895
|
+
sell_factor,
|
|
53896
|
+
places = "%.4f"
|
|
53897
|
+
} = payload;
|
|
53898
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
53899
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
53900
|
+
const gapLoss = gap * max_quantity;
|
|
53901
|
+
let calculated_factor;
|
|
53902
|
+
const long_notional = long.entry * long.quantity;
|
|
53903
|
+
const short_notional = short.entry * short.quantity;
|
|
53904
|
+
const target_to_reduce = desired_risk / (1 - sell_factor);
|
|
53905
|
+
if (kind === "short") {
|
|
53906
|
+
const calculate_longPercent = target_to_reduce / long_notional;
|
|
53907
|
+
calculated_factor = calculate_longPercent * short_notional / gapLoss;
|
|
53908
|
+
} else {
|
|
53909
|
+
const calculated_shortPercent = target_to_reduce / (short_notional - target_to_reduce);
|
|
53910
|
+
calculated_factor = calculated_shortPercent * long_notional / gapLoss;
|
|
53911
|
+
}
|
|
53912
|
+
calculated_factor = to_f2(calculated_factor, places);
|
|
53913
|
+
return calculated_factor;
|
|
53914
|
+
}
|
|
53874
53915
|
|
|
53875
53916
|
// src/helpers/strategy.ts
|
|
53876
53917
|
class Strategy {
|
|
@@ -54274,12 +54315,14 @@ class Strategy {
|
|
|
54274
54315
|
return { ...app_config, avg, loss: -expected_loss, profit_percent };
|
|
54275
54316
|
}
|
|
54276
54317
|
identifyGapConfig(payload) {
|
|
54277
|
-
const { factor = 1,
|
|
54318
|
+
const { factor, sell_factor = 1, kind, risk } = payload;
|
|
54278
54319
|
return generateGapTp({
|
|
54279
54320
|
long: this.position.long,
|
|
54280
54321
|
short: this.position.short,
|
|
54281
54322
|
factor,
|
|
54282
54323
|
sell_factor,
|
|
54324
|
+
kind,
|
|
54325
|
+
risk,
|
|
54283
54326
|
decimal_places: this.config.global_config.decimal_places,
|
|
54284
54327
|
price_places: this.config.global_config.price_places
|
|
54285
54328
|
});
|
|
@@ -54304,19 +54347,27 @@ class Strategy {
|
|
|
54304
54347
|
return result;
|
|
54305
54348
|
}
|
|
54306
54349
|
simulateGapReduction(payload) {
|
|
54307
|
-
const {
|
|
54350
|
+
const {
|
|
54351
|
+
factor,
|
|
54352
|
+
direction,
|
|
54353
|
+
sell_factor = 1,
|
|
54354
|
+
iterations = 10,
|
|
54355
|
+
risk: desired_risk,
|
|
54356
|
+
kind
|
|
54357
|
+
} = payload;
|
|
54308
54358
|
const results = [];
|
|
54309
54359
|
let params = {
|
|
54310
54360
|
long: this.position.long,
|
|
54311
54361
|
short: this.position.short,
|
|
54312
54362
|
config: this.config
|
|
54313
54363
|
};
|
|
54314
|
-
let
|
|
54315
|
-
while (true) {
|
|
54364
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
54316
54365
|
const instance = new Strategy(params);
|
|
54317
54366
|
const { profit_percent, risk, take_profit, sell_quantity, gap_loss } = instance.identifyGapConfig({
|
|
54318
54367
|
factor,
|
|
54319
|
-
sell_factor
|
|
54368
|
+
sell_factor,
|
|
54369
|
+
kind,
|
|
54370
|
+
risk: desired_risk
|
|
54320
54371
|
});
|
|
54321
54372
|
const to_add = {
|
|
54322
54373
|
profit_percent,
|
|
@@ -54336,26 +54387,24 @@ class Strategy {
|
|
|
54336
54387
|
}
|
|
54337
54388
|
};
|
|
54338
54389
|
results.push(to_add);
|
|
54339
|
-
const sell_kind =
|
|
54390
|
+
const sell_kind = direction == "long" ? "short" : "long";
|
|
54340
54391
|
const remaining = this.to_df(params[sell_kind].quantity - sell_quantity[sell_kind]);
|
|
54341
54392
|
if (remaining <= 0) {
|
|
54342
54393
|
break;
|
|
54343
54394
|
}
|
|
54344
54395
|
params[sell_kind].quantity = remaining;
|
|
54345
|
-
params[
|
|
54346
|
-
entry: take_profit[
|
|
54396
|
+
params[direction] = {
|
|
54397
|
+
entry: take_profit[direction],
|
|
54347
54398
|
quantity: remaining
|
|
54348
54399
|
};
|
|
54349
|
-
counter++;
|
|
54350
54400
|
}
|
|
54351
54401
|
const last_gap_loss = results.at(-1)?.gap_loss;
|
|
54352
|
-
const last_tp = results.at(-1)?.take_profit[
|
|
54353
|
-
const entry = this.position[
|
|
54402
|
+
const last_tp = results.at(-1)?.take_profit[direction];
|
|
54403
|
+
const entry = this.position[direction].entry;
|
|
54354
54404
|
const quantity = this.to_df(Math.abs(last_tp - entry) / last_gap_loss);
|
|
54355
54405
|
return {
|
|
54356
54406
|
results,
|
|
54357
|
-
quantity
|
|
54358
|
-
counter
|
|
54407
|
+
quantity
|
|
54359
54408
|
};
|
|
54360
54409
|
}
|
|
54361
54410
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -760,6 +760,8 @@ export declare class Strategy {
|
|
|
760
760
|
identifyGapConfig(payload: {
|
|
761
761
|
factor?: number;
|
|
762
762
|
sell_factor?: number;
|
|
763
|
+
kind?: "long" | "short";
|
|
764
|
+
risk?: number;
|
|
763
765
|
}): {
|
|
764
766
|
profit_percent: {
|
|
765
767
|
long: number;
|
|
@@ -806,8 +808,11 @@ export declare class Strategy {
|
|
|
806
808
|
decimal_places: string;
|
|
807
809
|
};
|
|
808
810
|
simulateGapReduction(payload: {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
+
iterations?: number;
|
|
812
|
+
factor?: number;
|
|
813
|
+
direction: "long" | "short";
|
|
814
|
+
kind?: "long" | "short";
|
|
815
|
+
risk?: number;
|
|
811
816
|
sell_factor?: number;
|
|
812
817
|
}): {
|
|
813
818
|
results: {
|
|
@@ -840,7 +845,6 @@ export declare class Strategy {
|
|
|
840
845
|
};
|
|
841
846
|
}[];
|
|
842
847
|
quantity: number;
|
|
843
|
-
counter: number;
|
|
844
848
|
};
|
|
845
849
|
}
|
|
846
850
|
export type SignalConfigType = {
|
|
@@ -1203,6 +1207,8 @@ export declare function generateGapTp(payload: {
|
|
|
1203
1207
|
entry: number;
|
|
1204
1208
|
quantity: number;
|
|
1205
1209
|
};
|
|
1210
|
+
risk?: number;
|
|
1211
|
+
kind?: "long" | "short";
|
|
1206
1212
|
factor?: number;
|
|
1207
1213
|
sell_factor?: number;
|
|
1208
1214
|
price_places?: string;
|
package/dist/index.js
CHANGED
|
@@ -53769,11 +53769,26 @@ function generateGapTp(payload) {
|
|
|
53769
53769
|
const {
|
|
53770
53770
|
long,
|
|
53771
53771
|
short,
|
|
53772
|
-
factor =
|
|
53772
|
+
factor: factor_value = 0,
|
|
53773
|
+
risk: desired_risk,
|
|
53773
53774
|
sell_factor = 1,
|
|
53775
|
+
kind,
|
|
53774
53776
|
price_places = "%.1f",
|
|
53775
53777
|
decimal_places = "%.3f"
|
|
53776
53778
|
} = payload;
|
|
53779
|
+
if (!factor_value && !desired_risk) {
|
|
53780
|
+
throw new Error("Either factor or risk must be provided");
|
|
53781
|
+
}
|
|
53782
|
+
if (desired_risk && !kind) {
|
|
53783
|
+
throw new Error("Kind must be provided when risk is provided");
|
|
53784
|
+
}
|
|
53785
|
+
let factor = factor_value || calculate_factor({
|
|
53786
|
+
long,
|
|
53787
|
+
short,
|
|
53788
|
+
risk: desired_risk,
|
|
53789
|
+
kind,
|
|
53790
|
+
sell_factor
|
|
53791
|
+
});
|
|
53777
53792
|
const gap = Math.abs(long.entry - short.entry);
|
|
53778
53793
|
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
53779
53794
|
const gapLoss = gap * max_quantity;
|
|
@@ -53786,7 +53801,7 @@ function generateGapTp(payload) {
|
|
|
53786
53801
|
const actualShortReduce = to_f2(shortToReduce * sell_factor, "%.1f");
|
|
53787
53802
|
const actualLongReduce = to_f2(longToReduce * sell_factor, "%.1f");
|
|
53788
53803
|
const short_quantity_to_sell = determine_amount_to_sell2(short.entry, short.quantity, longTp, actualShortReduce, "short", decimal_places);
|
|
53789
|
-
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp,
|
|
53804
|
+
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp, actualLongReduce, "long", decimal_places);
|
|
53790
53805
|
const risk_amount_short = to_f2(shortToReduce - actualShortReduce, "%.2f");
|
|
53791
53806
|
const risk_amount_long = to_f2(longToReduce - actualLongReduce, "%.2f");
|
|
53792
53807
|
const profit_percent_long = to_f2(shortToReduce * 100 / (long.entry * long.quantity), "%.4f");
|
|
@@ -53820,6 +53835,32 @@ function generateGapTp(payload) {
|
|
|
53820
53835
|
gap_loss: to_f2(gapLoss, "%.2f")
|
|
53821
53836
|
};
|
|
53822
53837
|
}
|
|
53838
|
+
function calculate_factor(payload) {
|
|
53839
|
+
const {
|
|
53840
|
+
long,
|
|
53841
|
+
short,
|
|
53842
|
+
risk: desired_risk,
|
|
53843
|
+
kind,
|
|
53844
|
+
sell_factor,
|
|
53845
|
+
places = "%.4f"
|
|
53846
|
+
} = payload;
|
|
53847
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
53848
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
53849
|
+
const gapLoss = gap * max_quantity;
|
|
53850
|
+
let calculated_factor;
|
|
53851
|
+
const long_notional = long.entry * long.quantity;
|
|
53852
|
+
const short_notional = short.entry * short.quantity;
|
|
53853
|
+
const target_to_reduce = desired_risk / (1 - sell_factor);
|
|
53854
|
+
if (kind === "short") {
|
|
53855
|
+
const calculate_longPercent = target_to_reduce / long_notional;
|
|
53856
|
+
calculated_factor = calculate_longPercent * short_notional / gapLoss;
|
|
53857
|
+
} else {
|
|
53858
|
+
const calculated_shortPercent = target_to_reduce / (short_notional - target_to_reduce);
|
|
53859
|
+
calculated_factor = calculated_shortPercent * long_notional / gapLoss;
|
|
53860
|
+
}
|
|
53861
|
+
calculated_factor = to_f2(calculated_factor, places);
|
|
53862
|
+
return calculated_factor;
|
|
53863
|
+
}
|
|
53823
53864
|
|
|
53824
53865
|
// src/helpers/strategy.ts
|
|
53825
53866
|
class Strategy {
|
|
@@ -54223,12 +54264,14 @@ class Strategy {
|
|
|
54223
54264
|
return { ...app_config, avg, loss: -expected_loss, profit_percent };
|
|
54224
54265
|
}
|
|
54225
54266
|
identifyGapConfig(payload) {
|
|
54226
|
-
const { factor = 1,
|
|
54267
|
+
const { factor, sell_factor = 1, kind, risk } = payload;
|
|
54227
54268
|
return generateGapTp({
|
|
54228
54269
|
long: this.position.long,
|
|
54229
54270
|
short: this.position.short,
|
|
54230
54271
|
factor,
|
|
54231
54272
|
sell_factor,
|
|
54273
|
+
kind,
|
|
54274
|
+
risk,
|
|
54232
54275
|
decimal_places: this.config.global_config.decimal_places,
|
|
54233
54276
|
price_places: this.config.global_config.price_places
|
|
54234
54277
|
});
|
|
@@ -54253,19 +54296,27 @@ class Strategy {
|
|
|
54253
54296
|
return result;
|
|
54254
54297
|
}
|
|
54255
54298
|
simulateGapReduction(payload) {
|
|
54256
|
-
const {
|
|
54299
|
+
const {
|
|
54300
|
+
factor,
|
|
54301
|
+
direction,
|
|
54302
|
+
sell_factor = 1,
|
|
54303
|
+
iterations = 10,
|
|
54304
|
+
risk: desired_risk,
|
|
54305
|
+
kind
|
|
54306
|
+
} = payload;
|
|
54257
54307
|
const results = [];
|
|
54258
54308
|
let params = {
|
|
54259
54309
|
long: this.position.long,
|
|
54260
54310
|
short: this.position.short,
|
|
54261
54311
|
config: this.config
|
|
54262
54312
|
};
|
|
54263
|
-
let
|
|
54264
|
-
while (true) {
|
|
54313
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
54265
54314
|
const instance = new Strategy(params);
|
|
54266
54315
|
const { profit_percent, risk, take_profit, sell_quantity, gap_loss } = instance.identifyGapConfig({
|
|
54267
54316
|
factor,
|
|
54268
|
-
sell_factor
|
|
54317
|
+
sell_factor,
|
|
54318
|
+
kind,
|
|
54319
|
+
risk: desired_risk
|
|
54269
54320
|
});
|
|
54270
54321
|
const to_add = {
|
|
54271
54322
|
profit_percent,
|
|
@@ -54285,26 +54336,24 @@ class Strategy {
|
|
|
54285
54336
|
}
|
|
54286
54337
|
};
|
|
54287
54338
|
results.push(to_add);
|
|
54288
|
-
const sell_kind =
|
|
54339
|
+
const sell_kind = direction == "long" ? "short" : "long";
|
|
54289
54340
|
const remaining = this.to_df(params[sell_kind].quantity - sell_quantity[sell_kind]);
|
|
54290
54341
|
if (remaining <= 0) {
|
|
54291
54342
|
break;
|
|
54292
54343
|
}
|
|
54293
54344
|
params[sell_kind].quantity = remaining;
|
|
54294
|
-
params[
|
|
54295
|
-
entry: take_profit[
|
|
54345
|
+
params[direction] = {
|
|
54346
|
+
entry: take_profit[direction],
|
|
54296
54347
|
quantity: remaining
|
|
54297
54348
|
};
|
|
54298
|
-
counter++;
|
|
54299
54349
|
}
|
|
54300
54350
|
const last_gap_loss = results.at(-1)?.gap_loss;
|
|
54301
|
-
const last_tp = results.at(-1)?.take_profit[
|
|
54302
|
-
const entry = this.position[
|
|
54351
|
+
const last_tp = results.at(-1)?.take_profit[direction];
|
|
54352
|
+
const entry = this.position[direction].entry;
|
|
54303
54353
|
const quantity = this.to_df(Math.abs(last_tp - entry) / last_gap_loss);
|
|
54304
54354
|
return {
|
|
54305
54355
|
results,
|
|
54306
|
-
quantity
|
|
54307
|
-
counter
|
|
54356
|
+
quantity
|
|
54308
54357
|
};
|
|
54309
54358
|
}
|
|
54310
54359
|
}
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -60507,11 +60507,26 @@ function generateGapTp(payload) {
|
|
|
60507
60507
|
const {
|
|
60508
60508
|
long,
|
|
60509
60509
|
short,
|
|
60510
|
-
factor =
|
|
60510
|
+
factor: factor_value = 0,
|
|
60511
|
+
risk: desired_risk,
|
|
60511
60512
|
sell_factor = 1,
|
|
60513
|
+
kind,
|
|
60512
60514
|
price_places = "%.1f",
|
|
60513
60515
|
decimal_places = "%.3f"
|
|
60514
60516
|
} = payload;
|
|
60517
|
+
if (!factor_value && !desired_risk) {
|
|
60518
|
+
throw new Error("Either factor or risk must be provided");
|
|
60519
|
+
}
|
|
60520
|
+
if (desired_risk && !kind) {
|
|
60521
|
+
throw new Error("Kind must be provided when risk is provided");
|
|
60522
|
+
}
|
|
60523
|
+
let factor = factor_value || calculate_factor({
|
|
60524
|
+
long,
|
|
60525
|
+
short,
|
|
60526
|
+
risk: desired_risk,
|
|
60527
|
+
kind,
|
|
60528
|
+
sell_factor
|
|
60529
|
+
});
|
|
60515
60530
|
const gap = Math.abs(long.entry - short.entry);
|
|
60516
60531
|
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
60517
60532
|
const gapLoss = gap * max_quantity;
|
|
@@ -60524,7 +60539,7 @@ function generateGapTp(payload) {
|
|
|
60524
60539
|
const actualShortReduce = to_f2(shortToReduce * sell_factor, "%.1f");
|
|
60525
60540
|
const actualLongReduce = to_f2(longToReduce * sell_factor, "%.1f");
|
|
60526
60541
|
const short_quantity_to_sell = determine_amount_to_sell2(short.entry, short.quantity, longTp, actualShortReduce, "short", decimal_places);
|
|
60527
|
-
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp,
|
|
60542
|
+
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp, actualLongReduce, "long", decimal_places);
|
|
60528
60543
|
const risk_amount_short = to_f2(shortToReduce - actualShortReduce, "%.2f");
|
|
60529
60544
|
const risk_amount_long = to_f2(longToReduce - actualLongReduce, "%.2f");
|
|
60530
60545
|
const profit_percent_long = to_f2(shortToReduce * 100 / (long.entry * long.quantity), "%.4f");
|
|
@@ -60558,6 +60573,32 @@ function generateGapTp(payload) {
|
|
|
60558
60573
|
gap_loss: to_f2(gapLoss, "%.2f")
|
|
60559
60574
|
};
|
|
60560
60575
|
}
|
|
60576
|
+
function calculate_factor(payload) {
|
|
60577
|
+
const {
|
|
60578
|
+
long,
|
|
60579
|
+
short,
|
|
60580
|
+
risk: desired_risk,
|
|
60581
|
+
kind,
|
|
60582
|
+
sell_factor,
|
|
60583
|
+
places = "%.4f"
|
|
60584
|
+
} = payload;
|
|
60585
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
60586
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
60587
|
+
const gapLoss = gap * max_quantity;
|
|
60588
|
+
let calculated_factor;
|
|
60589
|
+
const long_notional = long.entry * long.quantity;
|
|
60590
|
+
const short_notional = short.entry * short.quantity;
|
|
60591
|
+
const target_to_reduce = desired_risk / (1 - sell_factor);
|
|
60592
|
+
if (kind === "short") {
|
|
60593
|
+
const calculate_longPercent = target_to_reduce / long_notional;
|
|
60594
|
+
calculated_factor = calculate_longPercent * short_notional / gapLoss;
|
|
60595
|
+
} else {
|
|
60596
|
+
const calculated_shortPercent = target_to_reduce / (short_notional - target_to_reduce);
|
|
60597
|
+
calculated_factor = calculated_shortPercent * long_notional / gapLoss;
|
|
60598
|
+
}
|
|
60599
|
+
calculated_factor = to_f2(calculated_factor, places);
|
|
60600
|
+
return calculated_factor;
|
|
60601
|
+
}
|
|
60561
60602
|
|
|
60562
60603
|
// src/helpers/strategy.ts
|
|
60563
60604
|
class Strategy {
|
|
@@ -60961,12 +61002,14 @@ class Strategy {
|
|
|
60961
61002
|
return { ...app_config, avg, loss: -expected_loss, profit_percent };
|
|
60962
61003
|
}
|
|
60963
61004
|
identifyGapConfig(payload) {
|
|
60964
|
-
const { factor = 1,
|
|
61005
|
+
const { factor, sell_factor = 1, kind, risk } = payload;
|
|
60965
61006
|
return generateGapTp({
|
|
60966
61007
|
long: this.position.long,
|
|
60967
61008
|
short: this.position.short,
|
|
60968
61009
|
factor,
|
|
60969
61010
|
sell_factor,
|
|
61011
|
+
kind,
|
|
61012
|
+
risk,
|
|
60970
61013
|
decimal_places: this.config.global_config.decimal_places,
|
|
60971
61014
|
price_places: this.config.global_config.price_places
|
|
60972
61015
|
});
|
|
@@ -60991,19 +61034,27 @@ class Strategy {
|
|
|
60991
61034
|
return result;
|
|
60992
61035
|
}
|
|
60993
61036
|
simulateGapReduction(payload) {
|
|
60994
|
-
const {
|
|
61037
|
+
const {
|
|
61038
|
+
factor,
|
|
61039
|
+
direction,
|
|
61040
|
+
sell_factor = 1,
|
|
61041
|
+
iterations = 10,
|
|
61042
|
+
risk: desired_risk,
|
|
61043
|
+
kind
|
|
61044
|
+
} = payload;
|
|
60995
61045
|
const results = [];
|
|
60996
61046
|
let params = {
|
|
60997
61047
|
long: this.position.long,
|
|
60998
61048
|
short: this.position.short,
|
|
60999
61049
|
config: this.config
|
|
61000
61050
|
};
|
|
61001
|
-
let
|
|
61002
|
-
while (true) {
|
|
61051
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
61003
61052
|
const instance = new Strategy(params);
|
|
61004
61053
|
const { profit_percent, risk, take_profit, sell_quantity, gap_loss } = instance.identifyGapConfig({
|
|
61005
61054
|
factor,
|
|
61006
|
-
sell_factor
|
|
61055
|
+
sell_factor,
|
|
61056
|
+
kind,
|
|
61057
|
+
risk: desired_risk
|
|
61007
61058
|
});
|
|
61008
61059
|
const to_add = {
|
|
61009
61060
|
profit_percent,
|
|
@@ -61023,26 +61074,24 @@ class Strategy {
|
|
|
61023
61074
|
}
|
|
61024
61075
|
};
|
|
61025
61076
|
results.push(to_add);
|
|
61026
|
-
const sell_kind =
|
|
61077
|
+
const sell_kind = direction == "long" ? "short" : "long";
|
|
61027
61078
|
const remaining = this.to_df(params[sell_kind].quantity - sell_quantity[sell_kind]);
|
|
61028
61079
|
if (remaining <= 0) {
|
|
61029
61080
|
break;
|
|
61030
61081
|
}
|
|
61031
61082
|
params[sell_kind].quantity = remaining;
|
|
61032
|
-
params[
|
|
61033
|
-
entry: take_profit[
|
|
61083
|
+
params[direction] = {
|
|
61084
|
+
entry: take_profit[direction],
|
|
61034
61085
|
quantity: remaining
|
|
61035
61086
|
};
|
|
61036
|
-
counter++;
|
|
61037
61087
|
}
|
|
61038
61088
|
const last_gap_loss = results.at(-1)?.gap_loss;
|
|
61039
|
-
const last_tp = results.at(-1)?.take_profit[
|
|
61040
|
-
const entry = this.position[
|
|
61089
|
+
const last_tp = results.at(-1)?.take_profit[direction];
|
|
61090
|
+
const entry = this.position[direction].entry;
|
|
61041
61091
|
const quantity = this.to_df(Math.abs(last_tp - entry) / last_gap_loss);
|
|
61042
61092
|
return {
|
|
61043
61093
|
results,
|
|
61044
|
-
quantity
|
|
61045
|
-
counter
|
|
61094
|
+
quantity
|
|
61046
61095
|
};
|
|
61047
61096
|
}
|
|
61048
61097
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -60480,11 +60480,26 @@ function generateGapTp(payload) {
|
|
|
60480
60480
|
const {
|
|
60481
60481
|
long,
|
|
60482
60482
|
short,
|
|
60483
|
-
factor =
|
|
60483
|
+
factor: factor_value = 0,
|
|
60484
|
+
risk: desired_risk,
|
|
60484
60485
|
sell_factor = 1,
|
|
60486
|
+
kind,
|
|
60485
60487
|
price_places = "%.1f",
|
|
60486
60488
|
decimal_places = "%.3f"
|
|
60487
60489
|
} = payload;
|
|
60490
|
+
if (!factor_value && !desired_risk) {
|
|
60491
|
+
throw new Error("Either factor or risk must be provided");
|
|
60492
|
+
}
|
|
60493
|
+
if (desired_risk && !kind) {
|
|
60494
|
+
throw new Error("Kind must be provided when risk is provided");
|
|
60495
|
+
}
|
|
60496
|
+
let factor = factor_value || calculate_factor({
|
|
60497
|
+
long,
|
|
60498
|
+
short,
|
|
60499
|
+
risk: desired_risk,
|
|
60500
|
+
kind,
|
|
60501
|
+
sell_factor
|
|
60502
|
+
});
|
|
60488
60503
|
const gap = Math.abs(long.entry - short.entry);
|
|
60489
60504
|
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
60490
60505
|
const gapLoss = gap * max_quantity;
|
|
@@ -60497,7 +60512,7 @@ function generateGapTp(payload) {
|
|
|
60497
60512
|
const actualShortReduce = to_f2(shortToReduce * sell_factor, "%.1f");
|
|
60498
60513
|
const actualLongReduce = to_f2(longToReduce * sell_factor, "%.1f");
|
|
60499
60514
|
const short_quantity_to_sell = determine_amount_to_sell2(short.entry, short.quantity, longTp, actualShortReduce, "short", decimal_places);
|
|
60500
|
-
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp,
|
|
60515
|
+
const long_quantity_to_sell = determine_amount_to_sell2(long.entry, long.quantity, shortTp, actualLongReduce, "long", decimal_places);
|
|
60501
60516
|
const risk_amount_short = to_f2(shortToReduce - actualShortReduce, "%.2f");
|
|
60502
60517
|
const risk_amount_long = to_f2(longToReduce - actualLongReduce, "%.2f");
|
|
60503
60518
|
const profit_percent_long = to_f2(shortToReduce * 100 / (long.entry * long.quantity), "%.4f");
|
|
@@ -60531,6 +60546,32 @@ function generateGapTp(payload) {
|
|
|
60531
60546
|
gap_loss: to_f2(gapLoss, "%.2f")
|
|
60532
60547
|
};
|
|
60533
60548
|
}
|
|
60549
|
+
function calculate_factor(payload) {
|
|
60550
|
+
const {
|
|
60551
|
+
long,
|
|
60552
|
+
short,
|
|
60553
|
+
risk: desired_risk,
|
|
60554
|
+
kind,
|
|
60555
|
+
sell_factor,
|
|
60556
|
+
places = "%.4f"
|
|
60557
|
+
} = payload;
|
|
60558
|
+
const gap = Math.abs(long.entry - short.entry);
|
|
60559
|
+
const max_quantity = Math.max(long.quantity, short.quantity);
|
|
60560
|
+
const gapLoss = gap * max_quantity;
|
|
60561
|
+
let calculated_factor;
|
|
60562
|
+
const long_notional = long.entry * long.quantity;
|
|
60563
|
+
const short_notional = short.entry * short.quantity;
|
|
60564
|
+
const target_to_reduce = desired_risk / (1 - sell_factor);
|
|
60565
|
+
if (kind === "short") {
|
|
60566
|
+
const calculate_longPercent = target_to_reduce / long_notional;
|
|
60567
|
+
calculated_factor = calculate_longPercent * short_notional / gapLoss;
|
|
60568
|
+
} else {
|
|
60569
|
+
const calculated_shortPercent = target_to_reduce / (short_notional - target_to_reduce);
|
|
60570
|
+
calculated_factor = calculated_shortPercent * long_notional / gapLoss;
|
|
60571
|
+
}
|
|
60572
|
+
calculated_factor = to_f2(calculated_factor, places);
|
|
60573
|
+
return calculated_factor;
|
|
60574
|
+
}
|
|
60534
60575
|
|
|
60535
60576
|
// src/helpers/strategy.ts
|
|
60536
60577
|
class Strategy {
|
|
@@ -60934,12 +60975,14 @@ class Strategy {
|
|
|
60934
60975
|
return { ...app_config, avg, loss: -expected_loss, profit_percent };
|
|
60935
60976
|
}
|
|
60936
60977
|
identifyGapConfig(payload) {
|
|
60937
|
-
const { factor = 1,
|
|
60978
|
+
const { factor, sell_factor = 1, kind, risk } = payload;
|
|
60938
60979
|
return generateGapTp({
|
|
60939
60980
|
long: this.position.long,
|
|
60940
60981
|
short: this.position.short,
|
|
60941
60982
|
factor,
|
|
60942
60983
|
sell_factor,
|
|
60984
|
+
kind,
|
|
60985
|
+
risk,
|
|
60943
60986
|
decimal_places: this.config.global_config.decimal_places,
|
|
60944
60987
|
price_places: this.config.global_config.price_places
|
|
60945
60988
|
});
|
|
@@ -60964,19 +61007,27 @@ class Strategy {
|
|
|
60964
61007
|
return result;
|
|
60965
61008
|
}
|
|
60966
61009
|
simulateGapReduction(payload) {
|
|
60967
|
-
const {
|
|
61010
|
+
const {
|
|
61011
|
+
factor,
|
|
61012
|
+
direction,
|
|
61013
|
+
sell_factor = 1,
|
|
61014
|
+
iterations = 10,
|
|
61015
|
+
risk: desired_risk,
|
|
61016
|
+
kind
|
|
61017
|
+
} = payload;
|
|
60968
61018
|
const results = [];
|
|
60969
61019
|
let params = {
|
|
60970
61020
|
long: this.position.long,
|
|
60971
61021
|
short: this.position.short,
|
|
60972
61022
|
config: this.config
|
|
60973
61023
|
};
|
|
60974
|
-
let
|
|
60975
|
-
while (true) {
|
|
61024
|
+
for (let i2 = 0;i2 < iterations; i2++) {
|
|
60976
61025
|
const instance = new Strategy(params);
|
|
60977
61026
|
const { profit_percent, risk, take_profit, sell_quantity, gap_loss } = instance.identifyGapConfig({
|
|
60978
61027
|
factor,
|
|
60979
|
-
sell_factor
|
|
61028
|
+
sell_factor,
|
|
61029
|
+
kind,
|
|
61030
|
+
risk: desired_risk
|
|
60980
61031
|
});
|
|
60981
61032
|
const to_add = {
|
|
60982
61033
|
profit_percent,
|
|
@@ -60996,26 +61047,24 @@ class Strategy {
|
|
|
60996
61047
|
}
|
|
60997
61048
|
};
|
|
60998
61049
|
results.push(to_add);
|
|
60999
|
-
const sell_kind =
|
|
61050
|
+
const sell_kind = direction == "long" ? "short" : "long";
|
|
61000
61051
|
const remaining = this.to_df(params[sell_kind].quantity - sell_quantity[sell_kind]);
|
|
61001
61052
|
if (remaining <= 0) {
|
|
61002
61053
|
break;
|
|
61003
61054
|
}
|
|
61004
61055
|
params[sell_kind].quantity = remaining;
|
|
61005
|
-
params[
|
|
61006
|
-
entry: take_profit[
|
|
61056
|
+
params[direction] = {
|
|
61057
|
+
entry: take_profit[direction],
|
|
61007
61058
|
quantity: remaining
|
|
61008
61059
|
};
|
|
61009
|
-
counter++;
|
|
61010
61060
|
}
|
|
61011
61061
|
const last_gap_loss = results.at(-1)?.gap_loss;
|
|
61012
|
-
const last_tp = results.at(-1)?.take_profit[
|
|
61013
|
-
const entry = this.position[
|
|
61062
|
+
const last_tp = results.at(-1)?.take_profit[direction];
|
|
61063
|
+
const entry = this.position[direction].entry;
|
|
61014
61064
|
const quantity = this.to_df(Math.abs(last_tp - entry) / last_gap_loss);
|
|
61015
61065
|
return {
|
|
61016
61066
|
results,
|
|
61017
|
-
quantity
|
|
61018
|
-
counter
|
|
61067
|
+
quantity
|
|
61019
61068
|
};
|
|
61020
61069
|
}
|
|
61021
61070
|
}
|