TradingView

Exporting New TradingView Trades metrics to Excel

Exporting New TradingView Trades metrics to Excel

If you follow me you probably have seen a video about new metrics for backtesting results TradingView introduced a few weeks ago:

In Autoview plugin for Chrome, there is a quite handy feature that allows you to copy backtesting results to Excel. Unfortunately, this feature doesn’t work with new columns and copied data won’t have them.

I really wanted to explore these columns more so I spend some time to find the easy way to copy these columns. I took code of Autoview plugin, updated it a bit and got a piece of Javascript code you can use to parse new columns as well. Of course, this solution isn’t very fancy and I hope that Autoview will change their code to support new columns in the end.

So let me show how you can use it. First of all open TradingView’s chart in Chrome and apply a strategy you want to export trades from. Then press F12 to open developer tools or got to Main Menu -> More Tools -> Developer Tools. You will see something like that:

First, click Console on the top and then click on the last line of the console, near the “>” sign. Then just paste following JavaScript code to the console and press Enter.

// declaring functions
function type(k) {
    const a = {"le":"Entry Long","lx":"Exit Long","se":"Entry Short","sx":"Exit Short"};

    return a.hasOwnProperty(k) ? a[k] : undefined;
}
function tz(n) {
    return n.replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, "$1");
}
function mv(a, k) {
    if (typeof k === "function") {
        return a.push(k());
    }

    if (typeof k === "string") {
        const reg = /^(\$)?(.+?)(?:\.(\d+))?(%)?$/;
        const res = reg.exec(k);

        if (!a.hasOwnProperty(res[2])) {
            return;
        }

        res[1] = /*res[1] ||*/ "";
        res[2] = a[res[2]];
        res[3] = +res[3] || 0;
        res[4] = /*res[4] ||*/ "";

        if (res[2] === null) {
            return "N/A";
        }
        if (res[4] === "%") {
            res[2] *= 100;
        }
        if (k === "profitFactor" && res[2] < 1) {
            res[2] *= -1;
        }

        return res[1] + tz(res[2].toFixed(res[3])) + res[4];
    }

    throw new TypeError("Unsupported type: " + typeof k);
}
function dt(timestamp) {
    const D = new Date(timestamp);
    const d = [D.getFullYear(), p(D.getMonth() + 1), p(D.getDate())].join("-");
    const t = [p(D.getHours()), p(D.getMinutes()), p(D.getSeconds())].join(":");

    return d + " " + t;
}
function p(x) {
    return (x.length === 1 || x < 10) ? "0" + x : x;
}
function output(trades) {
    let ret = [];

    trades.items = trades.items.map(tab);
    ret.push(trades.headings.join("\t"));
    ret = ret.concat(trades.items);

    return ret.join("\n");
}
function tab(array) {
    return array.join("\t");
}
function clipboard(format, data) {
    const tmp = document.oncopy;

    document.oncopy = function clipboard_oncopy(e) {
        e.clipboardData.setData(format, data);
        e.preventDefault();
    };
    document.execCommand("copy", false, null);
    alert("Copied to Clipboard");

    document.oncopy = tmp;
}
// find React object from DOM node
function findReact(dom, traverseUp = 0) {
    const key = Object.keys(dom).find(key=>{
        return key.startsWith("__reactFiber$");
    });
    const domFiber = dom[key];
    if (domFiber == null) return null;

    const getCompFiber = fiber=>{
        let parentFiber = fiber.return;
        while (typeof parentFiber.type == "string") {
            parentFiber = parentFiber.return;
        }
        return parentFiber;
    };
    let compFiber = getCompFiber(domFiber);
    for (let i = 0; i < traverseUp; i++) {
        compFiber = getCompFiber(compFiber);
    }
    return compFiber;
}

// defining variables
var rw_new   = findReact(document.querySelector("div.report-content.trades-new").parentElement.parentElement)
    .memoizedProps.onCSVReportRequest._listeners[0].object;
var data_new = rw_new._data;
var t_new    = data_new.trades;
var sd_new   = 4;

// parsing trades
let trades3 = {
    headings: ("Trade #,Type,Signal,Date/Time,Price,Contracts,Profit,ProfitPerc,ProfitEqPerc,ProfitEq," +
        "RunUpPerc,RunUp,DrawdownPerc,Drawdown").split(","),
    items: []
};
for (i = 0; i < t_new.length; i++) {
    v = t_new[i];
    trades3.items.push([i + 1, type(v.e.tp), v.e.c, dt(v.e.tm), mv(v.e, "$p." + sd_new), , ]);
    trades3.items.push(v.x.c.length
        ? [, type(v.x.tp), v.x.c, dt(v.x.tm), mv(v.x, "$p." + sd_new), v.q, tz(v.pf.toFixed(sd_new)),
            tz(v.tp.p.toFixed(sd_new)), tz(v.cp.p.toFixed(sd_new)), tz(v.cp.v.toFixed(sd_new)),
            tz(v.rn.p.toFixed(sd_new)), tz(v.rn.v.toFixed(sd_new)), tz(v.dd.p.toFixed(sd_new)),
            tz(v.dd.v.toFixed(sd_new))]
        : [, type(v.x.tp), "Open", , , , ,]
    );
}

