# TradingBot25 Strategy Guidelines

This document outlines the guidelines for refactoring and improving the PineScript trading strategy in this repository. The goal is to maintain the strategy's good performance while improving its structure and maintainability. This document is a living document and should be updated as the project evolves.

## Guiding Principles

*   **PRIMARY DIRECTIVE: ALWAYS VERIFY BEFORE ACTING.** Before you propose or execute *any* code change, file operation, or command, you must first use the available tools (`read_file`, `ls`, `git diff`, etc.) to verify the current state of the relevant files. You are forbidden from relying on your memory or previous turns. Every action must be based on a fresh, verified understanding of the codebase. Failure to do so is a critical error.
*   **Verify All File Writes:** After every `write_file` or `replace` operation, you MUST immediately use the `read_file` tool on the same file to confirm that the changes were written correctly. You are not to report success to the user until you have visually verified the new content in the file.
*   **Do Not Automatically Restart Tasks:** If a user cancels a task, do not automatically restart it. Assume the user has a reason for the cancellation. If you believe the task is still necessary, you must ask the user for confirmation before proceeding.
*   **Targeted Changes:** All modifications should be focused on specific, isolated areas of the code. Avoid broad, sweeping changes that affect multiple, unrelated parts of the strategy.
*   **Minimalism:** Only change what is absolutely necessary to achieve the desired improvement. If a piece of code is working correctly and is not directly related to the task at hand, it should be left untouched.
*   **Preserve Performance:** The primary goal is to refactor the code without negatively impacting the strategy's performance. All changes should be made with this in mind.
*   **Modularity:** The monolithic codebase should be broken down into smaller, more manageable components. This will make the code easier to understand, test, and maintain.

## Code Formatting Rules

1.  **Indentation:** Use 4 spaces for each indentation level (a "tab").
2.  **Line Length:** Aim for a maximum line length of 150 characters to improve readability.
3.  **Line Continuation:**
    *   When a line is too long, it should be broken up.
    *   The continued line must be indented with at least one additional level of indentation (4 spaces) plus one extra space, for a total of at least 5 spaces. A standard of 8 spaces (two tabs) is preferred for consistency.
    *   For long string concatenations, align the `+` operators for readability.
4.  **Function and Type Declarations:**
    *   Keep function and type declarations on a single line if they are short.
    *   If a declaration is long, break it after the `=>` or at the parameter list, and indent the following lines.
5.  **Logical Expressions:**
    *   For long logical expressions (like in `if` statements), break the line after a logical operator (`or`, `and`). Each subsequent line should be indented and aligned.

## Coding & Naming Standards

### Coding Standards
*   **PineScript Version:** All new `.pine` script and library files must begin with `//@version=6`.
*   **No Nested Functions:** Avoid defining functions inside of other functions (nesting). All helper functions should be defined at the top level of a library script to prevent potential compiler errors and improve readability.
*   **Object Instantiation:** When creating a new object from a type, instantiate the object first, then assign its properties individually. This avoids potential compiler errors with long argument lists in the `new()` method.
*   **Function Documentation:** All exported functions in PineScript libraries must be preceded by a documentation block that explains the function's purpose, parameters, and return values. This aids in code readability and enables editor features like tooltips and auto-completion. The format is as follows:
    ```pinescript
    // <description>
    // @param <name> (<type>) <description>
    // @returns (<type>) <description>
    ```
*   **Handling Custom Type Returns:** When a library function returns a custom `type` object, the calling script must first assign the returned object to a single variable. The fields of the object can then be accessed from this variable. Do not attempt to destructure the object into a tuple directly on assignment, as this will cause a compiler error.
*   **History-Referencing with Custom Types:** When accessing historical values of a field within a custom `type` object that is passed into a function, you cannot use the history-referencing operator `[]` directly on the field (e.g., `inputs.my_field[1]`). This will cause a compiler error. Instead, you must first reference the historical object itself, and *then* access the field, like so: `(inputs[1]).my_field`.
    *   **Correct:**
        ```pinescript
        // Accessing the 'close' value from the previous bar
        previous_close = (inputs[1]).close
        ```
    *   **Incorrect:**
        ```pinescript
        // This will cause a compiler error
        previous_close = inputs.close[1]
        ```
