// ==UserScript==
// @name         IG Trading Simulator
// @version      1.0
// @description  IG Trading Simulator
// @author       M1A1
// @include      http://www.ig.com/pricestream/*
// @grant        none
// ==/UserScript==

console.log("Started");

// add style
function addStyle(css) {
    var head = document.head || document.getElementsByTagName('head')[0];
    if (head) {
        var style = document.createElement("style");
        style.type = "text/css";
        style.appendChild(document.createTextNode(css));
        head.appendChild(style);
    } // end if
} // end of function 

// Create element
function ce(n) { return document.createElement(n); }

function insertAfter(referenceNode, newNode) {
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

// Local storage
function LS_get(key){ return localStorage.getItem("trade_" + key); }
function LS_set(key, value){ localStorage.setItem("trade_" + key, value); }
function LS_rm (key){        localStorage.removeItem("trade_" + key); }

// 
function lpad(num) {
    return ("00" + num).slice(-2);
}

// Clock
function get_hhmmss() {
    var tm = new Date();
    var tm_h = tm.getHours().toString();
    var tm_m = tm.getMinutes().toString();
    var tm_d = tm.getSeconds().toString();
    return lpad(tm_h) + ":" + lpad(tm_m) + ":" + lpad(tm_d); 
}

// Global
var position, 
// figure out if this is moz || IE because they use documentElement
el = (navigator.userAgent.indexOf('Firefox') != -1 || navigator.userAgent.indexOf('MSIE') != -1) ? document.documentElement : document.body;

var nb_trade=0;
var price_in,price_out;
var in_time,out_time;
var in_timestmap,out_timestmap;
var qty,qty_signed;
var myTick; // timer
var position_entered=0; // flag
var trd_div;

// Executed every 0.1 sec
function tick() {
    
    var dur = (Date.now() - in_timestamp)/1000;
    dur = Math.round(dur*10)/10;
    document.querySelector("div.duration").innerHTML = dur.toFixed(1);
    
    // DAX = item#2
    var bid = document.querySelector('td.t2 div[item="2"]');
    var ask = document.querySelector('td.t3 div[item="2"]');
    
    // Actual/out price
    var price = (qty==1) ? Number(bid.innerHTML) : Number(ask.innerHTML);
    price = price.toFixed(1);
        
    var pl = qty * (price - price_in);
    pl = Math.round(pl*10)/10;
    pl = pl.toFixed(1);
        
    var trd_pl = document.querySelector("div.pl");
    trd_pl.innerHTML = pl.toString();
    
    // Colorize : blue/red/white
    trd_pl.className = 'pl'; // flat = white
    if (pl>0) {trd_pl.className = 'pl blue';}
    if (pl<0) {trd_pl.className = 'pl red';}
    
    // update out-time and out-price
    document.querySelector("div.time-out").innerHTML  = get_hhmmss();
    document.querySelector("div.price-out").innerHTML = price.toString();

}


function get_in_out(action) {
    
    // Only one position allowed
    if ((position_entered>0) && (action=="buy") && (qty>0)) {return false;}
    if ((position_entered>0) && (action=="sell") && (qty<0)) {return false;}
    
    // DAX = item#2
    var bid = document.querySelector('td.t2 div[item="2"]');
    var ask = document.querySelector('td.t3 div[item="2"]');
    
    var now_timestamp = Date.now();
    var now_time = get_hhmmss();
    
    // Out price, depends on trade direction
    var action_price = (action=="sell") ? Number(bid.innerHTML) :  Number(ask.innerHTML); 
    action_price = action_price.toFixed(1);
    
    if (position_entered==0) {
        // === TRADE IN  ===
        position_entered = 1;
        qty = (action=="sell") ? -1 : 1;
        price_in = action_price;
        in_time = now_time;
        in_timestamp = now_timestamp;
        
        // Create a new row
        trd_div = ce('div');
        trd_div.setAttribute('id',in_timestamp);
        trd_div.className = "trd";
        
        // Add "+" when on the buy side
        qty_signed = (qty>0) ? "+1" : "-1";        
        nb_trade++;
        
        trd_div.innerHTML = "<div class='num'>"+nb_trade+"</div><div class='qty'>" + qty_signed + "</div><div class='time-in'>" + in_time + "</div><div class='time-out'></div><div class='price'>" + price_in.toString() + "</div><div class='price-out'></div></div><div class='duration'></div><div class='pl'></div><div class='close'>Close</div>";
      //  document.body.appendChild(trd_div);
        // Last trade at the top (IG like)
        var el_summary = document.querySelector(".header-list");
        insertAfter(el_summary,trd_div);
        
        // Create close button
        var btn_close = document.querySelector("div.close");
        if (qty>0) {btn_close.addEventListener('click', function() { get_in_out("sell");}  , false);}
        if (qty<0) {btn_close.addEventListener('click', function() { get_in_out("buy");}  , false);}
        
        // Simulate LightStreamer Ticks with a 100ms update
        myTick = setInterval(function () {tick();}, 100); 
    }
    else
    {
        // === TRADE OUT ===
        clearInterval(myTick);
        position_entered = 0;
        
        price_out = action_price;
        out_time = now_time;
        
        // Update trade row
        // PL
        var pl = qty*(price_out - price_in);
        pl = Math.round(pl*1000000)/1000000;
        pl = pl.toFixed(1);
        
        // Duration (in seconds)
        var dur = (Date.now() - in_timestamp)/1000;
        dur = Math.round(dur*10)/10;
        dur = dur.toFixed(1);
        
        // Find last trade row (with id/timestamp)
        trd_div = document.getElementById(in_timestamp);
        // Add a "+" ?
        qty_signed = (qty>0) ? "+1" : "-1";
        // flat :|
        if (pl==0) {trd_div.innerHTML = "<div class='num'>"+nb_trade+"</div><div class='qty'>" + qty_signed + "</div><div>" + in_time + "</div><div>" + out_time + "</div><div class='price'>" + price_in.toString() + "</div><div class='price'>" + price_out.toString() + "</div><div>" + dur.toString()+ "</div><div class='tpl'>" + pl.toString()+ "</div>";}
        // gain :)
        if (pl>0)  {trd_div.innerHTML = "<div class='num'>"+nb_trade+"</div><div class='qty'>" + qty_signed + "</div><div>" + in_time + "</div><div>" + out_time + "</div><div class='price'>" + price_in.toString() + "</div><div class='price'>" + price_out.toString() + "</div><div>" + dur.toString()+ "</div><div class='tpl blue'>" + pl.toString()+ "</div>";}
        // loss :(
        if (pl<0)  {trd_div.innerHTML = "<div class='num'>"+nb_trade+"</div><div class='qty'>" + qty_signed + "</div><div>" + in_time + "</div><div>" + out_time + "</div><div class='price'>" + price_in.toString() + "</div><div class='price'>" + price_out.toString() + "</div><div>" + dur.toString()+ "</div><div class='tpl red'>" + pl.toString()+ "</div>";}
        
        // === Update Summary Row ===
        // Trades count
        var trade_list = document.querySelectorAll("div.trd");
        var trade_number = trade_list.length-1; // excluding header (with .trd class for aligment)
        
        // Total PL
        var pl_list = document.querySelectorAll("div.tpl");
        var total_pl = 0;
        var pct = 0;
        for (var i = 1; i < pl_list.length; i++) {
            total_pl+=Number(pl_list[i].innerHTML);
            pct += (Number(pl_list[i].innerHTML) >= 0) ? 1 : 0;
        }
        total_pl = Math.round(total_pl*10)/10;
        total_pl = total_pl.toFixed(1);
        
        // % Win rate
        pct = 100 * pct / trade_number;
        pct = Math.round(pct*10)/10;
        pct = pct.toFixed(1);
        
        document.querySelector(".summary").innerHTML = "<div>Summary :</div><div>"+trade_number.toString()+" trade(s)</div><div>"+total_pl.toString()+" pts</div><div>"+pct.toString()+" %</div>";
        
        // Save to localstorage for history and future use
        var trd = new Object();
        trd.timestamp  = in_timestamp;
        trd.qty        = qty_signed;
        trd.time_in    = in_time;
        trd.time_out   = out_time;
        trd.price_in   = price_in;
        trd.price_out  = price_out;
        trd.duration   = dur;
        trd.pl         = pl;    
        LS_set(in_timestamp,JSON.stringify(trd));
        
    }
        
}

// css
var s=''; 
	 
s+='div.trd {border:1px solid #AAA;margin: 2px;padding: 0px;font-size: 12px;font-family: Arial;width:620px;}';
s+='div.trd div {display:inline-block;width:75px;border-right: 1px solid #AAA;text-align: center;height: 22px;line-height: 22px;}';
s+='#tableContainer {margin-bottom: 15px;}';
s+='div[item="2"][field="2"] {border:2px solid #AAA;margin-left: 2px}';
s+='div[item="2"][field="1"] {border:2px solid #AAA;}';
s+='div[item="2"][field="2"]:hover {border:2px solid #0095d6;font-weight:bold;cursor:pointer;}';
s+='div[item="2"][field="1"]:hover {border:2px solid #d92d27;font-weight:bold;cursor:pointer;}';
s+='tbody div {border: 2px solid transparent; margin-left: 2px;}';
//
s+='div.close:hover {font-weight:bold;cursor:pointer;background:#EEE;}';
s+='div.trd div.close {border-right: 0px;width:82px;}';
// pl 
s+='div.pl.red,div.tpl.red   {background:#e83f3c;}';
s+='div.pl.blue,div.tpl.blue {background:#1896d3;}';
//
s+='div.trd div.qty,div.trd div.num  {width:40px;}';
// summary
s+='div.summary {border:1px solid #AAA;margin: 2px;padding: 0px;font-size: 12px;font-family: Arial;background:#EEE;margin-top:8px;margin-bottom:8px;width:620px;}';
s+='div.summary div {display:inline-block;width:80px;border-right: 1px solid #AAA;text-align: center;height: 22px;line-height: 22px;}';
//
s+='.price,.price-out {font-weight:bold;}';
//
s+='div.header-list {color: #555; background: #d3d5d0; font-weight: bold;}';

// Go for it
addStyle(''+s);

if(el){ 
    
        // HIDE non-indice rows
        var tr;
        for (var i = 4; i <= 9; i++) {
            tr = document.querySelector('tr:nth-of-type('+i+')');
            if (tr!==null) tr.style.display = "none";
        }
           
        // Define buy and sell "button" = DAX Bid & Ask
        var bt_buy  = document.querySelector('div[item="2"][field="2"]');
        var bt_sell = document.querySelector('div[item="2"][field="1"]');
    
        bt_buy.addEventListener('click', function()  { get_in_out("buy");}  , false);
        bt_sell.addEventListener('click', function() { get_in_out("sell");} , false);

        // Create summary div
        var summary = ce('div');
        summary.className='summary';
        summary.innerHTML = "<div>Summary:</div><div>-</div><div>-</div><div>-</div>";
        document.body.appendChild(summary);
        
        // Create header div
        var header = ce('div');
        header.className = 'trd header-list';
        header.innerHTML = "<div class='num'>#</div><div class='qty'>Qt</div><div>Entre</div><div>Sortie</div><div class='price'>Ouverture</div><div class='price'>Cloture</div><div>Dure (sec)</div><div class='tpl'>Points</div>" ;
        document.body.appendChild(header);
   
}

