@continuumdao/continuum-node-sdk 1.3.28 → 1.3.30
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/agent-host-catalog.json +2 -0
- package/dist/core/chart/analysis/analysis-agent-view.d.ts.map +1 -1
- package/dist/core/chart/analysis/analysis-agent-view.js +34 -0
- package/dist/core/chart/analysis/analysis-agent-view.js.map +1 -1
- package/dist/core/chart/analysis/analysis-catalog.d.ts.map +1 -1
- package/dist/core/chart/analysis/analysis-catalog.js +16 -0
- package/dist/core/chart/analysis/analysis-catalog.js.map +1 -1
- package/dist/core/chart/analysis/analyze-tools.d.ts +47 -0
- package/dist/core/chart/analysis/analyze-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/analyze-tools.js +28 -9
- package/dist/core/chart/analysis/analyze-tools.js.map +1 -1
- package/dist/core/chart/analysis/bollinger-analyze-tools.d.ts +101 -0
- package/dist/core/chart/analysis/bollinger-analyze-tools.d.ts.map +1 -0
- package/dist/core/chart/analysis/bollinger-analyze-tools.js +289 -0
- package/dist/core/chart/analysis/bollinger-analyze-tools.js.map +1 -0
- package/dist/core/chart/analysis/bollinger-highlight.d.ts +29 -0
- package/dist/core/chart/analysis/bollinger-highlight.d.ts.map +1 -0
- package/dist/core/chart/analysis/bollinger-highlight.js +39 -0
- package/dist/core/chart/analysis/bollinger-highlight.js.map +1 -0
- package/dist/core/chart/analysis/candlestick-patterns-tools.d.ts +2 -0
- package/dist/core/chart/analysis/candlestick-patterns-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/candlestick-patterns-tools.js +16 -2
- package/dist/core/chart/analysis/candlestick-patterns-tools.js.map +1 -1
- package/dist/core/chart/analysis/chart-patterns-drawings-tools.d.ts +1 -0
- package/dist/core/chart/analysis/chart-patterns-drawings-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/chart-patterns-tools.d.ts +2 -0
- package/dist/core/chart/analysis/chart-patterns-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/chart-patterns-tools.js +2 -0
- package/dist/core/chart/analysis/chart-patterns-tools.js.map +1 -1
- package/dist/core/chart/analysis/key-fib-drawings-tools.d.ts +1 -0
- package/dist/core/chart/analysis/key-fib-drawings-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/key-fib-drawings-tools.js +48 -3
- package/dist/core/chart/analysis/key-fib-drawings-tools.js.map +1 -1
- package/dist/core/chart/analysis/key-level-drawings-tools.d.ts.map +1 -1
- package/dist/core/chart/analysis/key-level-drawings-tools.js +12 -1
- package/dist/core/chart/analysis/key-level-drawings-tools.js.map +1 -1
- package/dist/core/chart/analysis/moving-averages-analyze-tools.d.ts +116 -0
- package/dist/core/chart/analysis/moving-averages-analyze-tools.d.ts.map +1 -0
- package/dist/core/chart/analysis/moving-averages-analyze-tools.js +205 -0
- package/dist/core/chart/analysis/moving-averages-analyze-tools.js.map +1 -0
- package/dist/core/chart/analysis/moving-averages-highlight.d.ts +30 -0
- package/dist/core/chart/analysis/moving-averages-highlight.d.ts.map +1 -0
- package/dist/core/chart/analysis/moving-averages-highlight.js +77 -0
- package/dist/core/chart/analysis/moving-averages-highlight.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/bollinger-trade-setup.d.ts +77 -0
- package/dist/core/chart/analysis/trade-setups/bollinger-trade-setup.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/bollinger-trade-setup.js +163 -0
- package/dist/core/chart/analysis/trade-setups/bollinger-trade-setup.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap.js +1 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/build-trade.d.ts +4 -1
- package/dist/core/chart/analysis/trade-setups/build-trade.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/build-trade.js +36 -12
- package/dist/core/chart/analysis/trade-setups/build-trade.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/candlestick-trade-setup.d.ts +3 -3
- package/dist/core/chart/analysis/trade-setups/candlestick-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/candlestick-trade-setup.js +12 -14
- package/dist/core/chart/analysis/trade-setups/candlestick-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/chart-data-purpose.d.ts +20 -0
- package/dist/core/chart/analysis/trade-setups/chart-data-purpose.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/chart-data-purpose.js +207 -0
- package/dist/core/chart/analysis/trade-setups/chart-data-purpose.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/chart-pattern-trade-setup.d.ts +7 -1
- package/dist/core/chart/analysis/trade-setups/chart-pattern-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/chart-pattern-trade-setup.js +24 -2
- package/dist/core/chart/analysis/trade-setups/chart-pattern-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/entry-proximity-atr.d.ts +3 -0
- package/dist/core/chart/analysis/trade-setups/entry-proximity-atr.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/entry-proximity-atr.js +32 -0
- package/dist/core/chart/analysis/trade-setups/entry-proximity-atr.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/index.d.ts +3 -0
- package/dist/core/chart/analysis/trade-setups/index.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/index.js +3 -0
- package/dist/core/chart/analysis/trade-setups/index.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/key-level-fib-retrace-trade-setup.d.ts +8 -0
- package/dist/core/chart/analysis/trade-setups/key-level-fib-retrace-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/key-level-fib-retrace-trade-setup.js +33 -5
- package/dist/core/chart/analysis/trade-setups/key-level-fib-retrace-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/key-levels-trade-setup.d.ts +7 -0
- package/dist/core/chart/analysis/trade-setups/key-levels-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/key-levels-trade-setup.js +47 -20
- package/dist/core/chart/analysis/trade-setups/key-levels-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/moving-averages-trade-setup.d.ts +110 -0
- package/dist/core/chart/analysis/trade-setups/moving-averages-trade-setup.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/moving-averages-trade-setup.js +330 -0
- package/dist/core/chart/analysis/trade-setups/moving-averages-trade-setup.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/pattern-limit-entry.d.ts +10 -1
- package/dist/core/chart/analysis/trade-setups/pattern-limit-entry.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/pattern-limit-entry.js +75 -34
- package/dist/core/chart/analysis/trade-setups/pattern-limit-entry.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/shared.d.ts +1 -1
- package/dist/core/chart/analysis/trade-setups/shared.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/shared.js +4 -0
- package/dist/core/chart/analysis/trade-setups/shared.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.d.ts +8 -0
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.js +9 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-universal-input.d.ts +16 -0
- package/dist/core/chart/analysis/trade-setups/trade-desk-universal-input.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/trade-desk-universal-input.js +24 -0
- package/dist/core/chart/analysis/trade-setups/trade-desk-universal-input.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/trade-entry-gates.d.ts +9 -5
- package/dist/core/chart/analysis/trade-setups/trade-entry-gates.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-entry-gates.js +24 -8
- package/dist/core/chart/analysis/trade-setups/trade-entry-gates.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.d.ts +21 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.js +52 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea.d.ts +20 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea.js +20 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.d.ts +2 -0
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.js +5 -0
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.d.ts +122 -0
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.js +231 -0
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.js +12 -3
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trend-line-menu-summary.d.ts +9 -2
- package/dist/core/chart/analysis/trend-line-menu-summary.d.ts.map +1 -1
- package/dist/core/chart/analysis/trend-line-menu-summary.js +74 -6
- package/dist/core/chart/analysis/trend-line-menu-summary.js.map +1 -1
- package/dist/core/chart/display-downsample.d.ts +1 -1
- package/dist/core/chart/display-downsample.d.ts.map +1 -1
- package/dist/core/chart/display-downsample.js +21 -0
- package/dist/core/chart/display-downsample.js.map +1 -1
- package/dist/core/chart/overlay-schemas.d.ts +3 -0
- package/dist/core/chart/overlay-schemas.d.ts.map +1 -1
- package/dist/core/chart/overlay-schemas.js +2 -0
- package/dist/core/chart/overlay-schemas.js.map +1 -1
- package/dist/core/chart/overlays.d.ts.map +1 -1
- package/dist/core/chart/overlays.js +21 -0
- package/dist/core/chart/overlays.js.map +1 -1
- package/dist/core/chart/prepare-core.d.ts.map +1 -1
- package/dist/core/chart/prepare-core.js +20 -1
- package/dist/core/chart/prepare-core.js.map +1 -1
- package/dist/core/chart/prepare-from-rows.d.ts +2 -0
- package/dist/core/chart/prepare-from-rows.d.ts.map +1 -1
- package/dist/core/chart/schemas.d.ts +9 -0
- package/dist/core/chart/schemas.d.ts.map +1 -1
- package/dist/core/chart/schemas.js +1 -1
- package/dist/core/chart/schemas.js.map +1 -1
- package/dist/core/chart-patterns/recommendation.d.ts +1 -0
- package/dist/core/chart-patterns/recommendation.d.ts.map +1 -1
- package/dist/core/chart-patterns/recommendation.js +7 -1
- package/dist/core/chart-patterns/recommendation.js.map +1 -1
- package/dist/core/chart-patterns/scan.d.ts.map +1 -1
- package/dist/core/chart-patterns/scan.js +4 -1
- package/dist/core/chart-patterns/scan.js.map +1 -1
- package/dist/core/chart-patterns/types.d.ts +2 -0
- package/dist/core/chart-patterns/types.d.ts.map +1 -1
- package/dist/core/mpc/schemas.d.ts +4 -0
- package/dist/core/mpc/schemas.d.ts.map +1 -1
- package/dist/core/mpc/schemas.js +3 -0
- package/dist/core/mpc/schemas.js.map +1 -1
- package/dist/core/mpc/sign-request-utils.d.ts +6 -0
- package/dist/core/mpc/sign-request-utils.d.ts.map +1 -1
- package/dist/core/mpc/sign-request-utils.js +47 -0
- package/dist/core/mpc/sign-request-utils.js.map +1 -1
- package/dist/core/mpc/sign-result-summary.d.ts.map +1 -1
- package/dist/core/mpc/sign-result-summary.js +5 -1
- package/dist/core/mpc/sign-result-summary.js.map +1 -1
- package/dist/core/mpc/types.d.ts +4 -0
- package/dist/core/mpc/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/agent-environment-variables.js +1 -1
- package/dist/mcp/agent-environment-variables.js.map +1 -1
- package/dist/mcp/chart.d.ts.map +1 -1
- package/dist/mcp/chart.js +14 -0
- package/dist/mcp/chart.js.map +1 -1
- package/dist/mcp/deferred/tool-group-map.d.ts.map +1 -1
- package/dist/mcp/deferred/tool-group-map.js +2 -0
- package/dist/mcp/deferred/tool-group-map.js.map +1 -1
- package/dist/mcp/defi/defi-protocol-fetch-meta.d.ts +3 -0
- package/dist/mcp/defi/defi-protocol-fetch-meta.d.ts.map +1 -1
- package/dist/mcp/defi/defi-protocol-fetch-meta.js +26 -18
- package/dist/mcp/defi/defi-protocol-fetch-meta.js.map +1 -1
- package/dist/mcp/defi/discovery.js +1 -1
- package/dist/mcp/defi/discovery.js.map +1 -1
- package/dist/mcp/defi/handler.d.ts.map +1 -1
- package/dist/mcp/defi/handler.js +13 -2
- package/dist/mcp/defi/handler.js.map +1 -1
- package/dist/mcp/defi/register-protocol-tools.d.ts.map +1 -1
- package/dist/mcp/defi/register-protocol-tools.js +4 -1
- package/dist/mcp/defi/register-protocol-tools.js.map +1 -1
- package/dist/mcp/defi/the-graph-api-key.d.ts +17 -0
- package/dist/mcp/defi/the-graph-api-key.d.ts.map +1 -0
- package/dist/mcp/defi/the-graph-api-key.js +82 -0
- package/dist/mcp/defi/the-graph-api-key.js.map +1 -0
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.d.ts +7 -0
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.d.ts.map +1 -0
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.js +11 -0
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.js.map +1 -0
- package/dist/mcp/mpc.js +2 -2
- package/dist/mcp/mpc.js.map +1 -1
- package/dist/mcp/ohlcv-session-wrapper.d.ts.map +1 -1
- package/dist/mcp/ohlcv-session-wrapper.js +1 -0
- package/dist/mcp/ohlcv-session-wrapper.js.map +1 -1
- package/dist/mcp/resources/chart-analysis.md +4 -1
- package/dist/mcp/resources/chart.md +3 -2
- package/dist/mcp/trade-tools.d.ts.map +1 -1
- package/dist/mcp/trade-tools.js +9 -1
- package/dist/mcp/trade-tools.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { isFiniteTradePrice } from './shared.js';
|
|
2
|
+
import { entryProximityAtrFromOhlcvRows } from './entry-proximity-atr.js';
|
|
3
|
+
import { assessTradeSetupEntryActionability } from './trade-entry-gates.js';
|
|
4
|
+
import { tradeDeskConfig } from './trade-desk-defaults.js';
|
|
5
|
+
export const DEFAULT_MA_FAST_PERIOD = 50;
|
|
6
|
+
export const DEFAULT_MA_SLOW_PERIOD = 200;
|
|
7
|
+
export const DEFAULT_MA_TYPE = 'sma';
|
|
8
|
+
export const DEFAULT_FRESH_CROSSOVER_MAX_BARS = 5;
|
|
9
|
+
const MIN_CLEAR_CONFIDENCE = 0.45;
|
|
10
|
+
export function maPairLabel(maType, fastPeriod, slowPeriod) {
|
|
11
|
+
const prefix = maType === 'ema' ? 'EMA' : 'SMA';
|
|
12
|
+
return `${prefix}(${fastPeriod})/${prefix}(${slowPeriod})`;
|
|
13
|
+
}
|
|
14
|
+
function sideFromRegime(fastMa, slowMa) {
|
|
15
|
+
if (fastMa > slowMa) {
|
|
16
|
+
return 'long';
|
|
17
|
+
}
|
|
18
|
+
if (fastMa < slowMa) {
|
|
19
|
+
return 'short';
|
|
20
|
+
}
|
|
21
|
+
return 'neutral';
|
|
22
|
+
}
|
|
23
|
+
function crossoverLabelFromState(state) {
|
|
24
|
+
if (state === 'bullish') {
|
|
25
|
+
return 'golden_cross';
|
|
26
|
+
}
|
|
27
|
+
if (state === 'bearish') {
|
|
28
|
+
return 'death_cross';
|
|
29
|
+
}
|
|
30
|
+
return 'none';
|
|
31
|
+
}
|
|
32
|
+
function proximityTypeFromSide(side) {
|
|
33
|
+
if (side === 'long') {
|
|
34
|
+
return 'slow_ma_retest_bullish';
|
|
35
|
+
}
|
|
36
|
+
if (side === 'short') {
|
|
37
|
+
return 'slow_ma_retest_bearish';
|
|
38
|
+
}
|
|
39
|
+
return 'none';
|
|
40
|
+
}
|
|
41
|
+
function crossoverConfidence(barsSinceCrossover, fastMa, slowMa) {
|
|
42
|
+
let confidence = 0.45;
|
|
43
|
+
if (barsSinceCrossover != null && barsSinceCrossover <= 2) {
|
|
44
|
+
confidence += 0.1;
|
|
45
|
+
}
|
|
46
|
+
else if (barsSinceCrossover != null && barsSinceCrossover <= 5) {
|
|
47
|
+
confidence += 0.05;
|
|
48
|
+
}
|
|
49
|
+
const spread = Math.abs(fastMa - slowMa);
|
|
50
|
+
const mid = (fastMa + slowMa) / 2;
|
|
51
|
+
if (mid > 0 && spread / mid > 0.002) {
|
|
52
|
+
confidence = Math.min(0.75, confidence + 0.05);
|
|
53
|
+
}
|
|
54
|
+
return confidence;
|
|
55
|
+
}
|
|
56
|
+
function retestConfidence(fastMa, slowMa) {
|
|
57
|
+
const spread = Math.abs(fastMa - slowMa);
|
|
58
|
+
const mid = (fastMa + slowMa) / 2;
|
|
59
|
+
let confidence = 0.45;
|
|
60
|
+
if (mid > 0 && spread / mid > 0.003) {
|
|
61
|
+
confidence = Math.min(0.65, confidence + 0.07);
|
|
62
|
+
}
|
|
63
|
+
return confidence;
|
|
64
|
+
}
|
|
65
|
+
function formatCrossoverAge(barsSinceCrossover) {
|
|
66
|
+
if (barsSinceCrossover == null) {
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
if (barsSinceCrossover === 0) {
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
return ` ${barsSinceCrossover} bar${barsSinceCrossover === 1 ? '' : 's'} ago`;
|
|
73
|
+
}
|
|
74
|
+
export function buildMovingAveragesTradeSummary(input) {
|
|
75
|
+
const pair = maPairLabel(input.maType, input.fastPeriod, input.slowPeriod);
|
|
76
|
+
if (input.strategy === 'crossover') {
|
|
77
|
+
const crossName = input.crossoverLabel === 'golden_cross' ? 'Golden cross' : 'Death cross';
|
|
78
|
+
const age = formatCrossoverAge(input.barsSinceCrossover);
|
|
79
|
+
if (input.status === 'clear' && input.side !== 'neutral') {
|
|
80
|
+
const sideWord = input.side === 'long' ? 'long' : 'short';
|
|
81
|
+
return `${crossName}${age} · ${pair} · ${sideWord} entry at last close`;
|
|
82
|
+
}
|
|
83
|
+
return `${crossName}${age} · ${pair} · no actionable entry`;
|
|
84
|
+
}
|
|
85
|
+
const regime = input.proximityType === 'slow_ma_retest_bullish'
|
|
86
|
+
? 'bullish regime'
|
|
87
|
+
: input.proximityType === 'slow_ma_retest_bearish'
|
|
88
|
+
? 'bearish regime'
|
|
89
|
+
: 'neutral regime';
|
|
90
|
+
const slowLabel = `${input.maType === 'ema' ? 'EMA' : 'SMA'}(${input.slowPeriod})`;
|
|
91
|
+
if (input.status === 'clear' && input.side !== 'neutral') {
|
|
92
|
+
const sideWord = input.side === 'long' ? 'long' : 'short';
|
|
93
|
+
return `Proximity + retest · ${regime} · ${sideWord} limit at ${slowLabel}`;
|
|
94
|
+
}
|
|
95
|
+
if (input.unclearReason?.includes('proximity')) {
|
|
96
|
+
return `Proximity + retest · ${regime} · price not within proximity of ${slowLabel}`;
|
|
97
|
+
}
|
|
98
|
+
return `Proximity + retest · ${regime} · no actionable entry`;
|
|
99
|
+
}
|
|
100
|
+
export function detectMaCrossover(fastSeries, slowSeries) {
|
|
101
|
+
const len = Math.min(fastSeries.length, slowSeries.length);
|
|
102
|
+
if (len < 2) {
|
|
103
|
+
return { crossoverState: 'none', barsSinceCrossover: null };
|
|
104
|
+
}
|
|
105
|
+
for (let offset = 0; offset < len - 1; offset++) {
|
|
106
|
+
const i = len - 1 - offset;
|
|
107
|
+
const prev = i - 1;
|
|
108
|
+
const fast = fastSeries[i];
|
|
109
|
+
const slow = slowSeries[i];
|
|
110
|
+
const fastPrev = fastSeries[prev];
|
|
111
|
+
const slowPrev = slowSeries[prev];
|
|
112
|
+
if (!isFiniteTradePrice(fast) ||
|
|
113
|
+
!isFiniteTradePrice(slow) ||
|
|
114
|
+
!isFiniteTradePrice(fastPrev) ||
|
|
115
|
+
!isFiniteTradePrice(slowPrev)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (fast > slow && fastPrev <= slowPrev) {
|
|
119
|
+
return { crossoverState: 'bullish', barsSinceCrossover: offset };
|
|
120
|
+
}
|
|
121
|
+
if (fast < slow && fastPrev >= slowPrev) {
|
|
122
|
+
return { crossoverState: 'bearish', barsSinceCrossover: offset };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { crossoverState: 'none', barsSinceCrossover: null };
|
|
126
|
+
}
|
|
127
|
+
export function buildMovingAveragesTradeSetup(input) {
|
|
128
|
+
const close = input.lastClose;
|
|
129
|
+
const fastMa = input.fastMa;
|
|
130
|
+
const slowMa = input.slowMa;
|
|
131
|
+
if (!isFiniteTradePrice(close) || !isFiniteTradePrice(fastMa) || !isFiniteTradePrice(slowMa)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const desk = tradeDeskConfig({
|
|
135
|
+
entryProximityPct: input.entryProximityPct,
|
|
136
|
+
entryProximityMode: input.entryProximityMode,
|
|
137
|
+
entryProximityAtrPeriod: input.entryProximityAtrPeriod,
|
|
138
|
+
entryOffsetPct: input.entryOffsetPct,
|
|
139
|
+
});
|
|
140
|
+
const freshMax = input.freshCrossoverMaxBars ?? DEFAULT_FRESH_CROSSOVER_MAX_BARS;
|
|
141
|
+
const regimeSide = sideFromRegime(fastMa, slowMa);
|
|
142
|
+
const crossoverLabel = crossoverLabelFromState(input.crossoverState);
|
|
143
|
+
const proximityType = proximityTypeFromSide(regimeSide);
|
|
144
|
+
const atrAtLastBar = desk.entryProximityMode === 'atr' && input.bars?.length
|
|
145
|
+
? entryProximityAtrFromOhlcvRows(input.bars, desk.entryProximityAtrPeriod)
|
|
146
|
+
: null;
|
|
147
|
+
const freshCrossover = input.crossoverState !== 'none' &&
|
|
148
|
+
input.barsSinceCrossover != null &&
|
|
149
|
+
input.barsSinceCrossover <= freshMax;
|
|
150
|
+
let strategy = 'proximity_retest';
|
|
151
|
+
let side = regimeSide;
|
|
152
|
+
let status = 'unclear';
|
|
153
|
+
let confidence = 0.35;
|
|
154
|
+
let entryPrice;
|
|
155
|
+
let entryLabel;
|
|
156
|
+
let entryOffsetMode = 'retest';
|
|
157
|
+
let setupPurposeCode = 'ma-ret';
|
|
158
|
+
let unclearReason = regimeSide === 'neutral'
|
|
159
|
+
? 'Fast and slow moving averages are aligned — no directional regime.'
|
|
160
|
+
: 'No actionable moving-average setup on the current bar.';
|
|
161
|
+
if (freshCrossover && input.crossoverState === 'bullish') {
|
|
162
|
+
strategy = 'crossover';
|
|
163
|
+
side = 'long';
|
|
164
|
+
confidence = crossoverConfidence(input.barsSinceCrossover, fastMa, slowMa);
|
|
165
|
+
entryOffsetMode = 'bounce';
|
|
166
|
+
setupPurposeCode = 'ma-cross';
|
|
167
|
+
if (confidence >= MIN_CLEAR_CONFIDENCE) {
|
|
168
|
+
status = 'clear';
|
|
169
|
+
entryPrice = close;
|
|
170
|
+
entryLabel = 'last close (crossover)';
|
|
171
|
+
unclearReason = '';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (freshCrossover && input.crossoverState === 'bearish') {
|
|
175
|
+
strategy = 'crossover';
|
|
176
|
+
side = 'short';
|
|
177
|
+
confidence = crossoverConfidence(input.barsSinceCrossover, fastMa, slowMa);
|
|
178
|
+
entryOffsetMode = 'bounce';
|
|
179
|
+
setupPurposeCode = 'ma-cross';
|
|
180
|
+
if (confidence >= MIN_CLEAR_CONFIDENCE) {
|
|
181
|
+
status = 'clear';
|
|
182
|
+
entryPrice = close;
|
|
183
|
+
entryLabel = 'last close (crossover)';
|
|
184
|
+
unclearReason = '';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (input.crossoverState !== 'none' &&
|
|
188
|
+
input.barsSinceCrossover != null &&
|
|
189
|
+
input.barsSinceCrossover > freshMax) {
|
|
190
|
+
strategy = 'crossover';
|
|
191
|
+
side = input.crossoverState === 'bullish' ? 'long' : 'short';
|
|
192
|
+
confidence = crossoverConfidence(input.barsSinceCrossover, fastMa, slowMa);
|
|
193
|
+
entryOffsetMode = 'bounce';
|
|
194
|
+
setupPurposeCode = 'ma-cross';
|
|
195
|
+
unclearReason = `Crossover occurred ${input.barsSinceCrossover} bars ago — outside fresh window (${freshMax} bars).`;
|
|
196
|
+
}
|
|
197
|
+
else if (regimeSide !== 'neutral') {
|
|
198
|
+
strategy = 'proximity_retest';
|
|
199
|
+
side = regimeSide;
|
|
200
|
+
confidence = retestConfidence(fastMa, slowMa);
|
|
201
|
+
entryOffsetMode = 'retest';
|
|
202
|
+
setupPurposeCode = 'ma-ret';
|
|
203
|
+
const entryCheck = assessTradeSetupEntryActionability({
|
|
204
|
+
lastClose: close,
|
|
205
|
+
entryPrice: slowMa,
|
|
206
|
+
side,
|
|
207
|
+
entryOffsetMode: 'retest',
|
|
208
|
+
entryProximityPct: desk.entryProximityPct,
|
|
209
|
+
entryProximityMode: desk.entryProximityMode,
|
|
210
|
+
entryProximityAtr: atrAtLastBar,
|
|
211
|
+
entryOffsetPct: desk.entryOffsetPct,
|
|
212
|
+
});
|
|
213
|
+
if (entryCheck.ok && confidence >= MIN_CLEAR_CONFIDENCE) {
|
|
214
|
+
status = 'clear';
|
|
215
|
+
entryPrice = slowMa;
|
|
216
|
+
entryLabel = `${input.maType === 'ema' ? 'EMA' : 'SMA'}(${input.slowPeriod}) retest`;
|
|
217
|
+
unclearReason = '';
|
|
218
|
+
confidence = Math.min(0.7, confidence + 0.05);
|
|
219
|
+
}
|
|
220
|
+
else if (!entryCheck.ok) {
|
|
221
|
+
unclearReason = entryCheck.unclearReason;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const targetPrice = status === 'clear' && side === 'long'
|
|
225
|
+
? fastMa
|
|
226
|
+
: status === 'clear' && side === 'short'
|
|
227
|
+
? fastMa
|
|
228
|
+
: undefined;
|
|
229
|
+
const targetLabel = status === 'clear' ? `${input.maType === 'ema' ? 'EMA' : 'SMA'}(${input.fastPeriod})` : undefined;
|
|
230
|
+
const invalidationPrice = status === 'clear' && side === 'long'
|
|
231
|
+
? slowMa
|
|
232
|
+
: status === 'clear' && side === 'short'
|
|
233
|
+
? slowMa
|
|
234
|
+
: undefined;
|
|
235
|
+
const invalidationLabel = status === 'clear'
|
|
236
|
+
? `below ${input.maType === 'ema' ? 'EMA' : 'SMA'}(${input.slowPeriod})`
|
|
237
|
+
: undefined;
|
|
238
|
+
const tradeSummary = buildMovingAveragesTradeSummary({
|
|
239
|
+
maType: input.maType,
|
|
240
|
+
fastPeriod: input.fastPeriod,
|
|
241
|
+
slowPeriod: input.slowPeriod,
|
|
242
|
+
strategy,
|
|
243
|
+
crossoverLabel: strategy === 'crossover' ? crossoverLabel : 'none',
|
|
244
|
+
proximityType: strategy === 'proximity_retest' ? proximityType : 'none',
|
|
245
|
+
side,
|
|
246
|
+
status,
|
|
247
|
+
barsSinceCrossover: input.barsSinceCrossover,
|
|
248
|
+
unclearReason,
|
|
249
|
+
});
|
|
250
|
+
const conditionalNote = status === 'clear'
|
|
251
|
+
? tradeSummary
|
|
252
|
+
: strategy === 'crossover' && crossoverLabel !== 'none'
|
|
253
|
+
? `${crossoverLabel === 'golden_cross' ? 'Golden cross' : 'Death cross'} detected but not actionable — ${unclearReason || 'wait for a fresh crossover or proximity retest.'}`
|
|
254
|
+
: unclearReason ||
|
|
255
|
+
'Moving-average setup is unclear — wait for crossover or slow MA retest within proximity.';
|
|
256
|
+
return {
|
|
257
|
+
status,
|
|
258
|
+
source: 'moving_averages',
|
|
259
|
+
lastClose: close,
|
|
260
|
+
fastMa,
|
|
261
|
+
slowMa,
|
|
262
|
+
fastPeriod: input.fastPeriod,
|
|
263
|
+
slowPeriod: input.slowPeriod,
|
|
264
|
+
maType: input.maType,
|
|
265
|
+
crossoverState: input.crossoverState,
|
|
266
|
+
barsSinceCrossover: input.barsSinceCrossover,
|
|
267
|
+
strategy,
|
|
268
|
+
crossoverLabel: strategy === 'crossover' ? crossoverLabel : 'none',
|
|
269
|
+
proximityType: strategy === 'proximity_retest' ? proximityType : 'none',
|
|
270
|
+
setupPurposeCode,
|
|
271
|
+
entryOffsetMode,
|
|
272
|
+
entryProximityPct: desk.entryProximityPct,
|
|
273
|
+
entryProximityMode: desk.entryProximityMode,
|
|
274
|
+
entryOffsetPct: desk.entryOffsetPct,
|
|
275
|
+
invalidationOffsetPct: desk.invalidationOffsetPct,
|
|
276
|
+
...(atrAtLastBar != null ? { atrAtLastBar } : {}),
|
|
277
|
+
side,
|
|
278
|
+
confidence,
|
|
279
|
+
tradeSummary,
|
|
280
|
+
conditionalNote,
|
|
281
|
+
...(status === 'clear' && entryPrice != null && entryLabel
|
|
282
|
+
? { entryPrice, entryLabel }
|
|
283
|
+
: {}),
|
|
284
|
+
...(targetPrice != null && targetLabel ? { targetPrice, targetLabel } : {}),
|
|
285
|
+
...(invalidationPrice != null && invalidationLabel
|
|
286
|
+
? { invalidationPrice, invalidationLabel }
|
|
287
|
+
: {}),
|
|
288
|
+
...(unclearReason && status === 'unclear' ? { unclearReason } : {}),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
export function movingAveragesTradeIdeaContextFromSetup(setup) {
|
|
292
|
+
return {
|
|
293
|
+
tradeSummary: setup.tradeSummary,
|
|
294
|
+
strategy: setup.strategy,
|
|
295
|
+
crossoverLabel: setup.crossoverLabel,
|
|
296
|
+
proximityType: setup.proximityType,
|
|
297
|
+
fastPeriod: setup.fastPeriod,
|
|
298
|
+
slowPeriod: setup.slowPeriod,
|
|
299
|
+
maType: setup.maType,
|
|
300
|
+
barsSinceCrossover: setup.barsSinceCrossover,
|
|
301
|
+
setupPurposeCode: setup.setupPurposeCode,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
export function normalizeMovingAveragesTradeSetup(setup) {
|
|
305
|
+
return {
|
|
306
|
+
status: setup.status,
|
|
307
|
+
side: setup.side,
|
|
308
|
+
confidence: setup.confidence,
|
|
309
|
+
lastClose: setup.lastClose,
|
|
310
|
+
entry: setup.status === 'clear' &&
|
|
311
|
+
setup.side !== 'neutral' &&
|
|
312
|
+
setup.entryPrice != null &&
|
|
313
|
+
isFiniteTradePrice(setup.entryPrice)
|
|
314
|
+
? { price: setup.entryPrice, label: setup.entryLabel ?? 'MA entry' }
|
|
315
|
+
: undefined,
|
|
316
|
+
...(setup.targetPrice != null && isFiniteTradePrice(setup.targetPrice)
|
|
317
|
+
? { target: { price: setup.targetPrice, label: setup.targetLabel ?? 'fast MA' } }
|
|
318
|
+
: {}),
|
|
319
|
+
...(setup.invalidationPrice != null && isFiniteTradePrice(setup.invalidationPrice)
|
|
320
|
+
? {
|
|
321
|
+
invalidation: {
|
|
322
|
+
price: setup.invalidationPrice,
|
|
323
|
+
label: setup.invalidationLabel ?? 'slow MA breach',
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
: {}),
|
|
327
|
+
unclearReason: setup.unclearReason,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=moving-averages-trade-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moving-averages-trade-setup.js","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/moving-averages-trade-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,13 @@ import type { PatternKeyLevelSummary } from '../../../chart-patterns/pattern-men
|
|
|
3
3
|
import type { TradeSetupSide } from './shared.js';
|
|
4
4
|
export declare const DEFAULT_BREAK_TOLERANCE_PCT = 0.1;
|
|
5
5
|
export declare const DEFAULT_ENTRY_PROXIMITY_PCT = 1;
|
|
6
|
+
export type EntryProximityMode = 'price' | 'atr';
|
|
7
|
+
export declare const DEFAULT_ENTRY_PROXIMITY_MODE: EntryProximityMode;
|
|
8
|
+
export type WithinEntryProximityOptions = {
|
|
9
|
+
mode?: EntryProximityMode;
|
|
10
|
+
atr?: number | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function entryProximityGateLabel(pct: number, mode?: EntryProximityMode): string;
|
|
6
13
|
export type PatternEntryPhase = 'inside_pattern' | 'post_breakout_retest';
|
|
7
14
|
export type EntryOffsetMode = 'bounce' | 'retest';
|
|
8
15
|
export type PatternPhase = 'inside' | 'broken_above' | 'broken_below';
|
|
@@ -22,6 +29,8 @@ export type ResolvePatternLimitInput = {
|
|
|
22
29
|
classificationSide: TradeSetupSide;
|
|
23
30
|
breakTolerancePct?: number;
|
|
24
31
|
entryProximityPct?: number;
|
|
32
|
+
entryProximityMode?: EntryProximityMode;
|
|
33
|
+
entryProximityAtr?: number | null;
|
|
25
34
|
};
|
|
26
35
|
export type ResolvePatternLimitResult = {
|
|
27
36
|
ok: true;
|
|
@@ -31,7 +40,7 @@ export type ResolvePatternLimitResult = {
|
|
|
31
40
|
unclearReason: string;
|
|
32
41
|
};
|
|
33
42
|
export declare function patternPhase(lastClose: number, support: number, resistance: number, tolerancePct?: number): PatternPhase;
|
|
34
|
-
export declare function withinEntryProximity(lastClose: number, entry: number, maxPct?: number): boolean;
|
|
43
|
+
export declare function withinEntryProximity(lastClose: number, entry: number, maxPct?: number, options?: WithinEntryProximityOptions): boolean;
|
|
35
44
|
export declare function boundaryAtRightEdge(levels: PatternKeyLevelSummary[]): {
|
|
36
45
|
support: number;
|
|
37
46
|
resistance: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pattern-limit-entry.d.ts","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/pattern-limit-entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,iDAAiD,CAAC;AAC5F,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,2BAA2B,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"pattern-limit-entry.d.ts","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/pattern-limit-entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,iDAAiD,CAAC;AAC5F,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAC7C,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,KAAK,CAAC;AACjD,eAAO,MAAM,4BAA4B,EAAE,kBAA4B,CAAC;AAExE,MAAM,MAAM,2BAA2B,GAAG;IACzC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,uBAAuB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,kBAAiD,GACrD,MAAM,CAER;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,sBAAsB,CAAC;AAC1E,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACtC,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,kBAAkB,EAAE,cAAc,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAClC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAC,GACtC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAC,CAAC;AAMtC,wBAAgB,YAAY,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,YAAY,SAA8B,GACxC,YAAY,CAYd;AAED,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,SAA8B,EACpC,OAAO,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAiBT;AA6DD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,EAAE,GAAG;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACxB,GAAG,IAAI,CA+BP;AAqJD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,wBAAwB,GAAG,yBAAyB,CAqcpG"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export const DEFAULT_BREAK_TOLERANCE_PCT = 0.1;
|
|
2
2
|
export const DEFAULT_ENTRY_PROXIMITY_PCT = 1;
|
|
3
|
+
export const DEFAULT_ENTRY_PROXIMITY_MODE = 'price';
|
|
4
|
+
export function entryProximityGateLabel(pct, mode = DEFAULT_ENTRY_PROXIMITY_MODE) {
|
|
5
|
+
return mode === 'atr' ? `${pct}% of ATR` : `${pct}% of entry`;
|
|
6
|
+
}
|
|
3
7
|
function tolPrice(price, pct) {
|
|
4
8
|
return Math.abs(price) * (pct / 100);
|
|
5
9
|
}
|
|
@@ -16,11 +20,33 @@ export function patternPhase(lastClose, support, resistance, tolerancePct = DEFA
|
|
|
16
20
|
}
|
|
17
21
|
return 'inside';
|
|
18
22
|
}
|
|
19
|
-
export function withinEntryProximity(lastClose, entry, maxPct = DEFAULT_ENTRY_PROXIMITY_PCT) {
|
|
20
|
-
if (!Number.isFinite(lastClose) || !Number.isFinite(entry)
|
|
23
|
+
export function withinEntryProximity(lastClose, entry, maxPct = DEFAULT_ENTRY_PROXIMITY_PCT, options) {
|
|
24
|
+
if (!Number.isFinite(lastClose) || !Number.isFinite(entry)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const distance = Math.abs(lastClose - entry);
|
|
28
|
+
const mode = options?.mode ?? DEFAULT_ENTRY_PROXIMITY_MODE;
|
|
29
|
+
if (mode === 'atr') {
|
|
30
|
+
const atr = options?.atr;
|
|
31
|
+
if (atr == null || !Number.isFinite(atr) || atr <= 0) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return distance <= (atr * maxPct) / 100;
|
|
35
|
+
}
|
|
36
|
+
if (entry === 0) {
|
|
21
37
|
return false;
|
|
22
38
|
}
|
|
23
|
-
return (
|
|
39
|
+
return (distance / Math.abs(entry)) * 100 <= maxPct;
|
|
40
|
+
}
|
|
41
|
+
function failUnlessWithinEntryProximity(lastClose, entryPrice, pct, label, options) {
|
|
42
|
+
if (withinEntryProximity(lastClose, entryPrice, pct, options)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const mode = options?.mode ?? DEFAULT_ENTRY_PROXIMITY_MODE;
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
unclearReason: `Price not within ${entryProximityGateLabel(pct, mode)} of ${label}.`,
|
|
49
|
+
};
|
|
24
50
|
}
|
|
25
51
|
function levelByLabels(levels, labels) {
|
|
26
52
|
for (const want of labels) {
|
|
@@ -135,7 +161,7 @@ function okLevels(trigger, invalidation, entryPhase, entryOffsetMode, limitSide)
|
|
|
135
161
|
},
|
|
136
162
|
};
|
|
137
163
|
}
|
|
138
|
-
function boundaryLong(support, resistance, phase, proximityPct, lastClose, requireBreakoutOnly) {
|
|
164
|
+
function boundaryLong(support, resistance, phase, proximityPct, proximityOptions, lastClose, requireBreakoutOnly) {
|
|
139
165
|
if (requireBreakoutOnly) {
|
|
140
166
|
if (phase === 'inside') {
|
|
141
167
|
return { ok: false, unclearReason: 'Price still inside pattern — no trade until breakout.' };
|
|
@@ -154,12 +180,13 @@ function boundaryLong(support, resistance, phase, proximityPct, lastClose, requi
|
|
|
154
180
|
}
|
|
155
181
|
const entry = { price: support.price, label: `${support.label} bounce` };
|
|
156
182
|
const inv = { price: support.price, label: `${support.label} pattern fail` };
|
|
157
|
-
|
|
158
|
-
|
|
183
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, proximityPct, 'support entry', proximityOptions);
|
|
184
|
+
if (proximityFail) {
|
|
185
|
+
return proximityFail;
|
|
159
186
|
}
|
|
160
187
|
return okLevels(entry, inv, 'inside_pattern', 'bounce', 'long');
|
|
161
188
|
}
|
|
162
|
-
function boundaryShort(support, resistance, phase, proximityPct, lastClose, requireBreakoutOnly) {
|
|
189
|
+
function boundaryShort(support, resistance, phase, proximityPct, proximityOptions, lastClose, requireBreakoutOnly) {
|
|
163
190
|
if (requireBreakoutOnly) {
|
|
164
191
|
if (phase === 'inside') {
|
|
165
192
|
return { ok: false, unclearReason: 'Price still inside pattern — no trade until breakout.' };
|
|
@@ -178,13 +205,18 @@ function boundaryShort(support, resistance, phase, proximityPct, lastClose, requ
|
|
|
178
205
|
}
|
|
179
206
|
const entry = { price: resistance.price, label: `${resistance.label} bounce` };
|
|
180
207
|
const inv = { price: resistance.price, label: `${resistance.label} pattern fail` };
|
|
181
|
-
|
|
182
|
-
|
|
208
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, proximityPct, 'resistance entry', proximityOptions);
|
|
209
|
+
if (proximityFail) {
|
|
210
|
+
return proximityFail;
|
|
183
211
|
}
|
|
184
212
|
return okLevels(entry, inv, 'inside_pattern', 'bounce', 'short');
|
|
185
213
|
}
|
|
186
214
|
export function resolvePatternLimitLevels(input) {
|
|
187
|
-
const { patternId, lastClose, keyLevels, breakTolerancePct = DEFAULT_BREAK_TOLERANCE_PCT, entryProximityPct = DEFAULT_ENTRY_PROXIMITY_PCT, } = input;
|
|
215
|
+
const { patternId, lastClose, keyLevels, breakTolerancePct = DEFAULT_BREAK_TOLERANCE_PCT, entryProximityPct = DEFAULT_ENTRY_PROXIMITY_PCT, entryProximityMode, entryProximityAtr, } = input;
|
|
216
|
+
const proximityOptions = {
|
|
217
|
+
mode: entryProximityMode,
|
|
218
|
+
atr: entryProximityAtr,
|
|
219
|
+
};
|
|
188
220
|
const bounds = boundaryAtRightEdge(keyLevels);
|
|
189
221
|
const phase = bounds != null
|
|
190
222
|
? patternPhase(lastClose, bounds.support, bounds.resistance, breakTolerancePct)
|
|
@@ -194,23 +226,23 @@ export function resolvePatternLimitLevels(input) {
|
|
|
194
226
|
if (!bounds) {
|
|
195
227
|
return { ok: false, unclearReason: 'Missing wedge boundary levels.' };
|
|
196
228
|
}
|
|
197
|
-
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, false);
|
|
229
|
+
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, false);
|
|
198
230
|
}
|
|
199
231
|
case 'rising_wedge': {
|
|
200
232
|
if (!bounds) {
|
|
201
233
|
return { ok: false, unclearReason: 'Missing wedge boundary levels.' };
|
|
202
234
|
}
|
|
203
|
-
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, false);
|
|
235
|
+
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, false);
|
|
204
236
|
}
|
|
205
237
|
case 'symmetrical_triangle': {
|
|
206
238
|
if (!bounds) {
|
|
207
239
|
return { ok: false, unclearReason: 'Missing triangle boundary levels.' };
|
|
208
240
|
}
|
|
209
241
|
if (phase === 'broken_above') {
|
|
210
|
-
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, true);
|
|
242
|
+
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, true);
|
|
211
243
|
}
|
|
212
244
|
if (phase === 'broken_below') {
|
|
213
|
-
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, true);
|
|
245
|
+
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, true);
|
|
214
246
|
}
|
|
215
247
|
return { ok: false, unclearReason: 'Symmetrical triangle — no trade until breakout.' };
|
|
216
248
|
}
|
|
@@ -225,8 +257,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
225
257
|
return okLevels({ price: res.price, label: `${res.label} retest` }, { price: sup.price, label: `${sup.label} pattern fail` }, 'post_breakout_retest', 'retest', 'long');
|
|
226
258
|
}
|
|
227
259
|
const entry = { price: sup.price, label: `${sup.label} bounce` };
|
|
228
|
-
|
|
229
|
-
|
|
260
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'support entry', proximityOptions);
|
|
261
|
+
if (proximityFail) {
|
|
262
|
+
return proximityFail;
|
|
230
263
|
}
|
|
231
264
|
return okLevels(entry, { price: sup.price, label: `${sup.label} pattern fail` }, 'inside_pattern', 'bounce', 'long');
|
|
232
265
|
}
|
|
@@ -241,8 +274,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
241
274
|
return okLevels({ price: sup.price, label: `${sup.label} retest` }, { price: res.price, label: `${res.label} pattern fail` }, 'post_breakout_retest', 'retest', 'short');
|
|
242
275
|
}
|
|
243
276
|
const entry = { price: res.price, label: `${res.label} bounce` };
|
|
244
|
-
|
|
245
|
-
|
|
277
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'resistance entry', proximityOptions);
|
|
278
|
+
if (proximityFail) {
|
|
279
|
+
return proximityFail;
|
|
246
280
|
}
|
|
247
281
|
return okLevels(entry, { price: res.price, label: `${res.label} pattern fail` }, 'inside_pattern', 'bounce', 'short');
|
|
248
282
|
}
|
|
@@ -250,13 +284,13 @@ export function resolvePatternLimitLevels(input) {
|
|
|
250
284
|
if (!bounds) {
|
|
251
285
|
return { ok: false, unclearReason: 'Missing channel boundary levels.' };
|
|
252
286
|
}
|
|
253
|
-
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, false);
|
|
287
|
+
return boundaryLong({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, false);
|
|
254
288
|
}
|
|
255
289
|
case 'channel_down': {
|
|
256
290
|
if (!bounds) {
|
|
257
291
|
return { ok: false, unclearReason: 'Missing channel boundary levels.' };
|
|
258
292
|
}
|
|
259
|
-
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, lastClose, false);
|
|
293
|
+
return boundaryShort({ price: bounds.support, label: bounds.supportLabel }, { price: bounds.resistance, label: bounds.resistanceLabel }, phase, entryProximityPct, proximityOptions, lastClose, false);
|
|
260
294
|
}
|
|
261
295
|
case 'double_bottom':
|
|
262
296
|
case 'double_bottom_adam_eve': {
|
|
@@ -269,8 +303,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
269
303
|
return okLevels({ price: neck.price, label: 'neckline retest' }, { price: trough.price, label: 'trough pattern fail' }, 'post_breakout_retest', 'retest', 'long');
|
|
270
304
|
}
|
|
271
305
|
const entry = { price: trough.price, label: 'trough bounce' };
|
|
272
|
-
|
|
273
|
-
|
|
306
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'trough entry', proximityOptions);
|
|
307
|
+
if (proximityFail) {
|
|
308
|
+
return proximityFail;
|
|
274
309
|
}
|
|
275
310
|
return okLevels(entry, { price: trough.price, label: 'trough pattern fail' }, 'inside_pattern', 'bounce', 'long');
|
|
276
311
|
}
|
|
@@ -284,8 +319,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
284
319
|
return okLevels({ price: neck.price, label: 'neckline retest' }, { price: peak.price, label: 'peak pattern fail' }, 'post_breakout_retest', 'retest', 'short');
|
|
285
320
|
}
|
|
286
321
|
const entry = { price: peak.price, label: 'peak bounce' };
|
|
287
|
-
|
|
288
|
-
|
|
322
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'peak entry', proximityOptions);
|
|
323
|
+
if (proximityFail) {
|
|
324
|
+
return proximityFail;
|
|
289
325
|
}
|
|
290
326
|
return okLevels(entry, { price: peak.price, label: 'peak pattern fail' }, 'inside_pattern', 'bounce', 'short');
|
|
291
327
|
}
|
|
@@ -299,8 +335,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
299
335
|
return okLevels({ price: neck.price, label: 'neckline retest' }, { price: head.price, label: 'head pattern fail' }, 'post_breakout_retest', 'retest', 'long');
|
|
300
336
|
}
|
|
301
337
|
const entry = { price: head.price, label: 'head bounce' };
|
|
302
|
-
|
|
303
|
-
|
|
338
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'head entry', proximityOptions);
|
|
339
|
+
if (proximityFail) {
|
|
340
|
+
return proximityFail;
|
|
304
341
|
}
|
|
305
342
|
return okLevels(entry, { price: head.price, label: 'head pattern fail' }, 'inside_pattern', 'bounce', 'long');
|
|
306
343
|
}
|
|
@@ -314,8 +351,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
314
351
|
return okLevels({ price: neck.price, label: 'neckline retest' }, { price: head.price, label: 'head pattern fail' }, 'post_breakout_retest', 'retest', 'short');
|
|
315
352
|
}
|
|
316
353
|
const entry = { price: head.price, label: 'head bounce' };
|
|
317
|
-
|
|
318
|
-
|
|
354
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'head entry', proximityOptions);
|
|
355
|
+
if (proximityFail) {
|
|
356
|
+
return proximityFail;
|
|
319
357
|
}
|
|
320
358
|
return okLevels(entry, { price: head.price, label: 'head pattern fail' }, 'inside_pattern', 'bounce', 'short');
|
|
321
359
|
}
|
|
@@ -331,8 +369,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
331
369
|
return okLevels({ price: rim.price, label: 'rim retest' }, { price: invPrice, label: 'cup/handle pattern fail' }, 'post_breakout_retest', 'retest', 'long');
|
|
332
370
|
}
|
|
333
371
|
const entry = { price: (handle ?? cupLow).price, label: 'handle bounce' };
|
|
334
|
-
|
|
335
|
-
|
|
372
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'handle entry', proximityOptions);
|
|
373
|
+
if (proximityFail) {
|
|
374
|
+
return proximityFail;
|
|
336
375
|
}
|
|
337
376
|
return okLevels(entry, { price: invPrice, label: 'cup/handle pattern fail' }, 'inside_pattern', 'bounce', 'long');
|
|
338
377
|
}
|
|
@@ -347,8 +386,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
347
386
|
return okLevels({ price: high.price, label: 'flag upper retest' }, { price: low.price, label: 'flag low pattern fail' }, 'post_breakout_retest', 'retest', 'long');
|
|
348
387
|
}
|
|
349
388
|
const entry = { price: low.price, label: 'flag low bounce' };
|
|
350
|
-
|
|
351
|
-
|
|
389
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'flag support entry', proximityOptions);
|
|
390
|
+
if (proximityFail) {
|
|
391
|
+
return proximityFail;
|
|
352
392
|
}
|
|
353
393
|
return okLevels(entry, { price: low.price, label: 'flag low pattern fail' }, 'inside_pattern', 'bounce', 'long');
|
|
354
394
|
}
|
|
@@ -363,8 +403,9 @@ export function resolvePatternLimitLevels(input) {
|
|
|
363
403
|
return okLevels({ price: low.price, label: 'flag lower retest' }, { price: high.price, label: 'flag high pattern fail' }, 'post_breakout_retest', 'retest', 'short');
|
|
364
404
|
}
|
|
365
405
|
const entry = { price: high.price, label: 'flag upper bounce' };
|
|
366
|
-
|
|
367
|
-
|
|
406
|
+
const proximityFail = failUnlessWithinEntryProximity(lastClose, entry.price, entryProximityPct, 'flag resistance entry', proximityOptions);
|
|
407
|
+
if (proximityFail) {
|
|
408
|
+
return proximityFail;
|
|
368
409
|
}
|
|
369
410
|
return okLevels(entry, { price: high.price, label: 'flag high pattern fail' }, 'inside_pattern', 'bounce', 'short');
|
|
370
411
|
}
|