PINE LIBRARY

FiniteStateMachine

81
🟩 OVERVIEW

A flexible framework for creating, testing and implementing a Finite State Machine (FSM) in your script. FSMs use rules to control how states change in response to events.

This is the first Finite State Machine library on TradingView and it's quite a different way to think about your script's logic. Advantages of using this vs hardcoding all your logic include:
Explicit logic: You can see all rules easily side-by-side.
Validation: Tables show your rules and validation results right on the chart.
Dual approach: Simple matrix for straightforward transitions; map implementation for concurrent scenarios. You can combine them for complex needs.
Type safety: Shows how to use enums for robustness while maintaining string compatibility.
Real-world examples: Includes both conceptual (traffic lights) and practical (trading strategy) demonstrations.
Priority control: Explicit control over which rules take precedence when multiple conditions are met.
Wildcard system: Flexible pattern matching for states and events.

The library seems complex, but it's not really. Your conditions, events, and their potential interactions are complex. The FSM makes them all explicit, which is some work. However, like all "good" pain in life, this is front-loaded, and *saves* pain later, in the form of unintended interactions and bugs that are very hard to find and fix.


🟩 SIMPLE FSM (MATRIX-BASED)

The simple FSM uses a matrix to define transition rules with the structure: state > event > state. We look up the current state, check if the event in that row matches, and if it does, output the resulting state.
Each row in the matrix defines one rule, and the first matching row, counting from the top down, is applied.
A limitation of this method is that you can supply only ONE event.
You can design layered rules using widlcards. Use an empty string "" or the special string "ANY" for any state or event wildcard.

The matrix FSM is foruse where you have clear, sequential state transitions triggered by single events. Think traffic lights, or any logic where only one thing can happen at a time.
The demo for this FSM is of traffic lights.


🟩 CONCURRENT FSM (MAP-BASED)

The map FSM uses a more complex structure where each state is a key in the map, and its value is an array of event rules. Each rule maps a named condition to an output (event or next state).
This FSM can handle multiple conditions simultaneously. Rules added first have higher priority.
Adding more rules to existing states combines the entries in the map (if you use the supplied helper function) rather than overwriting them.

This FSM is for more complex scenarios where multiple conditions can be true simultaneously, and you need to control which takes precedence. Like trading strategies, or any system with concurrent conditions.
The demo for this FSM is a trading strategy.


🟩 HOW TO USE

Pine Script libraries contain reusable code for importing into indicators. You do not need to copy any code out of here. Just import the library and call the function you want.
For example, for version 1 of this library, import it like this:
Pine Script®
import SimpleCryptoLife/FiniteStateMachine/1

See the EXAMPLE USAGE sections within the library for examples of calling the functions.
For more information on libraries and incorporating them into your scripts, see the Libraries section of the Pine Script User Manual.


🟩 TECHNICAL IMPLEMENTATION

Both FSM implementations support wildcards using blank strings "" or the special string "ANY". Wildcards match in this priority order:
• Exact state + exact event match
• Exact state + empty event (event wildcard)
• Empty state + exact event (state wildcard)
• Empty state + empty event (full wildcard)

When multiple rules match the same state + event combination, the FIRST rule encountered takes priority. In the matrix FSM, this means row order determines priority. In the map FSM, it's the order you add rules to each state.

