[fix] #76 백테스트 심볼 슬래시 형식 처리 (BTC/USDT → BTCUSDT 변환)#87
Merged
fray-cloud merged 4 commits intodevfrom Apr 2, 2026
Merged
Conversation
- Add `options?: string[]` to ParamDefinition type - Add options arrays to and-or (AND/OR), crossover (above/below), threshold operator (</>/<=/>==/==), market-order side (buy/sell), and rsi source (close/open/high/low) params - ParamInput renders <select> dropdown when options are present, showing localized labels from PARAM_VALUE_LABELS Co-Authored-By: Paperclip <noreply@paperclip.ing>
Binance API rejects lowercase characters in the symbol parameter (error -1100). Normalize symbol.toUpperCase() at the entry point of both backtest paths so DB keys and API calls are always uppercase. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Normalize BTC/USDT → BTCUSDT by chaining .replace(/\//g, '') after .toUpperCase() in fetchHistoricalCandles(). Fixes Binance 400 error -1100 (Illegal characters in 'symbol') when slash-formatted symbols are used. Closes #76 Co-Authored-By: Paperclip <noreply@paperclip.ing>
Contributor
Reviewer's GuideNormalizes backtest symbols for Binance (uppercasing and removing slashes) to avoid API errors and adds select-box UI support for enum-like flow node parameters by extending param definitions with options metadata and rendering a dropdown when options exist. Sequence diagram for normalized backtest candle fetchingsequenceDiagram
actor User
participant WebApp
participant BacktestsService
participant Redis
participant DataService
participant Database
participant BinanceApi
User->>WebApp: Run backtest(symbol BTC/USDT or btcusdt)
WebApp->>BacktestsService: getBacktestCandles(exchange, symbol, interval, startDate, endDate)
Note over BacktestsService: Normalization
BacktestsService->>BacktestsService: symbol = symbol.toUpperCase()
BacktestsService->>BacktestsService: symbol = symbol.replace(/\//g, "")
BacktestsService->>Redis: get(cacheKey using normalized symbol)
alt cache hit
Redis-->>BacktestsService: cached candles
BacktestsService-->>WebApp: candles
WebApp-->>User: show results
else cache miss
Redis-->>BacktestsService: null
BacktestsService->>DataService: getCandles(exchange, symbol, interval, startTime, endTime)
Note over DataService: Additional uppercasing
DataService->>DataService: symbol = symbol.toUpperCase()
DataService->>Database: loadFromDb(exchange, symbol, interval, startTime, endTime)
alt db hit
Database-->>DataService: stored candles
DataService-->>BacktestsService: candles
else db miss
Database-->>DataService: []
DataService->>BinanceApi: fetchKlines(exchange, symbol, interval, startTime, endTime)
BinanceApi-->>DataService: klines with normalized symbol
DataService->>Database: saveToDb(exchange, symbol, interval, startTime, endTime, candles)
DataService-->>BacktestsService: candles
end
BacktestsService->>Redis: set(cacheKey, candles)
BacktestsService-->>WebApp: candles
WebApp-->>User: show results
end
Updated class diagram for flow param definitions with optionsclassDiagram
class ParamDefinition {
+string key
+boolean required
+string[] options
}
class NodeTypeInfo {
+string subtype
+string name
+string description
+PortDefinition[] inputs
+PortDefinition[] outputs
+Record_string_any defaultConfig
+ParamDefinition[] params
}
class PortDefinition {
+string name
+string type
}
class NodeTypeRegistry {
+Record_string_NodeTypeInfo NODE_TYPE_REGISTRY
}
class RsiParams {
+number period
+string source
}
class ConditionRsiParams {
+string operator
+number threshold
}
class CrossoverParams {
+string direction
}
class AndOrParams {
+string operator
}
class MarketOrderParams {
+string side
+string amount
}
NodeTypeInfo "*" o-- "*" ParamDefinition : params
NodeTypeInfo "*" o-- "*" PortDefinition : inputs_outputs
NodeTypeRegistry ..> NodeTypeInfo : contains
RsiParams ..> ParamDefinition : uses
ConditionRsiParams ..> ParamDefinition : uses
CrossoverParams ..> ParamDefinition : uses
AndOrParams ..> ParamDefinition : uses
MarketOrderParams ..> ParamDefinition : uses
class RsiParamDefinitionExample {
+ParamDefinition period
+ParamDefinition source_options_close_open_high_low
}
class ConditionRsiParamDefinitionExample {
+ParamDefinition operator_options_lt_gt_lte_gte_eq
+ParamDefinition threshold
}
class CrossoverParamDefinitionExample {
+ParamDefinition direction_options_above_below
}
class AndOrParamDefinitionExample {
+ParamDefinition operator_options_AND_OR
}
class MarketOrderParamDefinitionExample {
+ParamDefinition side_options_buy_sell
+ParamDefinition amount
}
RsiParamDefinitionExample ..|> ParamDefinition
ConditionRsiParamDefinitionExample ..|> ParamDefinition
CrossoverParamDefinitionExample ..|> ParamDefinition
AndOrParamDefinitionExample ..|> ParamDefinition
MarketOrderParamDefinitionExample ..|> ParamDefinition
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Symbol normalization is now split between
BacktestsService.getCandles(uppercase + slash removal) andDataService.getCandlesFromExchange(uppercase only); consider centralizing this into a shared helper so all callers (including future ones) consistently get the same fully-normalized symbol. - The new
ParamDefinition.optionsbehavior is wired into the UI but only supports simple string arrays; if you expect more complex option metadata (e.g., value/label pairs or localized labels), it may be worth introducing a typedOptionstructure now instead of overloadingPARAM_VALUE_LABELS.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Symbol normalization is now split between `BacktestsService.getCandles` (uppercase + slash removal) and `DataService.getCandlesFromExchange` (uppercase only); consider centralizing this into a shared helper so all callers (including future ones) consistently get the same fully-normalized symbol.
- The new `ParamDefinition.options` behavior is wired into the UI but only supports simple string arrays; if you expect more complex option metadata (e.g., value/label pairs or localized labels), it may be worth introducing a typed `Option` structure now instead of overloading `PARAM_VALUE_LABELS`.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 사항
/) 제거 처리 (BTC/USDT→BTCUSDT).toUpperCase())관련 이슈
Closes #76
테스트 방법
BTC/USDT및btcusdt형식으로 백테스트 실행 → 정상 동작 확인/klinesAPI 호출 시 심볼 형식 오류(400) 미발생 확인참고
Co-Authored-By: Paperclip noreply@paperclip.ing
Summary by Sourcery
Add selectable parameter options to flow node inspector and normalize backtest symbols for Binance API compatibility.
New Features:
Bug Fixes:
Enhancements: