Workflows case 1
This scenario shows how to build an automated trading pipeline (Workflow) in KAWA.
The pipeline runs on a schedule and, step by step, does the following: loads and prepares market data, runs a Python script to calculate signals, and sends notifications and a short report.
1. Create a workflow
Go to Home → Workflows and click + Workflow.
Enter a name, e.g., Daily — Signals & Report.
Recommendation: create separate workflows for different frequencies (Daily / Intraday) and markets.
2. Trigger
In the WHEN area, choose At a scheduled time.
Frequency: Daily
Time: 06:10 (after market close).
Time zone: the exchange’s time zone (e.g., America/New_York).
Only on business days: On.
3. Action steps
3.1 Step 1 — Transform data: prepare market data
3.1.1 Go to Add action
→ Transform data and choose the OHLCV source.
3.1.2 Time
Use a single time column for all records. Ensure the timestamp is UTC ISO-8601 (e.g., 2025-10-17T20:00:00Z).
3.1.3 Order matters
Sort by timestamp (New -> Old) so EMA/RSI are calculated correctly.
3.1.4 Adding simple metrics (Enrich → Formula)
Body ratio — share of the candle body in the day’s range
Name: body_ratio
Formula:
ROUND( ABS(close - open) / ( ABS(high - low) + 1 / POWER(10, 7) ), 4 )
Meaning (0…1):
0 ≈ neutral/doji (open ≈ close)
1 ≈ strong one-direction day (big body, small wicks)
Range % — relative daily volatility
Name: range_pct
Formula:
ROUND( (high - low) / ( (high + low + close) / 3 + 1 / POWER(10, 7) ), 6 )
Meaning: Higher = a more volatile day. Good for comparing different tickers.
Close position in range — where the close sits within the day’s range
Name: close_pos_in_range
Formula:
ROUND( (close - low) / ( ABS(high - low) + 1 / POWER(10, 7) ), 4 )
Meaning (0…1):
0 = closed near low
0.5 = around the middle
1 = closed near high
3.1.5 Enrich → Lookup column
Goal: pull the exchange and currency for each ticker.
Source sheet: ref_symbols
Columns to pull: exchange, currency
Result: the source table gets new columns exchange and currency (e.g., NASDAQ, USD) for each symbol.
3.1.6 Enrich → Manual input
Goal: add simple constants for easier filtering and report/email subjects.
Add: session
Value: "EOD"
Why: marks the daily run; used in the AI report and filters.
Add: market
Value: "US"
Why: market tag; inserted into email subject and used for grouping.
3.1.7 Data quality checks
OHLC rules: high ≥ max(open, close), low ≤ min(open, close), high ≥ low.
Volume: volume ≥ 0; optionally flag volume = 0.
Uniqueness: no duplicate symbol + timestamp.
Types: price/volume columns are numeric; no stray text.
3.1.8 Row guardrails (Behavior)
For our scenario set exactly these parameters:
If no rows are found → Interrupt the workflow.
If more than [Max num of rows] are found → Interrupt the workflow.
The 1,000 threshold in this field is fixed (not editable).
Max num of rows → set a value greater than the current number of rows in the table.
Example: if the source has ~800 rows, set 1000.
If you add new tickers/history, increase this value accordingly.
If Max num of rows ≤ the table size, the workflow will not start.
3.2 Step 2 — Run python script
Goal: Using the data from Step 1 (OHLCV), calculate EMA(10) and EMA(20), and produce a simple BUY/SELL signal for the last bar of each symbol.
3.2.1 Create a Python tool in the library
Go to Home → Tools → + and create a script named, for example, compute_indicators_and_signals.
Paste the code and click Save.
3.2.2 Add an action to the Workflow and link it to Step 1
In your Workflow, click Add action → Run python script.
Select python tool from the library → choose compute_indicators_and_signals.
In Match tool inputs with any of the previous task outputs:
df → choose 1. Transform data (output of Step 1).
symbol → the symbol column from Step 1.
close → the close column from Step 1.
The script is created separately in Tools; the linking to Step 1 data is done here, in the Workflow.
3.2.3 Behavior (guardrails) for Step 2
If no rows are found → Interrupt workflow.
If more than 1000 rows are found → Interrupt workflow.
Max num of rows → set a value higher than the current table size (with a 10–20% buffer).
Example: table ≈ 800 rows → set 1000 or more.
If you add history/new tickers, increase this value.
3.3 Step 3 — AI prompt
Goal: generate a short EOD (end-of-day) report in Markdown using the results from Step 2 — Run python script (one last bar per symbol).
3.3.1 Add an action
Click Add action → AI prompt.
3.3.2 Paste the prompt text
Copy this text into the Prompt field:
3.3.3 Connect data from Step 2 (Grid)
Place your cursor under the ## Data section.
Click the + button on the right of the toolbar → Use data from: 2. Run python script → Grid.
3.4 Step 4 — Send email
Goal: send the EOD report generated in the previous step (AI prompt), with basic run context.
3.4.1 Add an action
Add action → Send email.
3.4.2 Fill in the fields
Recipients — specify recipients (comma-separated).
Subject — Daily — Signals & Report.
3.4.3 Build the Body
Insert the base text:
Now add dynamic “chips” (click the + button on the right side of the toolbar):
For the lines Run (UTC) / Market / Session:
Transform data → Aggregated values → timestamp
Transform data → Aggregated values → market
Transform data → Aggregated values → session
Under the Report heading:
AI prompt → Choose data → Generated Content (this is the Markdown text generated by Step 3).
4. Finish
Click Create workflow.
In Run history, make sure the flow reaches the Send email step with Success status.
5. Result — receiving the email
After the Workflow runs successfully, the report arrives by email.


6. Conclusion
We built a fully automated EOD pipeline in KAWA:
Transform data prepares OHLCV and adds helper fields.
Run python script calculates EMAs and signals.
AI prompt creates a short Markdown report.
Send email delivers the final result.
Following the guardrails (especially Max num of rows) and inserting only the needed fields in Steps 3–4 ensures reliable email delivery and no failures—even on “empty” days.
Last updated
Was this helpful?