// Copying trades to the clipboard
clipboard("text/plain", output(trades3));

This should work if you have Autoview installed or not. As a result, you should see the following Pop Up window:

Now open Excel, select a cell and paste your trades. The result should look like that and should include new columns as well:

So as you can easy it’s quite a simple thing to do, but not very handy. In one of the next articles/videos will show how you can run some analysis using new trades columns.


15 thoughts on “Exporting New TradingView Trades metrics to Excel”

  1. [Small BUG]
    VM863:93 Uncaught TypeError: Cannot read property ‘_data’ of undefined
    at :93:23

    If you can fix it, it doesn’t seem to work anymore. Thanks!

  2. @QUANTNOMAD – Hi , even with the autoview its the same error
    Uncaught TypeError: Cannot read property ‘_data’ of undefined
    at :93:23
    (anonymous) @ VM222:93

    Suggest how to make this thing work

  3. sir new code
    thanks for old code

    // declaring functions
    function type(k) {
    const a = {“le”:”Entry Long”,”lx”:”Exit Long”,”se”:”Entry Short”,”sx”:”Exit Short”};

    return a.hasOwnProperty(k) ? a[k] : undefined;
    }
    function tz(n) {
    return n.replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, “$1”);
    }
    function mv(a, k) {
    if (typeof k === “function”) {
    return a.push(k());
    }

    if (typeof k === “string”) {
    const reg = /^(\$)?(.+?)(?:\.(\d+))?(%)?$/;
    const res = reg.exec(k);

    if (!a.hasOwnProperty(res[2])) {
    return;
    }

    res[1] = /*res[1] ||*/ “”;
    res[2] = a[res[2]];
    res[3] = +res[3] || 0;
    res[4] = /*res[4] ||*/ “”;

    if (res[2] === null) {
    return “N/A”;
    }
    if (res[4] === “%”) {
    res[2] *= 100;
    }
    if (k === “profitFactor” && res[2] < 1) {
    res[2] *= -1;
    }

    return res[1] + tz(res[2].toFixed(res[3])) + res[4];
    }

    throw new TypeError("Unsupported type: " + typeof k);
    }
    function dt(timestamp) {
    const D = new Date(timestamp);
    const d = [D.getFullYear(), p(D.getMonth() + 1), p(D.getDate())].join("-");
    const t = [p(D.getHours()), p(D.getMinutes()), p(D.getSeconds())].join(":");

    return d + " " + t;
    }
    function p(x) {
    return (x.length === 1 || x {
    return key.startsWith(“__reactFiber$”);
    });
    const domFiber = dom[key];
    if (domFiber == null) return null;

    const getCompFiber = fiber=>{
    let parentFiber = fiber.return;
    while (typeof parentFiber.type == “string”) {
    parentFiber = parentFiber.return;
    }
    return parentFiber;
    };
    let compFiber = getCompFiber(domFiber);
    for (let i = 0; i < traverseUp; i++) {
    compFiber = getCompFiber(compFiber);
    }
    return compFiber;
    }

    // defining variables
    var rw_new = findReact(document.querySelector("div.report-content.trades-new").parentElement.parentElement)
    .memoizedProps.onCSVReportRequest._listeners[0].object;
    var data_new = rw_new._data;
    var t_new = data_new.trades;
    var sd_new = 4;

    // parsing trades
    let trades3 = {
    headings: ("Trade #,Type,Signal,Date/Time,Price,Contracts,Profit,ProfitPerc,ProfitEqPerc,ProfitEq," +
    "RunUpPerc,RunUp,DrawdownPerc,Drawdown").split(","),
    items: []
    };
    for (i = 0; i < t_new.length; i++) {
    v = t_new[i];
    trades3.items.push([i + 1, type(v.e.tp), v.e.c, dt(v.e.tm), mv(v.e, "$p." + sd_new), , ]);
    trades3.items.push(v.x.c.length
    ? [, type(v.x.tp), v.x.c, dt(v.x.tm), mv(v.x, "$p." + sd_new), v.q, tz(v.pf.toFixed(sd_new)),
    tz(v.tp.p.toFixed(sd_new)), tz(v.cp.p.toFixed(sd_new)), tz(v.cp.v.toFixed(sd_new)),
    tz(v.rn.p.toFixed(sd_new)), tz(v.rn.v.toFixed(sd_new)), tz(v.dd.p.toFixed(sd_new)),
    tz(v.dd.v.toFixed(sd_new))]
    : [, type(v.x.tp), "Open", , , , ,]
    );
    }

    // Copying trades to the clipboard
    clipboard("text/plain", output(trades3));

    1. I tried your new code but it does not work because Tradingview changed the layout around a month ago. Do you have any other solutions? Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Pine Script Programming Courses
Pine Script Programming Courses
Learn to build your own TradingView Indicators and Strategies
Sidebar Signup Form
If you want to be the first in this business, subscribe to the latest news