Re: Weekly Journal Review: The Questions That Matter
Posted: Wed Sep 23, 2026 9:57 am
cTrader Version (C# cBot)
1.) Open cTrader and go to the Automate tab (on the left menu).
2.) Click New cBot and name it WeeklyJournalDashboard.
3.) Replace all the default code in the editor with the following:
1.) Open cTrader and go to the Automate tab (on the left menu).
2.) Click New cBot and name it WeeklyJournalDashboard.
3.) Replace all the default code in the editor with the following:
Code: Select all
using System;
using System.Linq;
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class WeeklyJournalDashboard : Robot
{
// Use text Labels to identify your setups
[Parameter("Setup A Label", DefaultValue = "Setup A")]
public string SetupALabel { get; set; }
[Parameter("Setup B Label", DefaultValue = "Setup B")]
public string SetupBLabel { get; set; }
protected override void OnStart()
{
// Set a 1-second timer to update the dashboard even when markets are closed
Timer.Start(TimeSpan.FromSeconds(1));
UpdateDashboard(); // Run it immediately once on startup
}
protected override void OnTimer()
{
UpdateDashboard();
}
private void UpdateDashboard()
{
int weekWins = 0, weekLosses = 0;
double grossWin = 0, grossLoss = 0;
int setupAWins = 0, setupALosses = 0;
int setupBWins = 0, setupBLosses = 0;
// Determine the start time of the current week (Assuming a Monday start)
DateTime now = Server.Time;
int diff = (7 + (now.DayOfWeek - DayOfWeek.Monday)) % 7;
DateTime weekStart = now.Date.AddDays(-1 * diff).Date; // .Date strips the time to 00:00:00
// Query cTrader's History API for trades closed this week
var thisWeekTrades = History.Where(t => t.ClosingTime >= weekStart);
foreach (var trade in thisWeekTrades)
{
// NetProfit automatically accounts for commissions and swaps in cTrader
if (trade.NetProfit > 0)
{
weekWins++;
grossWin += trade.NetProfit;
if (trade.Label == SetupALabel) setupAWins++;
else if (trade.Label == SetupBLabel) setupBWins++;
}
else if (trade.NetProfit < 0)
{
weekLosses++;
grossLoss += Math.Abs(trade.NetProfit);
if (trade.Label == SetupALabel) setupALosses++;
else if (trade.Label == SetupBLabel) setupBLosses++;
}
}
// 1. Calculate Overall Win Rate
int totalTrades = weekWins + weekLosses;
double winRate = totalTrades > 0 ? ((double)weekWins / totalTrades) * 100 : 0.0;
// 2. Calculate Realized R:R Ratio
double avgWin = weekWins > 0 ? grossWin / weekWins : 0.0;
double avgLoss = weekLosses > 0 ? grossLoss / weekLosses : 0.0;
double rrRatio = avgLoss > 0 ? avgWin / avgLoss : 0.0;
// 3. Calculate Setup Win Rates
int totalA = setupAWins + setupALosses;
double winRateA = totalA > 0 ? ((double)setupAWins / totalA) * 100 : 0.0;
int totalB = setupBWins + setupBLosses;
double winRateB = totalB > 0 ? ((double)setupBWins / totalB) * 100 : 0.0;
// 4. Render the Dashboard text
string dashboard = "========== WEEKLY REVIEW ==========\n\n";
dashboard += "1. Win Rate This Week:\n";
dashboard += $" {totalTrades} Trades | {winRate:F2}%\n\n";
dashboard += "2. Avg Realized R:R:\n";
dashboard += $" 1 : {rrRatio:F2}\n\n";
dashboard += "3. Setup Performance:\n";
dashboard += $" {SetupALabel}: {totalA} Trades | {winRateA:F2}%\n";
dashboard += $" {SetupBLabel}: {totalB} Trades | {winRateB:F2}%\n\n";
dashboard += "4. Rule Deviations?\n";
dashboard += " [ Check journal for manual deviations ]\n";
dashboard += "===================================";
// Draw the dashboard directly to the top-left corner of the chart
Chart.DrawStaticText("JournalDash", dashboard, VerticalAlignment.Top, HorizontalAlignment.Left, Color.White);
}
protected override void OnStop()
{
// Remove the dashboard from the chart when the bot is stopped
Chart.RemoveObject("JournalDash");
}
}
}