Advertisement IC Markets

Screenshot Every Trade at Entry and Exit

Document your personal trading journey. Track daily equity curves, review winning and losing streaks, share trade screenshots, and get constructive feedback.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

1. MT4 Version (MQL4)

Save this file as VisualJournal.mq4 in your MQL4/Experts folder.

Code: Select all

//+------------------------------------------------------------------+
//|                                                VisualJournal.mq4 |
//| Automatically takes screenshots of your chart at entry and exit. |
//+------------------------------------------------------------------+
#property strict

input int FastEMA = 9;
input int SlowEMA = 21;
input int ScreenWidth = 1920;
input int ScreenHeight = 1080;

bool inTrade = false;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // 1. PLACEHOLDER STRATEGY LOGIC (Replace with your own rules)
    // Checking the previous completed candle (shift 1) and the one before it (shift 2)
    double fast1 = iMA(Symbol(), 0, FastEMA, 0, MODE_EMA, PRICE_CLOSE, 1);
    double slow1 = iMA(Symbol(), 0, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, 1);
    double fast2 = iMA(Symbol(), 0, FastEMA, 0, MODE_EMA, PRICE_CLOSE, 2);
    double slow2 = iMA(Symbol(), 0, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, 2);

    bool isEntrySetup = (fast1 > slow1 && fast2 <= slow2); // Bullish Crossover
    bool isExitSetup  = (fast1 < slow1 && fast2 >= slow2); // Bearish Crossunder

    // 2. ENTRY LOGIC & SCREENSHOT
    if (isEntrySetup && !inTrade)
    {
        inTrade = true;
        
        // Create a safe, timestamped filename
        string timeStr = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS);
        StringReplace(timeStr, ":", "-");
        StringReplace(timeStr, ".", "-");
        string filename = "Journal_ENTRY_" + Symbol() + "_" + timeStr + ".png";
        
        // Take the screenshot programmatically
        if(WindowScreenShot(filename, ScreenWidth, ScreenHeight)) {
            Alert("📸 ENTRY SCREENSHOT SAVED: ", filename, " - Review your raw setup later.");
            Print("Screenshot saved to MQL4/Files/", filename);
        } else {
            Print("Error taking entry screenshot: ", GetLastError());
        }
    }

    // 3. EXIT LOGIC & SCREENSHOT
    if (isExitSetup && inTrade)
    {
        inTrade = false;
        
        // Create a safe, timestamped filename
        string timeStr = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS);
        StringReplace(timeStr, ":", "-");
        StringReplace(timeStr, ".", "-");
        string filename = "Journal_EXIT_" + Symbol() + "_" + timeStr + ".png";
        
        // Take the screenshot programmatically
        if(WindowScreenShot(filename, ScreenWidth, ScreenHeight)) {
            Alert("📸 EXIT SCREENSHOT SAVED: ", filename, " - Compare execution to your plan.");
            Print("Screenshot saved to MQL4/Files/", filename);
        } else {
            Print("Error taking exit screenshot: ", GetLastError());
        }
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

2. MT5 Version (MQL5)

Save this file as VisualJournal.mq5 in your MQL5/Experts folder. MQL5 requires handles for indicators, so the structure is slightly different.

Code: Select all

//+------------------------------------------------------------------+
//|                                                VisualJournal.mq5 |
//| Automatically takes screenshots of your chart at entry and exit. |
//+------------------------------------------------------------------+
#property strict

input int FastEMA = 9;
input int SlowEMA = 21;
input int ScreenWidth = 1920;
input int ScreenHeight = 1080;