*   **Strict Type Initialization:** When declaring a variable with an explicit type, it must be initialized with a value of that same type. You cannot initialize a `bool` with `na`, as `na` is a special float value.
    *   **Problem:**
        ```pinescript
        bool my_flag = na // COMPILE ERROR! Cannot assign 'na' to a 'bool'.
        ```
    *   **Solution:** Initialize the variable with a valid default value for its type. For booleans, this is typically `false`.
        ```pinescript
        bool my_flag = false
        ```
*   **Declaration Before Use:** All variables must be declared and calculated *before* they are used. This is especially critical when populating `type` objects to be passed into library functions. Ensure that the calculation pipeline is sequential and that no variable is referenced before its value has been computed for the current bar.
    *   **Problem:**
        ```pinescript
        my_inputs = MyType.new()
        my_inputs.value := my_calculated_value // ERROR: my_calculated_value is not yet defined.
        
        my_calculated_value = ta.ema(close, 10)
        ```
    *   **Solution:** Reorder the script to ensure calculations happen before use.
        ```pinescript
        my_calculated_value = ta.ema(close, 10)
        my_inputs = MyType.new()
        my_inputs.value := my_calculated_value // This is now correct.
        ```
*   **Preventing Unintentional Type Promotion:** Pine Script automatically promotes a variable from a `simple` type to a `series` type if it is reassigned within any conditional (`if`, `switch`) or looping (`for`) block. This can cause compilation errors when that variable is later passed to a function that requires a `simple` type.
    *   **Problem:**
        ```pinescript
        my_length = input.int(14) // my_length is a 'simple int'
        if (condition)
            my_length := 28       // my_length is now a 'series int'
        plot(ta.sma(close, my_length)) // COMPILE ERROR! sma() needs a 'simple int'.
        ```
    *   **Solution (The "New Variable" Rule):** Never reassign a `simple` variable inside a conditional block if it needs to remain `simple`. Instead, create a **new** variable to hold the conditional value. This preserves the original variable's `simple` type.
        ```pinescript
        my_simple_length = input.int(14)
        my_series_length = condition ? 28 : my_simple_length
        // Now you can use the correct variable for the correct function.
        ```
