From 6af0db0d6d5c3016c6ba4916a12589cce467a297 Mon Sep 17 00:00:00 2001 From: Zheng Chen Date: Sun, 18 Feb 2024 10:33:19 +0800 Subject: [PATCH] fix(docs): shannon strategy updated (#433) * fix(kernel): enforce order matching round by volume_step * fix(docs): shannon strategy updated * fix(gui): Static Product Loading * refactor(agent): remove use_general_product * fix(docs): some fixes --- .../@yuants/agent/2024-02-18-01-42.json | 10 +++ .../@yuants/kernel/2024-02-18-01-40.json | 10 +++ .../@yuants/kernel/2024-02-18-01-42.json | 10 +++ libraries/agent/etc/agent.api.md | 1 - libraries/agent/src/AgentScene.ts | 12 +-- libraries/kernel/etc/kernel.api.md | 10 +-- .../kernel/src/units/OrderMatchingUnit.ts | 7 +- .../kernel/src/units/ProductLoadingUnit.ts | 88 ++----------------- .../docs/basics/how-to-calculate-margin.md | 34 +++++-- ui/docs/docs/basics/what-is-product.md | 3 +- .../creating-your-first-strategy.md | 7 +- .../creating-your-first-strategy.md | 7 +- ui/web/public/locales/en/AgentConfForm.json | 4 - .../public/locales/zh-Hans/AgentConfForm.json | 4 - .../Copilot/components/AgentConfigForm.tsx | 1 - .../StaticFileServerPeriodLoadingUnit.ts | 2 - 16 files changed, 88 insertions(+), 122 deletions(-) create mode 100644 common/changes/@yuants/agent/2024-02-18-01-42.json create mode 100644 common/changes/@yuants/kernel/2024-02-18-01-40.json create mode 100644 common/changes/@yuants/kernel/2024-02-18-01-42.json diff --git a/common/changes/@yuants/agent/2024-02-18-01-42.json b/common/changes/@yuants/agent/2024-02-18-01-42.json new file mode 100644 index 000000000..c538e4bf4 --- /dev/null +++ b/common/changes/@yuants/agent/2024-02-18-01-42.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@yuants/agent", + "comment": "remove use_general_product", + "type": "minor" + } + ], + "packageName": "@yuants/agent" +} \ No newline at end of file diff --git a/common/changes/@yuants/kernel/2024-02-18-01-40.json b/common/changes/@yuants/kernel/2024-02-18-01-40.json new file mode 100644 index 000000000..8622f7b8a --- /dev/null +++ b/common/changes/@yuants/kernel/2024-02-18-01-40.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@yuants/kernel", + "comment": "enforce order matching round by volume_step", + "type": "patch" + } + ], + "packageName": "@yuants/kernel" +} \ No newline at end of file diff --git a/common/changes/@yuants/kernel/2024-02-18-01-42.json b/common/changes/@yuants/kernel/2024-02-18-01-42.json new file mode 100644 index 000000000..86456de44 --- /dev/null +++ b/common/changes/@yuants/kernel/2024-02-18-01-42.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@yuants/kernel", + "comment": "remove use_general_product", + "type": "minor" + } + ], + "packageName": "@yuants/kernel" +} \ No newline at end of file diff --git a/libraries/agent/etc/agent.api.md b/libraries/agent/etc/agent.api.md index a76d5786b..bb9d23968 100644 --- a/libraries/agent/etc/agent.api.md +++ b/libraries/agent/etc/agent.api.md @@ -112,7 +112,6 @@ export interface IAgentConf { is_real?: boolean; kernel_id?: string; start_time?: string; - use_general_product?: boolean; } // @public diff --git a/libraries/agent/src/AgentScene.ts b/libraries/agent/src/AgentScene.ts index e062b3c2f..61b0cb6ef 100644 --- a/libraries/agent/src/AgentScene.ts +++ b/libraries/agent/src/AgentScene.ts @@ -47,8 +47,6 @@ export interface IAgentConf { /** Kernel ID */ kernel_id?: string; - /** 使用标准品种信息 */ - use_general_product?: boolean; /** 是否禁用打印日志 */ disable_log?: boolean; } @@ -91,12 +89,6 @@ export const agentConfSchema: JSONSchema7 = { type: 'string', default: 'Model', }, - use_general_product: { - type: 'boolean', - title: '使用标准品种信息', - description: '使用标准品种信息作为品种信息,但仍沿用具体品种的行情数据', - default: false, - }, disable_log: { type: 'boolean', title: '禁用打印日志', @@ -122,9 +114,7 @@ export const AgentScene = async (terminal: Terminal, agentConf: IAgentConf) => { kernel.log = undefined; } const productDataUnit = new ProductDataUnit(kernel); - const productLoadingUnit = new ProductLoadingUnit(kernel, terminal, productDataUnit, { - use_general_product: agentConf.use_general_product, - }); + const productLoadingUnit = new ProductLoadingUnit(kernel, terminal, productDataUnit); const quoteDataUnit = new QuoteDataUnit(kernel); const tickDataUnit = new TickDataUnit(kernel); const periodDataUnit = new PeriodDataUnit(kernel, quoteDataUnit); diff --git a/libraries/kernel/etc/kernel.api.md b/libraries/kernel/etc/kernel.api.md index 28f268585..5bdf17e4c 100644 --- a/libraries/kernel/etc/kernel.api.md +++ b/libraries/kernel/etc/kernel.api.md @@ -617,9 +617,7 @@ export class ProductDataUnit extends BasicUnit { // @public export class ProductLoadingUnit extends BasicUnit { - constructor(kernel: Kernel, terminal: Terminal, productDataUnit: ProductDataUnit, options?: { - use_general_product?: boolean | undefined; - } | undefined); + constructor(kernel: Kernel, terminal: Terminal, productDataUnit: ProductDataUnit, options?: {} | undefined); // (undocumented) dump(): { productTasks: { @@ -632,9 +630,7 @@ export class ProductLoadingUnit extends BasicUnit { // (undocumented) onInit(): Promise; // (undocumented) - options?: { - use_general_product?: boolean | undefined; - } | undefined; + options?: {} | undefined; // (undocumented) productDataUnit: ProductDataUnit; // (undocumented) @@ -778,7 +774,7 @@ export class TickDataUnit extends BasicUnit { // Warnings were encountered during analysis: // -// src/units/OrderMatchingUnit.ts:270:11 - (ae-forgotten-export) The symbol "IMatchingRange" needs to be exported by the entry point index.d.ts +// src/units/OrderMatchingUnit.ts:275:11 - (ae-forgotten-export) The symbol "IMatchingRange" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/libraries/kernel/src/units/OrderMatchingUnit.ts b/libraries/kernel/src/units/OrderMatchingUnit.ts index 1c156549d..0450cbdb3 100644 --- a/libraries/kernel/src/units/OrderMatchingUnit.ts +++ b/libraries/kernel/src/units/OrderMatchingUnit.ts @@ -1,5 +1,6 @@ import { encodePath } from '@yuants/data-model'; import { IOrder, IPeriod, ITick, OrderDirection, OrderStatus, OrderType } from '@yuants/protocol'; +import { roundToStep } from '@yuants/utils'; import { Subject, Subscription } from 'rxjs'; import { Kernel } from '../kernel'; import { AccountInfoUnit } from './AccountInfoUnit'; @@ -214,11 +215,15 @@ export class OrderMatchingUnit extends BasicUnit { continue; } isSomeOrderTraded = true; + const theProduct = this.productDataUnit.mapProductIdToProduct[order.product_id]; + const volume_step = theProduct.volume_step ?? 1; + const volume = roundToStep(order.volume, volume_step); const theOrder = { ...order, timestamp_in_us: this.kernel.currentTimestamp * 1000, traded_price: tradedPrice, - traded_volume: order.volume, + volume, + traded_volume: volume, status: OrderStatus.TRADED, }; // 成交 diff --git a/libraries/kernel/src/units/ProductLoadingUnit.ts b/libraries/kernel/src/units/ProductLoadingUnit.ts index f963242b1..665b20399 100644 --- a/libraries/kernel/src/units/ProductLoadingUnit.ts +++ b/libraries/kernel/src/units/ProductLoadingUnit.ts @@ -1,24 +1,12 @@ import { formatTime } from '@yuants/data-model'; import { IProduct, Terminal } from '@yuants/protocol'; -import { defaultIfEmpty, filter, lastValueFrom, map, mergeMap, of, tap, throwIfEmpty, toArray } from 'rxjs'; +import { defaultIfEmpty, lastValueFrom, map, tap } from 'rxjs'; import { Kernel } from '../kernel'; import { BasicUnit } from './BasicUnit'; import { ProductDataUnit } from './ProductDataUnit'; -// GSR -interface IGeneralSpecificRelation { - // general_datasource_id 一定是 Y 常量,因此不需要特别存储 - // general_datasource_id: string; - /** 标准品种ID */ - general_product_id: string; // XAUUSD - /** 具体数据源 ID */ - specific_datasource_id: string; // TradingView - /** 具体品种 ID */ - specific_product_id: string; // FX:XAUUSD -} - /** - * 品种加载单元 + * Product Loading Unit: load product info from storage * @public */ export class ProductLoadingUnit extends BasicUnit { @@ -26,20 +14,21 @@ export class ProductLoadingUnit extends BasicUnit { public kernel: Kernel, public terminal: Terminal, public productDataUnit: ProductDataUnit, - public options?: { - use_general_product?: boolean; - }, + public options?: {}, ) { super(kernel); } productTasks: { datasource_id: string; product_id: string }[] = []; async onInit() { - this.kernel.log?.(formatTime(Date.now()), `开始加载品种信息: 共 ${this.productTasks.length} 个品种`); + this.kernel.log?.( + formatTime(Date.now()), + `start product loading: all ${this.productTasks.length} product(s)`, + ); for (const task of this.productTasks) { this.kernel.log?.( formatTime(Date.now()), - `正在加载 ${task.datasource_id} / ${task.product_id} 的品种信息...`, + `product loading: ${task.datasource_id} / ${task.product_id}`, ); await lastValueFrom( this.terminal @@ -48,72 +37,13 @@ export class ProductLoadingUnit extends BasicUnit { tags: { datasource_id: task.datasource_id, product_id: task.product_id }, }) .pipe( - // ISSUE: 有时候确实没有定义这个品种,技术指标观察器的场景中只需要行情数据,不强制需要品种信息 - // 在其他场景中,如果忘记配置品种信息,造成的潜在危害更大,因此用配置按需抑制此错误 map((x) => x.origin), - mergeMap((specificProduct) => { - this.kernel.log?.(formatTime(Date.now()), `具体品种`, JSON.stringify(specificProduct)); - if (specificProduct.datasource_id !== 'Y' && this.options?.use_general_product) { - return this.terminal - .queryDataRecords({ type: 'general_specific_relation' }) - .pipe( - map((x) => x.origin), - filter( - (x) => - x.specific_datasource_id === task.datasource_id && - x.specific_product_id === task.product_id, - ), - throwIfEmpty( - () => new Error(`无法找到 ${task.datasource_id} / ${task.product_id} 的标准品种关系`), - ), - map((x) => x.general_product_id), - tap((general_product_id) => { - this.kernel.log?.(formatTime(Date.now()), `匹配标准品种 "${general_product_id}"`); - }), - ) - .pipe( - mergeMap((general_product_id) => - this.terminal - .queryDataRecords({ - type: 'product', - tags: { datasource_id: 'Y', product_id: general_product_id }, - }) - .pipe( - // - throwIfEmpty(() => new Error(`无法找到 ${general_product_id} 的标准品种`)), - map((x) => x.origin), - tap((generalProduct) => { - this.kernel.log?.( - formatTime(Date.now()), - `获取标准品种 "${generalProduct.product_id}"`, - JSON.stringify(generalProduct), - ); - }), - map((generalProduct) => ({ - ...generalProduct, - datasource_id: specificProduct.datasource_id, - product_id: specificProduct.product_id, - })), - ), - ), - // 此处代码是多余的,但是为了避免后续的代码出现问题,保留此处代码 - throwIfEmpty(() => new Error(`无法找到标准品种`)), - ); - } - return of(specificProduct); - }), - defaultIfEmpty({ datasource_id: task.datasource_id, product_id: task.product_id, }), tap((product) => { - this.kernel.log?.( - formatTime(Date.now()), - `加载到 ${product.datasource_id}/${product.product_id} 品种`, - JSON.stringify(product), - ); - // Issue: 如果不推到 products 列表中可能会导致后续的性能审计遇到一些问题 + this.kernel.log?.(formatTime(Date.now()), 'product loaded', JSON.stringify(product)); this.productDataUnit.mapProductIdToProduct[product.product_id] = product; }), ), diff --git a/ui/docs/docs/basics/how-to-calculate-margin.md b/ui/docs/docs/basics/how-to-calculate-margin.md index 65e1f220b..0a60d7712 100644 --- a/ui/docs/docs/basics/how-to-calculate-margin.md +++ b/ui/docs/docs/basics/how-to-calculate-margin.md @@ -8,11 +8,27 @@ sidebar_position: 5 The standard margin model is: -Used Margin = sum of all positions' used margin / account's leverage. - -- Each position's used margin = Position Volume \* Product Value Speed \* Factor of Asset \* Base Currency Exchange Rate \* Product Margin Rate -- Factor of Asset = 1 if FX or Bond Spot, otherwise Open Price of Position. -- Base Currency Exchange Rate = the exchange rate of **product's base currency** vs **account's margin currency** at the time of position opening. +$$ +\text{Standard Margin} = \frac{\sum_{\text{Position}} {\text{Volume} \times \text{Value Scale}} \times P(\text{Value Scale Unit}, C, t_1) \times P(C, A, t_1) \times \text{Margin Rate} }{\text{Account Leverage}} +$$ + +When: + +- $A$ is the account's margin currency; $B$ is the product itself; $C$ is the product's quote currency; +- For any assets $x$, $y$ and time $t$, $P(x, y, t)$ is the price of two assets $x$ vs $y$ at time $t$, and $t_1$ is the time of position entering; $t_2$ is the time of position exiting; +- $P(B, C, t)$ is the price of the product at time $t$; You can see it directly everywhere in the market; +- Volume is the number of contract, non-negative; +- Open Price $P(B, C, t_1)$ is the price of the product at the time of position entering; +- Value scale is a constant multiple item for the product, usually 1 in spots, and is called "contract size" in futures or options contracts. +- Margin rate is a constant multiple item for the product, equivalent 1 in spots, and less than 1 in leverage trading. +- $P(C, A, t)$ is the exchange rate of the quote currency vs the margin currency at time $t$; + - if the quote currency is the same as the margin currency, then $P(C, A, t) = 1$, you can ignore this item; +- Value scale unit is the unit of value scale, usually refers to the product itself ($B$), or the product's quote currency ($C$); + - if it refers to the product itself, then $P(\text{Value Scale Unit}, C, t_1) = P(B, C, t_1) = \text{Open Price}$; + - if it refers to the product's quote currency, then $P(\text{Value Scale Unit}, C, t_1) = P(C, C, t_1) = 1$; + - for example, if the product specified that 1 contract = 100 shares of stock, then the value scale unit is the stock itself, and the value scale is 100; + - for another example, if the product specified that 1 contract = stocks worth 1000 USD, then the value scale unit is the quote currency, and the value scale is 1000; +- Actually when the quote currency and margin currency are different, it is not possible to directly obtain the precise exchange rate $P(C, A, t_1)$. However, the exchange usually directly shows the precise standard margin in the history orders. So we can deduce the exchange rate $P(C, A, t_1)$ from the standard margin. Once a position is opened, the used margin will not change with the price. @@ -20,7 +36,9 @@ Once a position is opened, the used margin will not change with the price. The available margin will fluctuate with the fluctuation of the equity, and the necessary condition for opening a position is that the available margin is not less than the margin required to open the position. -**Margin-equity ratio** = 100% \* used margin / equity +$$ +\text{Margin-equity Ratio} = \frac{\text{Used Margin}}{Equity} \times 100\% +$$ Margin-equity ratio is used to measure the overall risk of an account. @@ -30,7 +48,9 @@ Margin-equity ratio is used to measure the overall risk of an account. When the margin-equity ratio is too low, it means that the account funds are not fully utilized. -Actual leverage ratio = Margin-equity ratio \* account leverage ratio +$$ +\text{Actual Leverage} = \text{Margin-equity ratio} \times \text{Account Leverage} +$$ Sometimes we are more inclined to use the actual leverage ratio to express the utilization rate of funds. When the actual leverage ratio is less than 100%, it means that no matter how the price fluctuates, as long as it is non-negative , the account will not be liquidated to zero. However, if the volatility of the variety price is very small, using too little leverage will waste the funds in the account. Therefore, the setting of the actual leverage ratio should be related to the volatility of the trading variety price. However, in the stock market, unless financing and securities lending, since the account leverage ratio is 1, the actual leverage ratio cannot exceed 100%. diff --git a/ui/docs/docs/basics/what-is-product.md b/ui/docs/docs/basics/what-is-product.md index 753e9a67d..235485254 100644 --- a/ui/docs/docs/basics/what-is-product.md +++ b/ui/docs/docs/basics/what-is-product.md @@ -17,8 +17,9 @@ The specifications for evaluating products have the following dimensions: | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `product_id` | (**Required**) Which product does this specification information belong to? How to distinguish it from other products? | `"XAUUSD"` | | `datasource_id` | (**Required**) Who provided this specification information? | `"Y"` | -| `currency` | (**Required**) What currency is used for trading this product? | `"USD"` | | `name` | How do humans generally refer to this species? | `"Gold Spot vs US Dollar"` | +| `quote_currency` | The quote currency to price the product. | `"USD"` | +| `base_currency` | Only available in foreign exchange product. If defined, the price of this product (P(this, quote_currency)) can be treated as P(base_currency, quote_currency) | | | `value_scale` | How many units of the subject matter is equivalent to 1 lot? How much profit and loss will be generated by changes in unit prices? Some places are also called "contract multipliers". Default to 1 | `100` | | `value_scale_unit` | What is the unit of this value scale? Leave it undefined if unit is product itself. Or set to currency if needed. | | | `price_step` | What is the minimum price per hop for this product? The quoted price in the market must be an integer multiple of this unit. However, the actual transaction price does not need to comply with this constraint. Default to 1 | `0.01` | diff --git a/ui/docs/docs/tutorial-basics/creating-your-first-strategy.md b/ui/docs/docs/tutorial-basics/creating-your-first-strategy.md index a9544e7b8..e3a2a1bc0 100644 --- a/ui/docs/docs/tutorial-basics/creating-your-first-strategy.md +++ b/ui/docs/docs/tutorial-basics/creating-your-first-strategy.md @@ -96,6 +96,7 @@ export default () => { const datasource_id = useParamString('DataSource', 'Y'); const product_id = useParamString('Product'); const period = useParamString('Period', 'PT1H'); + const currency = useParamString('Currency', 'USD'); // Get the product information and price data const product = useProduct(datasource_id, product_id); const { close } = useOHLC(datasource_id, product_id, period); @@ -155,7 +156,7 @@ export default () => { const initial_balance = useParamNumber('Initial Balance', 100_000); const threshold = useParamNumber('Threshold', 1); // Get the account information - const accountInfo = useAccountInfo(); + const accountInfo = useAccountInfo({ currency }); // Use a simple position manager const [actualVolume, setVolume] = useSimplePositionManager(accountInfo.account_id, product_id); // Re-balance the position @@ -166,7 +167,9 @@ export default () => { const totalValueToHold = totalValue * 0.5; // infer the volume to hold const valuePerVolume = - price * (product.value_speed ?? 1) * (product.is_underlying_base_currency ? -1 / price : 1); + (product.value_scale ?? 1) * + (product.value_scale_unit ? 1 : price) * + (product.quote_currency === accountInfo.money.currency ? 1 : -1 / price); const expectedVolume = totalValueToHold / valuePerVolume; // calculate the error rate const volume_step = product.volume_step ?? 1; diff --git a/ui/docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/tutorial-basics/creating-your-first-strategy.md b/ui/docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/tutorial-basics/creating-your-first-strategy.md index 318f4cae4..8fff90770 100644 --- a/ui/docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/tutorial-basics/creating-your-first-strategy.md +++ b/ui/docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/tutorial-basics/creating-your-first-strategy.md @@ -96,6 +96,7 @@ export default () => { const datasource_id = useParamString('DataSource', 'Y'); const product_id = useParamString('Product'); const period = useParamString('Period', 'PT1H'); + const currency = useParamString('Currency', 'USD'); // 获取品种信息和价格数据 const product = useProduct(datasource_id, product_id); const { close } = useOHLC(datasource_id, product_id, period); @@ -155,7 +156,7 @@ export default () => { const initial_balance = useParamNumber('Initial Balance', 100_000); const threshold = useParamNumber('Threshold', 1); // 获取账户信息 - const accountInfo = useAccountInfo(); + const accountInfo = useAccountInfo({ currency }); // 使用单一头寸管理器 const [actualVolume, setVolume] = useSimplePositionManager(accountInfo.account_id, product_id); // 重新平衡头寸 @@ -166,7 +167,9 @@ export default () => { const totalValueToHold = totalValue * 0.5; // 推断要持有的头寸量 const valuePerVolume = - price * (product.value_speed ?? 1) * (product.is_underlying_base_currency ? -1 / price : 1); + (product.value_scale ?? 1) * + (product.value_scale_unit ? 1 : price) * + (product.quote_currency === accountInfo.money.currency ? 1 : -1 / price); const expectedVolume = totalValueToHold / valuePerVolume; // 计算误差率 const volume_step = product.volume_step ?? 1; diff --git a/ui/web/public/locales/en/AgentConfForm.json b/ui/web/public/locales/en/AgentConfForm.json index cfaf7aa3a..b17d6a5ce 100644 --- a/ui/web/public/locales/en/AgentConfForm.json +++ b/ui/web/public/locales/en/AgentConfForm.json @@ -68,10 +68,6 @@ "description": "Pull the starting point of the interval of historical data in advance; leave it blank to pull infinitely early data; fill in the time zone according to the local time zone", "title": "Start Time of History" }, - "root_use_general_product": { - "description": "Treat general product as product", - "title": "Use General Product" - }, "run": "Run", "run_failed": "Failed to run the model instance, please check if there is a problem with the code or configuration", "run_succeed": "Run completed", diff --git a/ui/web/public/locales/zh-Hans/AgentConfForm.json b/ui/web/public/locales/zh-Hans/AgentConfForm.json index 8c238e6e0..cc0b3eeb1 100644 --- a/ui/web/public/locales/zh-Hans/AgentConfForm.json +++ b/ui/web/public/locales/zh-Hans/AgentConfForm.json @@ -68,10 +68,6 @@ "description": "提前拉取历史数据的区间起点;留空表示拉取无穷早的数据;时区按照本地时区填写", "title": "历史数据开始时间" }, - "root_use_general_product": { - "description": "使用标准品种信息作为品种信息", - "title": "使用标准品种信息" - }, "run": "运行", "run_failed": "运行模型实例失败,请检查代码或配置是否有问题", "run_succeed": "运行完毕", diff --git a/ui/web/src/modules/Copilot/components/AgentConfigForm.tsx b/ui/web/src/modules/Copilot/components/AgentConfigForm.tsx index 415152ac1..78518ea6f 100644 --- a/ui/web/src/modules/Copilot/components/AgentConfigForm.tsx +++ b/ui/web/src/modules/Copilot/components/AgentConfigForm.tsx @@ -46,7 +46,6 @@ export default ({ is_real: false, kernel_id: 'Model', disable_log: true, - use_general_product: false, }; const validator = new Ajv({ strictSchema: false }); const isValid = validator.validate(payload.schema, formData); diff --git a/ui/web/src/modules/StaticFileServerStorage/StaticFileServerPeriodLoadingUnit.ts b/ui/web/src/modules/StaticFileServerStorage/StaticFileServerPeriodLoadingUnit.ts index a02fa46b1..47f050aa4 100644 --- a/ui/web/src/modules/StaticFileServerStorage/StaticFileServerPeriodLoadingUnit.ts +++ b/ui/web/src/modules/StaticFileServerStorage/StaticFileServerPeriodLoadingUnit.ts @@ -59,7 +59,6 @@ export class StaticFileServerPeriodLoadingUnit extends BasicUnit { price_step: +(raw.price_step || 1), volume_step: +(raw.volume_step || 1), value_scale: +(raw.value_scale || 1), - value_speed: +(raw.value_speed || 1), margin_rate: +(raw.margin_rate || 1), spread: +(raw.spread || 0), allow_long: raw.allow_long === 'true', @@ -75,7 +74,6 @@ export class StaticFileServerPeriodLoadingUnit extends BasicUnit { ] || { datasource_id: task.datasource_id, product_id: task.product_id, - base_currency: 'YYY', }; } }