Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,40 @@





@app.get("/admin/walkforward")
@app.post("/admin/walkforward")
async def admin_walkforward(folds: int = 3):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The 'folds' parameter should be validated to ensure it is a positive integer. If 'folds=0' is passed, it will cause a 'ZeroDivisionError' in 'propiq_walkforward_backtest.py' at line 562 during the fold size calculation.

"""Run walk-forward backtest export + fold analysis.
Exports graded legs from bet_ledger, runs propiq_walkforward_backtest.py,
saves results to data/walkforward_results.json.
Usage: POST /admin/walkforward or GET /admin/walkforward?folds=5
"""
async def _run_walkforward():
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This background task lacks concurrency control. Multiple requests to this endpoint will trigger multiple backtests simultaneously, potentially leading to resource exhaustion or file write conflicts in the output directory. Consider implementing a guard (e.g., a global boolean flag or an 'asyncio.Lock') to prevent concurrent executions.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Micro-Learning Topic: Resource exhaustion (Detected by phrase)

Matched on "resource exhaustion"

What is this? (2min video)

Allocating objects or timers with user-controlled sizes or durations can cause resource exhaustion.

Try a challenge in Secure Code Warrior

try:
Comment on lines +1287 to +1288
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The 'importlib' module is not defined in this scope, which will cause a 'NameError' when calling 'importlib.util.find_spec'. Additionally, 'importlib.util' must be explicitly imported to access the 'util' submodule and the base 'importlib' package.

Suggested change
async def _run_walkforward():
try:
async def _run_walkforward():
import importlib.util
try:

loop = asyncio.get_event_loop()
spec_wf = importlib.util.find_spec("wire_walkforward_backtest")

Check warning on line 1290 in orchestrator.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

orchestrator.py#L1290

undefined name 'importlib' (F821)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable 'importlib'


The variable name is not defined where it is used.
This will lead to an error during the runtime.
Make sure there is no typo. If the name was supposed to be imported, verify that you've actually imported the name.

spec_bt = importlib.util.find_spec("propiq_walkforward_backtest")

Check warning on line 1291 in orchestrator.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

orchestrator.py#L1291

undefined name 'importlib' (F821)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable 'importlib'


The variable name is not defined where it is used.
This will lead to an error during the runtime.
Make sure there is no typo. If the name was supposed to be imported, verify that you've actually imported the name.

if spec_wf is None or spec_bt is None:
logger.warning("[walkforward] Required scripts not found — skipping")
return
wf_mod = importlib.import_module("wire_walkforward_backtest")

Check warning on line 1295 in orchestrator.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

orchestrator.py#L1295

undefined name 'importlib' (F821)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable 'importlib'


The variable name is not defined where it is used.
This will lead to an error during the runtime.
Make sure there is no typo. If the name was supposed to be imported, verify that you've actually imported the name.

bt_mod = importlib.import_module("propiq_walkforward_backtest")

Check warning on line 1296 in orchestrator.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

orchestrator.py#L1296

undefined name 'importlib' (F821)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable 'importlib'


The variable name is not defined where it is used.
This will lead to an error during the runtime.
Make sure there is no typo. If the name was supposed to be imported, verify that you've actually imported the name.

await loop.run_in_executor(None, wf_mod.export_from_db)
await loop.run_in_executor(None, bt_mod.run, folds)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The 'propiq_walkforward_backtest' module does not contain a 'run' function. Calling 'bt_mod.run(folds)' will raise an 'AttributeError'. Based on the module's content, you likely intended to call 'run_walkforward_backtest', but that function requires 'pitching_df' and 'prop_lines_df' DataFrames as input. Ensure the intended function is defined or use a wrapper that handles data loading.

logger.info("[walkforward] Walk-forward backtest complete (%d folds).", folds)
except Exception as exc:
logger.error("[walkforward] Failed: %s", exc, exc_info=True)

asyncio.create_task(_run_walkforward())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Prevent concurrent /admin/walkforward runs; overlapping background tasks can race and overwrite shared walkforward output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At orchestrator.py, line 1303:

<comment>Prevent concurrent `/admin/walkforward` runs; overlapping background tasks can race and overwrite shared walkforward output.</comment>

<file context>
@@ -1274,6 +1274,40 @@ async def admin_bp2vec_train():
+        except Exception as exc:
+            logger.error("[walkforward] Failed: %s", exc, exc_info=True)
+
+    asyncio.create_task(_run_walkforward())
+    return JSONResponse({
+        "status": "started",
</file context>

return JSONResponse({
"status": "started",
"message": f"Walk-forward backtest running in background (~3-5 min, {folds} folds). "
"Results written to data/walkforward_results.json when complete.",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a discrepancy between the response message and the actual script output. The message points to 'data/walkforward_results.json', but 'propiq_walkforward_backtest.py' is configured to write its summary to 'backtest_results/walkforward_summary.json' (line 699).

Suggested change
"Results written to data/walkforward_results.json when complete.",
"Results written to backtest_results/walkforward_summary.json when complete.",

})


@app.get("/admin/scan-logs")
async def admin_scan_logs(hours: int = 6):
"""
Expand Down