*   **Handling Tuple Assignments in Conditional Blocks:** Pine Script has strict and non-obvious rules when assigning multiple return values (a tuple) from a function inside a conditional block (`if/else`). Attempts to follow the DRY (Don't Repeat Yourself) principle by calling the function only once can lead to a cycle of compilation errors.
    *   **Problem:** You need to call a function that returns a tuple (`[val1, val2]`) and assign the results to variables, but the function call depends on a condition.
    *   **Incorrect Patterns (To Be Avoided):**
        ```pinescript
        // Fails: The ternary operator cannot return a tuple.
        [hband, lband] = isDaily ? my_func(1) : my_func(2)

        // Fails: The ':=' operator cannot be combined with tuple destructuring `[...]`.
        if isDaily
            [hband, lband] := my_func(1)
        else
            [hband, lband] := my_func(2)

        // Fails: A temporary tuple variable creates scope and assignment issues.
        var my_tuple = na
        if isDaily
            my_tuple := my_func(1) // This pattern is prone to errors.
        // ...
        ```
    *   **Solution (The "Repetitive but Correct" Rule):** To ensure correct compilation, you **must** call the function inside each branch of the `if/else` block and assign the results directly. This is an exception to the DRY principle that is required by Pine Script's syntax.
        ```pinescript
        var float hband = na, var float lband = na // Declare with 'var'
        if isDaily
            [hband, lband] := my_func(1) // Correct: Call function in each branch.
        else
            [hband, lband] := my_func(2)
        ```
*   **Exporting Constant Data from Libraries:** The `export` keyword can only be used for functions and `type` definitions; it cannot be used on variables. To share constant data like an array of strings or colors from a library, you must use a "getter" function pattern. The array should be declared with `var` *inside* the exported function. This ensures it is initialized only once for performance, but its scope is local to the function, which satisfies the compiler's global scope restrictions.
    *   **Correct:**
        ```pinescript
        // In a library
        export get_my_constants() =>
            var array<string> _MY_CONSTANTS = ["a", "b", "c"]
            _MY_CONSTANTS
        ```
    *   **Incorrect (will not compile):**
        ```pinescript
        export const array<string> MY_CONSTANTS = ["a", "b", "c"]
        ```

### Naming Conventions

To maintain consistency and readability across the codebase, the following naming conventions should be followed:

*   **Inputs:** All user-configurable inputs should be prefixed with `i_`. For example: `i_enableShort`.
*   **Input Groups:** Input group names should be prefixed with `group_`. For example: `group_main_algo_settings`.
*   **Functions:** Helper functions defined within the script should be prefixed with `f_`. For example: `f_apply_smoothing`.
*   **Booleans:** Boolean variables should be named to sound like questions where possible, e.g., `isMacdHistRising`.
*   **Variables:** Use camelCase for local variables (e.g., `longEntryReasonsDetailed`) and snake_case for global variables and constants (e.g., `m3_global_smoothed`).

## Refactoring Guidelines

### General Process

1.  **Identify Areas for Improvement:** Before making any changes, identify specific areas of the code that would benefit from refactoring. This could include complex functions, duplicated code, or tightly coupled components.
2.  **Check naming:** Review the variable and function names for the area of code selected for refactor, if variables could be renamed for clarity and better context then suggest that renaming first. If names are changed then ask the user to backtest just to make sure no functionality was inadvertently broken.
2.  **Isolate:** Once an area for improvement has been identified and optional renaming completed, then isolate it from the rest of the codebase.
3.  **Refactor:** Refactor the isolated code, focusing on improving its structure, documentation and readability.
4.  **Backtest:** After any refactoring, the user must perform backtesting to ensure that the changes have not introduced any new bugs or negatively impacted the strategy's performance. No commit should be suggested before backtesting is complete and successful.
5.  **Test and Verify:** After backtesting, thoroughly test the changes to ensure that they have not introduced any new bugs or negatively impacted the strategy's performance.
6.  **Integrate and Repeat:** Once the refactored code has been tested and verified, integrate it back into the main codebase. Repeat the process for other areas of the code that require refactoring.

### Creating PineScript Libraries

*   **Managing High Parameter Counts (The 254-Element Limit):** Pine Script imposes a hard limit of 254 "external elements" for a function call. This includes not only the direct parameters to a function but also all the individual fields within a custom `type` object when you create it (e.g., `MyType.new()`). A flattened object with too many fields will exceed this limit.
    *   **Problem:** A single, large input object can be easy to manage but will fail if it grows too large.
    *   **Solution (Hybrid Object Model):** To solve this, break down the single large object into multiple, smaller, logically-grouped `type` objects (e.g., `EnablementInputs`, `MACDInputs`, `RSIInputs`). The library function should then accept these smaller objects as distinct parameters. This keeps the code organized and respects the compiler limit.
    *   **Example:**
        ```pinescript
        // In Library
        export type RSIInputs
            int length
            float level

        export type MACDInputs
            int fast
            int slow

        export f_calculate(RSIInputs rsi, MACDInputs macd) =>
            // ... logic using rsi.length and macd.fast

        // In Main Script
        rsi_inputs = RSIInputs.new(14, 70)
        macd_inputs = MACDInputs.new(12, 26)
        myLib.f_calculate(rsi_inputs, macd_inputs)
        ```

*   **Check for Existing Helpers:** Before writing a new helper function, always check `LibraryUtility.pine` first to see if a suitable function already exists. Avoid duplicating functionality.
*   **Group Parameters with Custom Types:** When refactoring code into a library, if an exported function requires numerous parameters, group them into a single custom `type` object. This simplifies the function signature, improves readability, and avoids potential compiler issues with long argument lists.
*   **Export Functions for External Access:** Functions within a library are private by default. To make them accessible from other scripts, they must be explicitly marked with the `export` keyword. A function that is not exported cannot be called from the main strategy, as seen with the `getSequenceReversal` function.
*   **Verify All Call Sites After Refactoring:** After moving a function to a library, it is critical to perform a global search in the main strategy file for all calls to the original function. Each call site must be updated to use the new library-based function (e.g., `myLib.myFunction()`). This ensures that no legacy calls are left behind, which would lead to "undefined function" errors. This must be done in conjunction with verifying the function is exported from the library.
*   **Strict Data Typing (`series` vs. `simple`):** The PineScript compiler is much stricter about data types in libraries than in the main strategy script. A common example is the `length` parameter in built-in functions like `ta.sma()` or `ta.ema()`. While these functions may accept a `series int` (e.g., from an `input`) in a strategy, they can cause compiler errors in a library context. The `LibraryMACD` refactoring required creating custom helper functions (`_dynamic_sma`, `_dynamic_ema`) to manually handle the `series int` length, as the built-in functions would not compile. This highlights that sometimes custom implementations are necessary to work around the compiler's stricter library enforcement.
*   **Backtest to Ensure Performance:** Once the section of code has been isolated, likely into a library, ask the user to backtest the newly refactored code to verify that there are no performance degradations in the trading logic / strategy. Only once that is confirmed can you proceed to the next step. If there are any differences in performance, then compare the refactored code to the original code which should be stored in a separate file @PreviousMainStrategy.pine
*   **Be Wary of Compiler Errors:** PineScript compiler errors can sometimes be misleading. If an error on a specific line persists despite apparently correct syntax, investigate the surrounding code structure (like complex function signatures) as a potential root cause.
*   **Isolate Problems with a Minimal Test Case:** When a new implementation pattern (like creating a library) fails with a stubborn or confusing error, don't keep trying to fix the complex version. Instead, step back and create the simplest possible "hello world" version of the feature. For instance, creating a tiny library with a single, one-line function would have confirmed the correct basic syntax and immediately shown that the problem was with the *content* of our complex functions, not the library mechanism itself.
*   **Acknowledge Stateful Complexity:** Be aware that functions that maintain state across bars (i.e., those using the `var` keyword) are inherently more complex to refactor into libraries. While possible, they require extra scrutiny. Ensure that the logic remains sound and that the state is managed correctly within the new library structure.

### Project Goals
*   **Maintain strategy trading logic, so as to maintain the profitabability of the strategy.**
*   **Safely transition the codebase to a more modular, less monolithic structure for multiple reasons (readability, maintainability, usability).**
*   **Prepare strategy and libraries for future where we adapt it from having great performance on the 1 day chart, to maintaining that performance on the 1 day chart while also finding ways to get great, just as good, or at least reasonable performance on lower time frames like the 12hr chart, 8hr chart, 6hr chart, 4hr chart. This includes the following considerations:**
    *   **Dynamic Length Adjustments:** Lengths of indicators may need to be adjusted dynamically based on the timeframe. This could be a direct calculation from the timeframe divisor or a mapping to different preset values for various timeframes.
    *   **Timeframe-Specific Settings:** Certain thresholds and settings (e.g., RSI, Stochastic thresholds) might require different values for different timeframes to remain effective.
    *   **Conditional Logic Execution:** Some long entry or long exit conditions that are effective on the 1-day chart may need to be disabled on shorter timeframes. The existing input switches could be managed automatically based on the selected chart timeframe.
    *   **Exploration of Other Adjustments:** There may be other, unforeseen adjustments necessary to optimize the strategy for shorter timeframes.

### A Note on "Magic Numbers" and Overfitting

The strategy currently contains many hard-coded numerical values ("magic numbers") within its conditional logic. Many of these were derived from backtesting and serve to filter out undesirable trades. While effective, this approach may lead to **overfitting** the strategy to historical data.

A future refactoring goal is to replace these static numbers with more dynamic, relative calculations (e.g., using oscillators or values derived from statistical measures) to make the strategy more robust and adaptable to changing market conditions.

### Input Naming Conventions & Philosophy

The numerous input switches for enabling/disabling trading conditions follow a specific naming pattern to manage their status and priority:

*   **`D-` Prefix:** Indicates the condition is **D**efault enabled on the 1-day chart, as it has been deemed profitable and reliable.
*   **`H-` Prefix:** Indicates the condition is **D**efault enabled on the 12-hour chart, as it has been deemed profitable and reliable.
*   **`F-` Prefix:** Indicates the condition **F**lags for future work. The number following `F-` (e.g., `F1-`, `F3-`) signifies its development priority in ascending order. Lower numbers are considered more promising and closer to being integrated into the default strategy.
*   **`?-` Prefix:** Indicates the condition's profitability is unknown or questionable and requires further analysis.

### M2/M3 Indicator Philosophy & Future Goals

The strategy heavily relies on M2 and M3 money supply data as a leading indicator for asset price movements.

**Current Implementation:**

*   The core of the M2/M3 logic involves applying various time offsets (e.g., `i_m2l_tiny_offset`, `i_m2l_short_offset`) to the money supply data.
*   These specific offset values were determined through **visual observation** of historical data, identifying apparent correlations between shifts in M2/M3 and subsequent price action in Bitcoin.

**Future Goals & Areas for Improvement:**

1.  **Automated Correlation Analysis:** The current visual correlation method is subjective. A major future goal is to implement a system that **mathematically calculates the correlation** between the M2/M3 data and the asset price to dynamically determine the most predictive offset.
2.  **Adaptive Offsets:** There is a hypothesis that the ideal offset is not static and may be **shortening over time**. A future version of the strategy should be able to adapt to this.
3.  **Asymmetric Offsets:** The correlation timing might differ based on the direction of the money supply trend. The strategy could be improved by investigating if a **different, possibly shorter, offset is more predictive when M2/M3 is decreasing** compared to when it is increasing.

### Collaborator Context & Working Style

To optimize collaboration, the following context is provided about the primary user/developer of this strategy:

*   **Strengths:** The user has years of experience in software QA, specializing in black-box and UI testing, and is very familiar with Agile methodologies. Their expertise is valuable for:
    *   Validating the strategy's performance and behavior through backtesting.
    *   Defining acceptance criteria for new features.
    *   Understanding and verifying the high-level logic of the strategy.

*   **Collaboration Approach:**
    *   **On Testing:** Explanations regarding testing can be high-level, relying on the user's expertise for validation.
    *   **On Code:** Explanations for complex code, data structures, algorithms, or intricate PineScript syntax should be more detailed. Providing complete, well-explained code snippets is preferred.

By following these guidelines, we can refactor the trading strategy in a way that improves its structure and maintainability while preserving its performance.


### Advanced Library Refactoring: Inter-Library Dependencies

As the project grows, libraries may need to use common helper functions. To avoid code duplication and maintain a clean architecture, follow these principles:

*   **Centralize Generic Helpers:** If you write a helper function in one library (e.g., `LibraryMACD`) that could be useful in another (e.g., `LibraryMoneySupply`), it's a strong candidate for being moved. The `_dynamic_sma` and `_dynamic_ema` functions are perfect examples. They were moved from `LibraryMACD` to `LibraryUtility` so any other library can use them.

*   **Export for Inter-Library Use:** Functions in a library are private by default. For another library to be able to call a function from your utility library, that function **must be exported** from the utility library.

*   **Update Call Sites:** After moving a shared function to a utility library, you must update the original library to call the function from the new location. For example, the call `_dynamic_sma()` inside `LibraryMACD` was changed to `utils._dynamic_sma()` after the function was moved to `LibraryUtility` (which is imported with the alias `utils`).

*   **Update Import Versions:** After publishing a new version of a library, remember to update the version number in the `import` statement in all scripts that use it (e.g., `import NiceOrbit/LibraryUtility/2 as utils` might become `import NiceOrbit/LibraryUtility/3 as utils`). This ensures the strategy is using the latest code.

### File Editing Strategies

To prevent accidental data loss and to ensure that changes are made in a safe and reliable manner, the following file editing strategies should be followed.

*   **For small, targeted changes:** Use the `replace` tool to make small, targeted changes to the file. This is the preferred method for making changes to a file, as it is less prone to errors than other methods.
*   **For large, complex changes:** If a large number of changes need to be made to a file, it is often safer to break the changes down into a series of smaller, more manageable changes. This will make it easier to track the changes and to ensure that they are all applied correctly.
*   **Avoid using `write_file` for modifications:** The `write_file` tool should only be used for creating new files. It should not be used for modifying existing files, as this can lead to accidental data loss.

### Workflow for Large-Scale Refactoring

To ensure efficiency and avoid unproductive loops when performing large-scale refactoring that spans multiple files or involves numerous changes within a single large file, the following workflow must be followed:

*   **1. Deconstruct the Task:** Break down the high-level goal into the smallest possible, verifiable, and independent steps. For a large rename, this means treating each distinct term to be replaced as a separate sub-task.
*   **2. Execute One Step at a Time:** Complete each sub-task in its entirety before moving to the next. This means for each term to be renamed:
    *   First, get the exact count of the term to be replaced using the `search_file_content` tool.
    *   Second, execute a single, precise `replace` call with the `expected_replacements` parameter set to the count from the previous step.
    *   Third, after the replacement, immediately read the file back to verify the change was successful.
*   **3. Report Progress Clearly:** After each successful and verified replacement, I must report to you what I have just done. For example: "I have successfully replaced all 114 instances of 'M2Liquidity' with 'M2LeadingIndicator' in `MainStrategy.pine`."
*   **4. Prioritize Safety and Verification:** This step-by-step, verified approach is mandatory for any operation involving more than a few replacements. It prioritizes correctness and progress over attempting a single, large, and error-prone operation.

## Plotting Strategy

To improve debuggability and maintainability, the plotting of variables and conditions will be handled by dedicated indicators rather than being cluttered inside the main strategy script.

### Guidelines

*   **Dedicated Indicators:** Each library should have a corresponding indicator for visualizing its data.
*   **Plot All The Things:** Every new input, internal variable, and output of a library function must be added to its corresponding indicator for plotting.
*   **Consistent Naming:** The `input.bool()` switches in the indicators should follow a consistent naming convention, e.g., `i_plot_variableName`.
*   **Use the Right Tool for the Job:** Use the chart for visualizing trends (e.g., `plot()`) and the data window for displaying precise numerical values (e.g., `plotchar()` with `display.data_window`).
*   **Conditional Plotting:** To work around Pine Script's limitation of not allowing plotting functions inside conditionals, use conditional expressions to plot `na` when a plot is disabled: `plot(i_plot_my_variable ? my_variable : na, title="My Variable")`

### Indicator and Strategy Synchronization

Due to Pine Script's limitations (a 64-plot limit per script and no conditional plotting functions), we must use separate `indicator` scripts to visualize the strategy's behavior. This creates a significant risk: the inputs and logic in the indicator can "drift" and become out of sync with the main strategy, leading to misleading visualizations.

To mitigate this risk, the following guidelines are mandatory:

1.  **Indicators are for Visualization Only:** An indicator script created for debugging a strategy should contain the absolute minimum logic required. Its primary purpose is to *visualize* the data that the strategy is using. It should not contain any unique calculations or logic that doesn't exist in the strategy.

2.  **Input Synchronization is Mandatory:** When an `input.*()` value is defined or changed in `MainStrategy.pine`, the **exact same change must be mirrored** in the corresponding indicator script(s) that use it. This includes the input's:
    *   Variable name (e.g., `i_m2LeadingIndicator_shortOffset`)
    *   Data type (`input.int`, `input.float`, etc.)
    *   Default value (`defval`)
    *   All other parameters (`title`, `group`, `tooltip`, etc.)

3.  **Verification via Diffing:** Before committing any changes that affect inputs, the developer **must** use a diffing tool (like the IDE's compare feature or `git diff`) to compare the input sections of `MainStrategy.pine` and the relevant indicator script. This is a critical step to visually confirm that the inputs have not diverged.