bool inTrade = false;
int fastHandle, slowHandle;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialize indicator handles for MQL5
    fastHandle = iMA(_Symbol, _Period, FastEMA, 0, MODE_EMA, PRICE_CLOSE);
    slowHandle = iMA(_Symbol, _Period, SlowEMA, 0, MODE_EMA, PRICE_CLOSE);
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    double fastArray[], slowArray[];
    ArraySetAsSeries(fastArray, true);
    ArraySetAsSeries(slowArray, true);
    
    // Copy the last 3 bars of indicator data
    if(CopyBuffer(fastHandle, 0, 0, 3, fastArray) <= 0) return;
    if(CopyBuffer(slowHandle, 0, 0, 3, slowArray) <= 0) return;

    // 1. PLACEHOLDER STRATEGY LOGIC (Replace with your own rules)
    // Array index 1 is the last completed bar, index 2 is the bar before it
    bool isEntrySetup = (fastArray[1] > slowArray[1] && fastArray[2] <= slowArray[2]);
    bool isExitSetup  = (fastArray[1] < slowArray[1] && fastArray[2] >= slowArray[2]);

    // 2. ENTRY LOGIC & SCREENSHOT
    if (isEntrySetup && !inTrade)
    {
        inTrade = true;
        
        string timeStr = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS);
        StringReplace(timeStr, ":", "-");
        StringReplace(timeStr, ".", "-");
        string filename = "Journal_ENTRY_" + _Symbol + "_" + timeStr + ".png";
        
        // Take the screenshot automatically
        if(ChartScreenShot(0, filename, ScreenWidth, ScreenHeight, ALIGN_RIGHT)) {
            Alert("📸 ENTRY SCREENSHOT SAVED: ", filename);
            Print("Screenshot saved to MQL5/Files/", filename);
        } else {
            Print("Error taking entry screenshot: ", GetLastError());
        }
    }

    // 3. EXIT LOGIC & SCREENSHOT
    if (isExitSetup && inTrade)
    {
        inTrade = false;
        
        string timeStr = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS);
        StringReplace(timeStr, ":", "-");
        StringReplace(timeStr, ".", "-");
        string filename = "Journal_EXIT_" + _Symbol + "_" + timeStr + ".png";
        
        // Take the screenshot automatically
        if(ChartScreenShot(0, filename, ScreenWidth, ScreenHeight, ALIGN_RIGHT)) {
            Alert("📸 EXIT SCREENSHOT SAVED: ", filename);
            Print("Screenshot saved to MQL5/Files/", filename);
        } else {
            Print("Error taking exit screenshot: ", GetLastError());
        }
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

How to Retrieve Your Journal Images

Unlike standard screenshots that save to your desktop, MetaTrader sandboxes its file creation for security. To find your automated screenshots for review:

1.) Open MetaTrader.

2.) Go to the top menu: File > Open Data Folder.

3.) Open the MQL4 (or MQL5) folder.

4.) Open the Files folder.

Every time your strategy triggers, a perfectly sized .png showing your exact indicators, market structure, and price action at that precise second will be waiting for you in this folder, labeled neatly by ENTRY/EXIT, Ticker, and Timestamp.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

Like MetaTrader, cTrader (using the cAlgo API in C#) has native capability to take chart screenshots directly from your automated script.

The beauty of cTrader is that its TakeChartshot() method returns the exact image data as a byte array, allowing you to easily save it straight to a dedicated journaling folder on your hard drive.

Below is the cBot written in C#. It uses the exact same placeholder logic (EMA crossover) and automatically grabs a snapshot of your screen the moment the setup occurs.

The cTrader cBot (C#)

1.) Open cTrader Automate (cAlgo).

2.) Create a New cBot and name it VisualJournalBot.

3.) Paste the following C# code over the default template.

4.) Important: Because this bot writes files to your hard drive, it requires AccessRights.FileSystem. The [Robot] attribute at the top already handles this for you.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

Ctrader script ver. 1.00

Code: Select all

