@riocrypto/common-server 1.0.2788 → 1.0.2790

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.
@@ -272,7 +272,17 @@ const resolveFXProviderForAmount = (policy, fiat, amountFiat, offset, now = new
272
272
  if (!matchedAmountRange) {
273
273
  return Object.assign(Object.assign({}, FALLBACK_RESOLUTION), { executionThresholdMs });
274
274
  }
275
- if (!isProviderEligible(matchedAmountRange.provider, fiat, amountFiat, offset)) {
275
+ // Eligibility is checked against the *effective* offset (the override
276
+ // when set, otherwise the trade's own offset). This lets an operator
277
+ // route a T+0 band to StoneX by overriding to T+1, or a T+3 band to
278
+ // Emarkets/Transnetwork by overriding to T+2 - the upstream provider
279
+ // only ever sees the override. For Matching / Other the override is
280
+ // applied to the FX trade's operative settlement date (which is what
281
+ // matching nets by) even though those providers have no upstream
282
+ // value-date concept.
283
+ const tradeAsTwoWaySettlementDateOffset = matchedAmountRange.tradeAsTwoWaySettlementDateOffset;
284
+ const effectiveOffset = tradeAsTwoWaySettlementDateOffset !== null && tradeAsTwoWaySettlementDateOffset !== void 0 ? tradeAsTwoWaySettlementDateOffset : offset;
285
+ if (!isProviderEligible(matchedAmountRange.provider, fiat, amountFiat, effectiveOffset)) {
276
286
  return Object.assign(Object.assign({}, FALLBACK_RESOLUTION), { executionThresholdMs });
277
287
  }
278
288
  const automatic = NON_COSIGNER_PROVIDERS.has(matchedAmountRange.provider)
@@ -282,6 +292,7 @@ const resolveFXProviderForAmount = (policy, fiat, amountFiat, offset, now = new
282
292
  provider: matchedAmountRange.provider,
283
293
  automatic,
284
294
  executionThresholdMs,
295
+ tradeAsTwoWaySettlementDateOffset,
285
296
  };
286
297
  };
287
298
  exports.resolveFXProviderForAmount = resolveFXProviderForAmount;
@@ -10,8 +10,34 @@ interface FXTradeAttrs {
10
10
  amountTraded: number;
11
11
  price?: number;
12
12
  provider: FXProvider;
13
+ /**
14
+ * Operative settlement (what the trade is *hedged* at). Equals the
15
+ * underlying settlement unless the matched FX trading policy band
16
+ * carries a `tradeAsTwoWaySettlementDateOffset` override (or the
17
+ * cosigner-notification webhook picked an alternative settlement
18
+ * type during approval), in which case it is the post-override
19
+ * value. This is what `place-fx-trade-external-trade` and
20
+ * `send-fx-trade-cosigner-request` consume - they only care about
21
+ * the tenor we will actually trade at upstream.
22
+ */
13
23
  twoWaySettlementDate: Date;
14
24
  twoWaySettlementDateOffset: number;
25
+ /**
26
+ * Customer-facing settlement derived from the underlying order(s).
27
+ * Immutable for the lifetime of the FX trade and used for:
28
+ * - policy lookup (`getFXTradingPolicy` is keyed on what the
29
+ * customer was promised, not on our hedging tenor);
30
+ * - aggregation grouping (two orders that promised the customer
31
+ * different days cannot share an FX trade even if the operative
32
+ * hedge tenor would be the same).
33
+ *
34
+ * Marked optional on the type for backwards-compat with trades
35
+ * created before this field existed; runtime readers fall back to
36
+ * the operative fields when missing. New writers always populate
37
+ * both.
38
+ */
39
+ underlyingTwoWaySettlementDate?: Date;
40
+ underlyingTwoWaySettlementDateOffset?: number;
15
41
  executedTrades: {
16
42
  amount: number;
17
43
  provider: FXProvider;
@@ -36,6 +62,8 @@ interface FXTradeDoc extends Document {
36
62
  provider: FXProvider;
37
63
  twoWaySettlementDate: Date;
38
64
  twoWaySettlementDateOffset: number;
65
+ underlyingTwoWaySettlementDate?: Date;
66
+ underlyingTwoWaySettlementDateOffset?: number;
39
67
  executedTrades: {
40
68
  amount: number;
41
69
  provider: FXProvider;
@@ -33,6 +33,12 @@ const buildFXTrade = (mongoose) => {
33
33
  twoWaySettlementDateOffset: {
34
34
  type: Number,
35
35
  },
36
+ underlyingTwoWaySettlementDate: {
37
+ type: mongoose.Schema.Types.Date,
38
+ },
39
+ underlyingTwoWaySettlementDateOffset: {
40
+ type: Number,
41
+ },
36
42
  amountTraded: {
37
43
  type: Number,
38
44
  required: true,
@@ -1,4 +1,4 @@
1
- import { Country, DeferredPaymentType, EmarketsSettlementType, Fiat, FXProvider, FXTradingPolicies, Processor, Side, TransnetworkSettlementType } from "@riocrypto/common";
1
+ import { Country, DeferredPaymentType, Fiat, FXProvider, FXTradingPolicies, Processor, Side } from "@riocrypto/common";
2
2
  import { TVFXDataProvider } from "@riocrypto/common";
3
3
  import mongoose, { HydratedDocument } from "mongoose";
4
4
  interface RioSettingsAttrs {
@@ -45,10 +45,6 @@ interface RioSettingsAttrs {
45
45
  fxProviders: {
46
46
  [key in FXProvider]: {
47
47
  enabled: boolean;
48
- defaultSettlementType?: {
49
- buy: EmarketsSettlementType | TransnetworkSettlementType;
50
- sell: EmarketsSettlementType | TransnetworkSettlementType;
51
- };
52
48
  };
53
49
  };
54
50
  fxTradingPolicies?: FXTradingPolicies;
@@ -134,10 +130,6 @@ interface RioSettingsDoc extends mongoose.Document {
134
130
  fxProviders: {
135
131
  [key in FXProvider]: {
136
132
  enabled: boolean;
137
- defaultSettlementType?: {
138
- buy: EmarketsSettlementType | TransnetworkSettlementType;
139
- sell: EmarketsSettlementType | TransnetworkSettlementType;
140
- };
141
133
  };
142
134
  };
143
135
  fxTradingPolicies?: FXTradingPolicies;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common-server",
3
- "version": "1.0.2788",
3
+ "version": "1.0.2790",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "@google-cloud/secret-manager": "^5.6.0",
29
29
  "@google-cloud/storage": "^7.19.0",
30
30
  "@hyperdx/node-opentelemetry": "^0.10.3",
31
- "@riocrypto/common": "1.0.2594",
31
+ "@riocrypto/common": "1.0.2595",
32
32
  "@slack/web-api": "^7.15.0",
33
33
  "@types/express": "^4.17.25",
34
34
  "axios": "1.15.2",