The library uses user-defined types for the map FSM:
o_eventRule: Maps a condition name to an output
o_eventRuleWrapper: Wraps an array of rules (since maps can't contain arrays directly)

Everything uses strings for maximum library compatibility, though the examples show how to use enums for type safety by converting them to strings.

Unlike normal maps where adding a duplicate key overwrites the value, this library's `m_addRuleToEventMap()` method *combines* rules, making it intuitive to build rule sets without breaking them.


🟩 VALIDATION & ERROR HANDLING

The library includes comprehensive validation functions that catch common FSM design errors:

Error detection:
• Empty next states
• Invalid states not in the states array
• Duplicate rules
• Conflicting transitions
• Unreachable states (no entry/exit rules)

Warning detection:
• Redundant wildcards
• Empty states/events (potential unintended wildcards)
• Duplicate conditions within states

You can display validation results in tables on the chart, with tooltips providing detailed explanations. The helper functions to display the tables are exported so you can call them from your own script.


🟩 PRACTICAL EXAMPLES

The library includes four comprehensive demos:

Traffic Light Demo (Simple FSM): Uses the matrix FSM to cycle through traffic light states (red → red+amber → green → amber → red) with timer events. Includes pseudo-random "break" events and repair logic to demonstrate wildcards and priority handling.

Trading Strategy Demo (Concurrent FSM): Implements a realistic long-only trading strategy using BOTH FSM types:
• Map FSM converts multiple technical conditions (EMA crosses, gaps, fractals, RSI) into prioritised events
• Matrix FSM handles state transitions (idle → setup → entry → position → exit → re-entry)
• Includes position management, stop losses, and re-entry logic

Error Demonstrations: Both FSM types include error demos with intentionally malformed rules to showcase the validation system's capabilities.


🟩 BRING ON THE FUNCTIONS

f_printFSMMatrix(_mat_rules, _a_states, _tablePosition)
  Prints a table of states and rules to the specified position on the chart. Works only with the matrix-based FSM.
  Parameters:
    _mat_rules (matrix<string>)
    _a_states (array<string>)
    _tablePosition (simple string)
  Returns: The table of states and rules.

method m_loadMatrixRulesFromText(_mat_rules, _rulesText)
  Loads rules into a rules matrix from a multiline string where each line is of the form "current state | event | next state" (ignores empty lines and trims whitespace).
This is the most human-readable way to define rules because it's a visually aligned, table-like format.
  Namespace types: matrix<string>
  Parameters:
    _mat_rules (matrix<string>)
    _rulesText (string)
  Returns: No explicit return. The matrix is modified as a side-effect.

method m_addRuleToMatrix(_mat_rules, _currentState, _event, _nextState)
  Adds a single rule to the rules matrix. This can also be quite readble if you use short variable names and careful spacing.
  Namespace types: matrix<string>
  Parameters:
    _mat_rules (matrix<string>)
    _currentState (string)
    _event (string)
    _nextState (string)
  Returns: No explicit return. The matrix is modified as a side-effect.

method m_validateRulesMatrix(_mat_rules, _a_states, _showTable, _tablePosition)
  Validates a rules matrix and a states array to check that they are well formed. Works only with the matrix-based FSM.
Checks: matrix has exactly 3 columns; no empty next states; all states defined in array; no duplicate states; no duplicate rules; all states have entry/exit rules; no conflicting transitions; no redundant wildcards. To avoid slowing down the script unnecessarily, call this method once (perhaps using `barstate.isfirst`), when the rules and states are ready.
  Namespace types: matrix<string>
  Parameters:
    _mat_rules (matrix<string>)
    _a_states (array<string>)
    _showTable (bool)
    _tablePosition (simple string)
  Returns: `true` if the rules and states are valid; `false` if errors or warnings exist.

method m_getStateFromMatrix(_mat_rules, _currentState, _event, _strictInput, _strictTransitions)
  Returns the next state based on the current state and event, or `na` if no matching transition is found. Empty (not na) entries are treated as wildcards if `strictInput` is false.
Priority: exact match > event wildcard > state wildcard > full wildcard.
  Namespace types: matrix<string>
  Parameters:
    _mat_rules (matrix<string>)
    _currentState (string)
    _event (string)
    _strictInput (bool)
    _strictTransitions (bool)
  Returns: The next state or `na`.

method m_addRuleToEventMap(_map_eventRules, _state, _condName, _output)
  Adds a single event rule to the event rules map. If the state key already exists, appends the new rule to the existing array (if different). If the state key doesn't exist, creates a new entry.
  Namespace types: map<string, o_eventRuleWrapper>
  Parameters:
    _map_eventRules (map<string, o_eventRuleWrapper>)
    _state (string)
    _condName (string)
    _output (string)
  Returns: No explicit return. The map is modified as a side-effect.

method m_addEventRulesToMapFromText(_map_eventRules, _configText)
  Loads event rules from a multiline text string into a map structure.
Format: "state | condName > output | condName > output | ..." . Pairs are ordered by priority. You can have multiple rules on the same line for one state.
Supports wildcards: Use an empty string ("") or the special string "ANY" for state or condName to create wildcard rules.
Examples: " | condName > output" (state wildcard), "state | > output" (condition wildcard), " | > output" (full wildcard).
Splits lines by \n, extracts state as key, creates/appends to array<o_eventRule> with new o_eventRule(condName, output).
Call once, e.g., on barstate.isfirst for best performance.
  Namespace types: map<string, o_eventRuleWrapper>
  Parameters:
    _map_eventRules (map<string, o_eventRuleWrapper>)
    _configText (string)
  Returns: No explicit return. The map is modified as a side-effect.

f_printFSMMap(_map_eventRules, _a_states, _tablePosition)
  Prints a table of map-based event rules to the specified position on the chart.
  Parameters:
    _map_eventRules (map<string, o_eventRuleWrapper>)
    _a_states (array<string>)
    _tablePosition (simple string)
  Returns: The table of map-based event rules.

method m_validateEventRulesMap(_map_eventRules, _a_states, _a_validEvents, _showTable, _tablePosition)
  Validates an event rules map to check that it's well formed.
Checks: map is not empty; wrappers contain non-empty arrays; no duplicate condition names per state; no empty fields in o_eventRule objects; optionally validates outputs against matrix events.
NOTE: Both "" and "ANY" are treated identically as wildcards for both states and conditions.
To avoid slowing down the script unnecessarily, call this method once (perhaps using `barstate.isfirst`), when the map is ready.
  Namespace types: map<string, o_eventRuleWrapper>
  Parameters:
    _map_eventRules (map<string, o_eventRuleWrapper>)
    _a_states (array<string>)
    _a_validEvents (array<string>)
    _showTable (bool)
    _tablePosition (simple string)
  Returns: `true` if the event rules map is valid; `false` if errors or warnings exist.

method m_getEventFromConditionsMap(_currentState, _a_activeConditions, _map_eventRules)
  Returns a single event or state string based on the current state and active conditions.
Uses a map of event rules where rules are pre-sorted by implicit priority via load order.
Supports wildcards using empty string ("") or "ANY" for flexible rule matching.
Priority: exact match > condition wildcard > state wildcard > full wildcard.
  Namespace types: series string, simple string, input string, const string
  Parameters:
    _currentState (string)
    _a_activeConditions (array<string>)
    _map_eventRules (map<string, o_eventRuleWrapper>)
  Returns: The output string (event or state) for the first matching condition, or na if no match found.

o_eventRule
  o_eventRule defines a condition-to-output mapping for the concurrent FSM.
  Fields:
    condName (series string): The name of the condition to check.
    output (series string): The output (event or state) when the condition is true.

o_eventRuleWrapper
  o_eventRuleWrapper wraps an array of o_eventRule for use as map values (maps cannot contain collections directly).
  Fields:
    a_rules (array<o_eventRule>): Array of o_eventRule objects for a specific state.

免責事項

これらの情報および投稿は、TradingViewが提供または保証する金融、投資、取引、またはその他の種類のアドバイスや推奨を意図したものではなく、またそのようなものでもありません。詳しくは利用規約をご覧ください。