using System;
using System.IO;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class VisualJournalBot : Robot
    {
        [Parameter("Fast EMA", DefaultValue = 9)]
        public int FastEmaPeriods { get; set; }

        [Parameter("Slow EMA", DefaultValue = 21)]
        public int SlowEmaPeriods { get; set; }

        // Define exactly where you want your journal images saved
        [Parameter("Save Folder Path", DefaultValue = @"C:\Trading_Journal_Screenshots")]
        public string SaveFolderPath { get; set; }

        private ExponentialMovingAverage _fastEma;
        private ExponentialMovingAverage _slowEma;
        private bool _inTrade = false;

        protected override void OnStart()
        {
            // Initialize indicator placeholders
            _fastEma = Indicators.ExponentialMovingAverage(Bars.ClosePrices, FastEmaPeriods);
            _slowEma = Indicators.ExponentialMovingAverage(Bars.ClosePrices, SlowEmaPeriods);

            // Ensure your journaling directory exists; if not, create it
            if (!Directory.Exists(SaveFolderPath))
            {
                Directory.CreateDirectory(SaveFolderPath);
                Print("Created new visual journaling directory at: ", SaveFolderPath);
            }
        }

        protected override void OnBar()
        {
            // 1. PLACEHOLDER STRATEGY LOGIC (Replace with your actual rules)
            // Evaluates using the completed bars
            bool isEntrySetup = _fastEma.Result.HasCrossedAbove(_slowEma.Result, 0);
            bool isExitSetup = _fastEma.Result.HasCrossedBelow(_slowEma.Result, 0);

            // 2. ENTRY LOGIC & SCREENSHOT
            if (isEntrySetup && !_inTrade)
            {
                _inTrade = true;
                
                // Format a clean, sortable timestamp
                string timestamp = Server.Time.ToString("yyyyMMdd_HHmmss");
                string filename = $"Journal_ENTRY_{Symbol.Name}_{timestamp}.png";
                string fullPath = Path.Combine(SaveFolderPath, filename);

                CaptureAndSaveChart(fullPath, "ENTRY");
            }

            // 3. EXIT LOGIC & SCREENSHOT
            if (isExitSetup && _inTrade)
            {
                _inTrade = false;
                
                // Format a clean, sortable timestamp
                string timestamp = Server.Time.ToString("yyyyMMdd_HHmmss");
                string filename = $"Journal_EXIT_{Symbol.Name}_{timestamp}.png";
                string fullPath = Path.Combine(SaveFolderPath, filename);

                CaptureAndSaveChart(fullPath, "EXIT");
            }
        }

        private void CaptureAndSaveChart(string filePath, string tradeEvent)
        {
            // cTrader's screenshot method only fires if the chart is actively visible
            if (Chart.IsVisible)
            {
                // TakeChartshot() captures exactly what you see and returns it as image data
                byte[] chartShotBytes = Chart.TakeChartshot();
                
                if (chartShotBytes != null)
                {
                    try
                    {
                        // Write the image data directly to a PNG file
                        File.WriteAllBytes(filePath, chartShotBytes);
                        Print($"📸 {tradeEvent} SCREENSHOT SAVED: {filePath}");
                    }
                    catch (Exception ex)
                    {
                        Print($"Failed to save screenshot due to permissions/path error: {ex.Message}");
                    }
                }
            }
            else
            {
                Print($"Warning: Could not take {tradeEvent} screenshot. The chart must be visible.");
            }
        }
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Screenshot Every Trade at Entry and Exit

Post by PTScalper »

How to Retrieve Your Journal Images

Unlike MetaTrader which forces you to dig through its hidden sandboxed MQL/Files directory, cTrader lets you specify any path you want.

By default, the script above will automatically create a folder right on your C-Drive named C:\Trading_Journal_Screenshots.

Every time your rules trigger, a .png file perfectly capturing the raw setup—the chart structure, indicator values, and candlestick formations—is instantly dropped into that folder, labeled like Journal_ENTRY_EURUSD_20240510_143000.png.

One quick caveat: The cTrader API requires the chart window to actually be visible for TakeChartshot() to successfully generate an image. If the chart is fully minimized or hidden in the background when the trade triggers, it will skip the picture. (It will print a warning in your cBot log so you know you missed it).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply