Advertisement
Guest User

quoter.php - котировщик Pi-Bot

a guest
Dec 7th, 2016
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html lang="ru">
  3.  <head>
  4.   <meta charset=utf-8>
  5.   <meta name="author" content="Denusinus">
  6.   <title>BTC-E котировщик v0.1</title>
  7.   <style>
  8.   td{
  9.    vertical-align: top;
  10.   }
  11.   #buy, #sell{
  12.     max-height: 180px;
  13.     overflow: hidden;
  14.   }
  15.   </style>
  16.  
  17.     <script src="http://js.pusher.com/2.2/pusher.min.js" type="text/javascript"></script>
  18.     <script src="js/ajaxsup.js" type="text/javascript"></script>
  19.     <script src="js/jquery-1.11.2.js" type="text/javascript"></script>
  20.     <script src="js/jquery.json-2.4.js" type="text/javascript"></script>
  21. <?php
  22.  
  23.    $state = file_get_contents('trade_state.json');
  24.    echo '<script type="text/javascript">';
  25.   echo "\nvar trade_state_json = '$state';\n";
  26.   echo "</script>\n";
  27.    
  28.    $act = "";
  29.    
  30.    if (isset($_REQUEST['action']))
  31.       $act = $_REQUEST['action'];
  32.      
  33.    if ($act == 'upd_state')
  34.    {
  35.       $state = $_POST['trade_state'];
  36.       file_put_contents('trade_state.json', $state);
  37.    }    
  38.      
  39.      
  40. ?>      
  41.    
  42.     <script type="text/javascript">
  43.    
  44.        
  45.     var ask_last = 0;
  46.     var bid_last = 0;
  47.     // var price_last = 0;
  48.     var recv_count = 0;
  49.     var time_last  = new Date();
  50.     var trade_state = $.evalJSON(trade_state_json);        
  51.    
  52.     var actions      = new Array();
  53.     var orders       = new Object();
  54.     var o2kill       = new Object(); // заявки для снятия
  55.     var orders_count = new Object();   // counters by ticker
  56.     var positions    = new Object();
  57.     var orders_received = false;
  58.     var work_queue   = new Array();  // джобы на выполнении сейчас
  59.    
  60.    
  61.     var sel_orders    = new Object(); // отмеченные заявки в таблице
  62.    
  63.     var in_progress = new Object();    
  64.     var checks_count = 0;
  65.     var idle_ticks = 0;
  66.    
  67.     var post_queue = new Array();
  68.     var trans_map  = new Object(); // transaction map: creating orders
  69.    
  70.     var kill_queue = new Array();
  71.     var killed_map = new Object(); // набор статусов убираемых заявок
  72.     var kill_timer = 0;
  73.     var last_trans_no = new Array();
  74.          
  75.     var nodes_cache = new Object(); // для хранения указателей на узлы под Осла
  76.     var last_min = 0;      
  77.     var last_funds = new Object();
  78.     var last_trade = new Object();
  79.    
  80.     in_progress.load_orders = 0;
  81.    
  82.     // ============================================ functions ========================================= //
  83.     function dumpObject(data)
  84.     {
  85.       var result = "";
  86.       for (var index in data)
  87.       {
  88.         var val = data[index];
  89.         var vt = typeof val;
  90.         result = result + index + " = ";
  91.        
  92.         if (vt == "number" || vt == "string")
  93.            result = result + String(val) + " ";
  94.         else
  95.         if (vt == "object")
  96.            result = result + "{" + dumpObject(val) + "}";
  97.          
  98.         else
  99.            result = result + "@" + vt + " ";  
  100.        
  101.       }
  102.    
  103.       return result;
  104.     }
  105.    
  106.     function elem(id)
  107.     {
  108.        var e = document.getElementById(id);
  109.        if (!e) setHTML("info5", "ERROR: document.getElementById not found element '" + id + "'");
  110.        if (e && typeof e.innerHTML == "undefined") alert(id + ".innerHTML == @undefined");
  111.        return e;
  112.        
  113.     }
  114.    
  115.    
  116.     function volcheck(v)
  117.     {
  118.        v = Number(v) * 100;
  119.        v = v - Math.floor(v);              
  120.        if ( v > 0.33 && v < 0.35 ) return true;
  121.        
  122.        return false;
  123.     }
  124.    
  125.    
  126.     function arval (a, key, def)
  127.     {
  128.        if (typeof a[key] == 'undefined')
  129.            return def;
  130.        else
  131.           return a[key];
  132.     }
  133.  
  134.      
  135.     function LZ(num)
  136.     {
  137.        var A = num.toString();
  138.        if (A.length == 2) return A;        
  139.        if (A.length == 1) return "0" + A;
  140.              
  141.          return "00";
  142.     }
  143.    
  144.     function LZ3 (num)
  145.     {
  146.        var A = num.toString();
  147.        if (A.length >= 3) return A;
  148.        if (A.length == 2) return "0" + A;      
  149.        if (A.length == 1) return "00" + A;              
  150.          return "000";
  151.     }
  152.    
  153.  
  154.     function timeToStr(t)
  155.     {
  156.        return LZ(t.getHours()) + ":" + LZ(t.getMinutes()) + ":" + LZ(t.getSeconds());
  157.     }
  158.     function fullTimeStr(t, sep)
  159.     {
  160.       return LZ(t.getHours()) + sep + LZ(t.getMinutes()) + sep + LZ(t.getSeconds()) + "." + LZ3(t.getMilliseconds());
  161.     }
  162.    
  163.     function setTBodyInnerHTML(tbody, html)
  164.     {
  165.        var temp = tbody.ownerDocument.createElement('div');
  166.        var save_id = tbody.id;
  167.        temp.innerHTML = '<table>' + html + '</table>';
  168.        tbody.id = tbody.id + "1"; // forgot element
  169.        
  170.        var tab = temp.firstChild;
  171.        var cl = tab.children;
  172.        var i;      
  173.        for (i = 0; i < cl.length; i ++) // && fc[0]
  174.        {
  175.          var e = cl[i];
  176.          if (e.tagName == "TBODY")
  177.          {
  178.             e.id = save_id;
  179.             // setHTML ("info3", e.id + "@" + e.tagName + " replacing to " + tbody.id);
  180.             tab = tbody.parentNode;                    
  181.             tab.replaceChild(e, tbody);
  182.             nodes_cache[save_id] = e;
  183.          }
  184.        }
  185.        
  186.     }
  187.    
  188.     function genTransNo()
  189.     {      
  190.        var t = "0";
  191.        var dt = new Date();
  192.        for (i = 0; i < 10; i++)
  193.        {
  194.          t = fullTimeStr(dt, "") + i.toString();
  195.          if (last_trans_no.indexOf(t) < 0) break;
  196.        }
  197.        last_trans_no.push(t);
  198.        if (last_trans_no.length > 10) last_trans_no.shift();
  199.        return t;      
  200.     }
  201.    
  202.     function logMsg(text)
  203.     {
  204.        var e = elem("debug_log");
  205.        var t = timeToStr(new Date());
  206.        if (e)      
  207.        {
  208.            var lines = e.innerHTML.split("\n");
  209.            while (lines.length > 500) lines.shift();
  210.            e.innerHTML = lines.join("\n") + "[" + t + "]. " + text + "</br>\n";
  211.        }          
  212.     }
  213.    
  214.     function findWork(name, target)
  215.     {
  216.       for (i = 0; i < work_queue.length; i++)
  217.       {
  218.           var w = work_queue[i];
  219.           if (w.name == name && w.target == target) return w;
  220.       }
  221.       return false;
  222.     }
  223.    
  224.     function readyForWork (name, target)
  225.     {
  226.       return (!findWork(name, target) && work_queue.length < 5);
  227.     }
  228.    
  229.     function workFailed(name, target)
  230.     {
  231.       var w = findWork(name, target);
  232.       if (w)
  233.        {
  234.            w.status = "error";
  235.            w.fail_count = w.fail_count + 1;
  236.        }
  237.    
  238.     }
  239.    
  240.     function workSuccess(name, target)
  241.     {
  242.        var w = findWork(name, target);
  243.        if (w) w.status = "complete";
  244.     }
  245.  
  246.    
  247.     function schedule(cmd, args)
  248.     {
  249.       actions[actions.length] = { command: cmd, params: args };
  250.     }
  251.    
  252.     function killPostpone(id)
  253.     {
  254.       if (kill_queue.indexOf(id) < 0 && !arval(killed_map, id, false))
  255.       {
  256.           kill_queue.push(id);
  257.           sel_orders[id] = false;
  258.           killed_map[id] = 1;
  259.           idle_ticks = 0;
  260.          
  261.           var e = elem('cbx' + id);
  262.            
  263.           if (e)
  264.           {
  265.              e.checked = false;
  266.              var tr  = e.parentElement.parentElement;
  267.              var tab = tr.parentElement;
  268.              // alert (tab.nodeName);
  269.              tr.style.backgroundColor = '#FFEEEE';
  270.              // if (tab) tab.removeChild(tr);
  271.           }          
  272.        }  
  273.     }
  274.    
  275.     function killFailed(id)
  276.     {
  277.        o2kill[id] = false;
  278.        killed_map[id] = 0;
  279.        killPostpone(id);      
  280.        if (1 == kill_queue.length)
  281.            kill_timer = 1;
  282.        workFailed("kill_order", id);  
  283.     }
  284.    
  285.     function killSuccess(id)
  286.     {
  287.        // ok
  288.        killed_map[id] = 2;
  289.        workSuccess("kill_order", id);
  290.        in_progress.load_orders = 3;                    
  291.     }
  292.    
  293.     function killOrder(id)
  294.     {
  295.       idle_ticks = 0;
  296.       $.ajax(
  297.          { dataType: "json",
  298.               cache: false,
  299.                 url: "brokserv.php?action=kill_order&order_id=" + id,              
  300.               error: function (jqXHR, status, err)  { logMsg ("#ERROR(killOrder): " + status); killFailed(id); },
  301.             timeout: 28500,  
  302.             success: function (data, status, jqXHR)
  303.                      {
  304.                         var err = arval(data, "error", "");                        
  305.                         logMsg ("#SUCCESS(killOrder " + id + "): " + status + ", data: " + dumpObject(data));
  306.                         if(1 == data.success || "bad status" == err) killSuccess(id);
  307.                      }
  308.          } );
  309.     }
  310.        
  311.    
  312.    
  313.     function scheduledCancel(timeout)        
  314.     {
  315.        if (0 == kill_queue.length)
  316.            return;
  317.        
  318.        var cnt = 0;
  319.        for (var i = 0; i < kill_queue.length; i ++)
  320.        {
  321.          var id = kill_queue.shift();
  322.          if (arval(killed_map, id, false)) continue;
  323.          
  324.          cnt = cnt + 1;
  325.          logMsg("   scheduled cancel order #" + String(id) + ", cnt = " + String(cnt));        
  326.          setTimeout ( "killOrder(" + String(id) + ")", cnt * 500 + 5 );
  327.          o2kill[id] = true;
  328.          
  329.          if (cnt >= 10) break;
  330.        } // for
  331.        
  332.        
  333.        if (kill_queue.length > 0)
  334.            kill_timer = 5;          
  335.     }
  336.  
  337.     function cancelOrders(params)
  338.     {
  339.       // by ticker and volume tag
  340.       if (kill_queue.length > 0)
  341.       {
  342.         // scheduledCancel(1);
  343.         return;        
  344.       }
  345.      
  346.      
  347.       logMsg("cancelOrders: ticker = " + params.ticker);
  348.       var cnt = 0;
  349.        
  350.       for (var id in orders)      
  351.       {
  352.          var rec = orders[id];
  353.          if (rec.pair != params.ticker || !volcheck(rec.qty) ) continue;
  354.          if (o2kill[id] || arval(killed_map, id, false)) continue; // trying to kill
  355.          
  356.          /* if (cnt < 5)
  357.          {
  358.            logMsg("immediate cancelling order " + id + " price = " + String(rec.price) + ", qty = " + String(rec.qty));
  359.            setTimeout ( "killOrder(" + String(id) + ")", cnt * 500 + 5 );
  360.          }
  361.          else */  
  362.          {          
  363.            logMsg("scheduled cancelling order " + id + " price = " + String(rec.price) + ", qty = " + String(rec.qty));
  364.            killPostpone(id);      
  365.          }
  366.                                    
  367.          // killOrder (id);
  368.          o2kill[id] = true;
  369.          cnt = cnt + 1;                
  370.       }      
  371.       if (kill_queue.length > 0 && 0 == kill_timer)
  372.           kill_timer = 5;                              
  373.     }
  374.  
  375.     function cancelSelected()    
  376.     {
  377.        for (var id in sel_orders)
  378.        if (sel_orders[id])      
  379.            killPostpone(id);      
  380.     }
  381.    
  382.    
  383.     function createOrder(ticker, price, qty, dir, tno)
  384.     {
  385.        idle_ticks = 0;
  386.        if (typeof price == "undefined" || price <= 0.0001)
  387.        {
  388.           logMsg("#ERROR(createOrder): price not valid = " + String(price));
  389.           workFailed("create_order", tno);
  390.           return;            
  391.        }
  392.  
  393.        if (price < 0.001)
  394.          price = price.toFixed(5); else
  395.          if (price < 0.01)
  396.            price = price.toFixed(4); else          
  397.            if (price < 10)          
  398.                price = price.toFixed(3); else
  399.              if (price > 100)
  400.                  price = price.toFixed(2);
  401.              
  402.  
  403.        logMsg("#DBG(createOrder): " + dir  + " " + ticker + " @ " + String(price));
  404.  
  405.        $.ajax(
  406.        { dataType: "json",
  407.             cache: false,
  408.               url: "brokserv.php?action=new_order&pair=" + ticker +
  409.                    "&price=" + String(price) + "&qty=" + String(qty) + "&dir=" + dir,              
  410.             error: function (jqXHR, status, err)  
  411.                    { logMsg ("#ERROR(createOrder): " + status);
  412.                      workFailed("create_order", tno);
  413.                    },
  414.           timeout: 15500,  
  415.           success: function (data, status, jqXHR)
  416.                    {
  417.                       logMsg ("#SUCCESS(createOrder): price = " + String(price) + ", data: " + dumpObject(data));
  418.                       if (1 == data.success)
  419.                       {
  420.                           workSuccess ("create_order", tno);
  421.                           in_progress.load_orders = 3;
  422.                           var funds = data["return"].funds;
  423.                           $.each(funds, function(key, val)
  424.                            {
  425.                              last_funds[key] = val;
  426.                              if ("nvc" == key) setHTML("info4", "nvc amount now = " + String(val));
  427.                            }
  428.                           );
  429.                       }
  430.                       else
  431.                           workFailed  ("create_order", tno);    
  432.                    }
  433.        } );      
  434.     }
  435.    
  436.     function addOrder(t, p, v, d)
  437.     {                                  
  438.       var obj = { ticker: t, price: p, amount: v, dir: d };
  439.       obj.transNo = genTransNo();
  440.       post_queue.push(obj.transNo);      
  441.       trans_map[obj.transNo] = obj;
  442.     }
  443.    
  444.    
  445.    
  446.     function scheduleOrders (params, index)
  447.     {
  448.       var t = params.ticker;
  449.       var ask = params.a_targets[index];      
  450.       // setTimeout ( function () { createOrder(t, ask, 0.1034, "sell"); }, index * 500 + 5 );
  451.       addOrder(t, ask, params.volume, "sell");      
  452.       var bid = params.b_targets[index];
  453.       addOrder(t, bid, params.volume, "buy");
  454.       // setTimeout ( function () { createOrder(t, bid, 0.1034, "buy"); },  index * 500 + 250 );  
  455.     }
  456.    
  457.     function placeOrders(params)
  458.     {
  459.       if (orders.length > 32)
  460.       {
  461.          logMsg("#ERROR: placeOrders breaked due to many orders active");
  462.          return;
  463.       }
  464.        
  465.       var dt = new Date();
  466.        
  467.       if (dt.getHours() < 23) // TODO: preserve cool-down time 10 minutes only  
  468.         for (var i = 0; i < 8; i ++)
  469.              scheduleOrders(params, i);
  470.    
  471.     }
  472.    
  473.    
  474.     function processAction()
  475.     {
  476.    
  477.        if (kill_timer > 0)
  478.        {
  479.            kill_timer = kill_timer - 1;
  480.            // if (0 == kill_timer)  scheduledCancel(1);                      
  481.        }    
  482.       setTimeout(processAction, 1000);
  483.       if (actions.length == 0) return;
  484.       var action = actions.shift();
  485.       var cmd = action.command;
  486.       if ("KILL_ORDERS" == cmd)
  487.           cancelOrders(action.params);
  488.       if ("NEW_ORDERS" == cmd)
  489.           placeOrders(action.params);  
  490.       logMsg("processed action: " + cmd);
  491.     }
  492.    
  493.     function addWork(name, target, params)
  494.     {
  495.       var w = new Object();
  496.       w.name = name;
  497.       w.target = target;
  498.       w.status = "new";
  499.       w.fail_count = 0;
  500.       w.timeout    = 300;
  501.       w.params     = params;    
  502.       work_queue.push(w);
  503.       return w;
  504.     }
  505.    
  506.     function handleWork(w)
  507.     {
  508.       w.status = "progress";
  509.       if ("create_order" == w.name)
  510.       {
  511.         var o = w.params;                
  512.         if (o)
  513.         {
  514.             createOrder(o.ticker, o.price, o.amount, o.dir, w.target);
  515.             logMsg("#DBG: handleWork/create_order params = " + dumpObject(o));
  516.         }
  517.       }
  518.       if ("kill_order" == w.name)
  519.           killOrder(w.target);
  520.          
  521.       if ("load_orders" == w.name)
  522.           requestOrders();        
  523.       if ("load_trades" == w.name)
  524.           requestTrades();  
  525.     }
  526.    
  527.     function processWork()
  528.     {
  529.       setTimeout(processWork, 100);
  530.       var i = 0;
  531.       var dt = new Date();
  532.       var sec = dt.getSeconds();
  533.       var tm = dt.getMinutes(); // Math.round (sec / 5);  
  534.       var hr = dt.getHours();
  535.       if (tm != last_min)
  536.       {
  537.         last_min = tm;        
  538.         var price = 1.301;        
  539.        
  540.         var btc_price = 700;
  541.         st = trade_state["btc_usd"];        
  542.         if (typeof st != "undefined" && st.price_last > 0)
  543.             btc_price = st.price_last;
  544.         st = trade_state["nvc_btc"];
  545.        
  546.         var nvc_btc = 0.0005;          
  547.        
  548.         if (typeof st != "undefined" && st.price_last > 0)
  549.              nvc_btc = st.price_last;
  550.              
  551.         var target = nvc_btc * btc_price;
  552.        
  553.         var st = trade_state ["nvc_usd"];
  554.         if (typeof st != "undefined" && st.price_last > 0)
  555.             price = st.price_last;      
  556.        
  557.        
  558.         if (price != 1.301)
  559.         {
  560.           price = price.toFixed(3);
  561.           var rv = Math.random() * 20;          
  562.           logMsg("#DBG: шальной прострел новы по цене около price_last = " + String(price) + ", target = " + String(target) + ", ref = " + String(nvc_btc));          
  563.  
  564.           if (price > target + 0.003)                                        
  565.             {
  566.               createOrder("nvc_usd", Number(target) -    0.001, 3.1415, "sell", 0);
  567.               createOrder("nvc_btc", nvc_btc + 0.00001, 3.1415, "buy",  0);
  568.             }
  569.           else
  570.           // if (price < target - 0.003)
  571.           {
  572.             createOrder("nvc_usd", target + 0.003, 3.14159, "buy",  0);
  573.             createOrder("nvc_btc", nvc_btc - 0.00001, 3.14159, "sell",  0);
  574.           }
  575.                                
  576.           // 1DvHSF7RMCfd3y3SFgFmvxMqK8K5kTKTTD
  577.           // createOrder("nvc_btc", 1,  3.1415926, "buy", 0);
  578.         }
  579.        
  580.         var day = dt.getDate();
  581.         if (day == 8 && price != 1.301)
  582.         {
  583.           var qadd = ( Math.floor (st.qty_last) % 10 ) * 0.1;
  584.           qadd = qadd + ( st.qty_last - Math.floor(st.qty_last) ) * 0.5;            
  585.           var qty_buy  = 100;
  586.           var qty_sell = 100;
  587.          
  588.           if (sec % 20 == 0)
  589.           {
  590.              if (st.side_last == "sell")
  591.                  qty_buy = qty_buy + qadd;
  592.              else
  593.                  qty_buy = qty_buy - qadd;    
  594.             logMsg("#DBG: correction volume for " + String(st.qty_last) + " = " + String(qadd));
  595.           }
  596.          
  597.                  
  598.           // createOrder("nvc_usd", Number(price) - 0.000, qty_buy.toFixed(8),  "buy",  0);
  599.           // createOrder("nvc_usd", Number(price) + 0.000, qty_sell.toFixed(8), "sell", 0);                  
  600.         }
  601.        
  602.         if (hr >= 22 && hr < 23)
  603.         {
  604.           // logMsg("#DBG: шальная продажа новы по цене, price_last = " + String(price));
  605.           // createOrder("nvc_usd", 1, 3.1415926, "sell", 0);
  606.           // createOrder("nvc_btc", 0.001,  3.1415926, "sell", 0);
  607.         }
  608.        
  609.              
  610.         var amount = last_funds["nvc"];
  611.         if (typeof amount != "undefined" && amount > 1000 && hr == 21)
  612.         {
  613.            price = price * 0.99;
  614.            price = price.toFixed(3);
  615.            logMsg("#DBG: заявка на ликвидацию позиции по цене $ " + String(price));
  616.            createOrder("nvc_usd", price, 500.0034, "sell", 0);
  617.            price = price / btc_price;
  618.            price = price.toFixed(5);
  619.            logMsg("#DBG: заявка на ликвидацию позиции по цене BTC " + String(price));
  620.            createOrder("nvc_btc", price, 500.0034, "sell", 0);
  621.         }      
  622.       }
  623.      
  624.      
  625.       var tab = "";
  626.       var wrest = new Array();
  627.       // dumping works      
  628.       for (i = 0; i < work_queue.length; i++)
  629.       {
  630.           var w = work_queue[i];
  631.           tab = tab + "<tr><td>" + w.name + "<td>" + w.target + "<td>" + w.status;
  632.           if ("complete" != w.status && w.fail_count < 3 && w.timeout > 0)
  633.               wrest.push (w);          
  634.           if ("error" == w.status)  
  635.               tab = tab + ":" + w.fail_count;
  636.  
  637.           if ("progress" == w.status)
  638.           {
  639.               w.timeout = w.timeout - 1;
  640.               tab = tab + ":" + w.timeout;
  641.           }  
  642.       }
  643.       for (i = work_queue.length; i < 5; i ++)
  644.            tab = tab + "<tr><td>idle<td>nope<td>wait...";
  645.  
  646.       var e = elem("tbody_jobs");      
  647.       if (e)
  648.       {
  649.         if (navigator  &&  navigator.userAgent.match( /MSIE/i ))
  650.            setTBodyInnerHTML(e, tab);
  651.         else
  652.            e.innerHTML = tab;
  653.       }
  654.      
  655.       // handling single work
  656.       for (i = 0; i < work_queue.length; i++)
  657.       {
  658.          var w = work_queue[i];
  659.          if (w.status == "new" || w.status == "error")
  660.          {
  661.              handleWork(w);
  662.              break;
  663.          }        
  664.       }
  665.      
  666.       work_queue = wrest;      
  667.      
  668.       // pushing new jobs
  669.       if (work_queue.length >= 5) return;
  670.            
  671.       if (kill_queue.length > 0)      
  672.       {
  673.          var id = kill_queue.shift();
  674.          addWork("kill_order", id);
  675.          return;
  676.       }
  677.       if (post_queue.length > 0)
  678.       {
  679.          var tno = post_queue.shift();
  680.          addWork("create_order", tno, trans_map[tno]);
  681.          return;
  682.       }
  683.      
  684.    
  685.     }
  686.    
  687.    
  688.     var pusher = null;
  689.    
  690.     var sender = makeXMLRequest();  
  691.    
  692.     function setHTML(id, text)
  693.     {
  694.        var e = elem(id);
  695.        if (e == null)
  696.        {
  697.            setHTML("info", "ERROR: not found element: " + id);
  698.            return;  
  699.        }
  700.              
  701.        if (typeof text != "undefined")
  702.            e.innerHTML = text.toString();
  703.        else
  704.            e.innerHTML = "NULL";    
  705.     }
  706.  
  707.  
  708.  
  709.     function onTrade(ticker, data)
  710.     {            
  711.    
  712.        var i = data.length - 1;
  713.        // setHTML("info", "data last: " + i.toString());
  714.        if (i < 0) return;        
  715.        var rec = data[i];      
  716.        if (typeof rec == "undefined")
  717.        {
  718.           setHTML("info4", "data.last undefined!");
  719.           return;
  720.        }
  721.        
  722.        if (typeof rec[1] == "undefined")
  723.        {
  724.           setHTML("info4", "data.last[1] undefined!");
  725.           return;
  726.        }
  727.        var state = trade_state[ticker];
  728.        if (typeof state == "undefined")
  729.            state = { price_last: 0, price_ref: 0 };
  730.            
  731.        var price_ref = arval (state, 'price_ref', 0);      
  732.        // setHTML("info", "record length: " + rec.length.toString());
  733.        
  734.        recv_count = recv_count + 1;
  735.        setHTML("counter", String(recv_count) + ", checks: " + String(checks_count) + ", idle: " + String(idle_ticks));
  736.        
  737.        time_last = new Date();  // received was
  738.        
  739.        var pval = Number (rec[1]);        
  740.        
  741.        if (ticker != "btc_usd")
  742.           setHTML("info", "onTrade: " + ticker + "@" + pval);
  743.        
  744.              
  745.        state['side_last']  = rec[0];
  746.        state['price_last'] = pval;
  747.        state['qty_last']   = Number(rec[2]);
  748.        state['time_last']  = timeToStr (time_last);
  749.        
  750.        if (!orders_received)
  751.        {
  752.          setHTML("info4", "onTrade: orders_received === false");
  753.          return;
  754.        }
  755.        
  756.        
  757.        // if ( Math.abs(pval - price_ref) < 0.0001 ) return;
  758.        if (ticker == "nvc_usd")
  759.            logMsg(" nvc price changed from " + String(price_rev) + " to " + String(pval));
  760.              
  761.        
  762.        state['price_ref']  = pval;
  763.        /*
  764.        var a_targets = new Array( 0, 0, 0, 0, 0, 0, 0, 0 );
  765.        var b_targets = new Array( 0, 0, 0, 0, 0, 0, 0, 0 );
  766.        
  767.        var fp = 1;
  768.        if (pval < 100)   fp = 2;
  769.        if (pval < 10)    fp = 3;
  770.        if (pval < 0.1)   fp = 4;
  771.        if (pval < 0.01)  fp = 5;
  772.        // if (pval < 0.01) fp = 6;
  773.        
  774.        
  775.        for (var i = 0; i < a_targets.length; i ++)
  776.        {
  777.           var delta = (i + 1) * 0.02;
  778.           var price = pval * (1 + delta);
  779.           a_targets[i] = price.toFixed(fp);
  780.           price = pval * (1 - delta);
  781.           b_targets[i] = price.toFixed(fp);
  782.        }
  783.              
  784.        state['ask_targets'] = a_targets;
  785.        state['bid_targets'] = b_targets;
  786.              
  787.        // TODO: start order replacing (cancel/new) by timer
  788.        var args = new Object();
  789.        args.ticker = ticker;
  790.        args.tag    = 0.0034;  // float qty tag
  791.        schedule("KILL_ORDERS", args);
  792.        
  793.        orders_active = arval(orders_count, ticker, 0);      
  794.        setHTML ("info3", "active orders for '" + ticker + "'  = " + String(orders_active));
  795.        if (orders_active > 16)
  796.        {
  797.           setHTML ("info5", "#OVERF: to many active orders for '" + ticker + "' = " + String(orders_active));
  798.           // schedule("KILL_ORDERS", args);
  799.           return 0;
  800.        }
  801.        
  802.        
  803.        args.a_targets = a_targets;
  804.        args.b_targets = b_targets;
  805.        args.price = pval;
  806.        args.volume = 0.1034;
  807.        if (pval < 2)
  808.            args.volume = 1.0034;
  809.              
  810.        schedule("NEW_ORDERS",  args);              
  811.                
  812.                
  813.        setHTML("ask_target", a_targets.join(", ") );
  814.        setHTML("bid_target", b_targets.join(", ") );      
  815.        
  816.        
  817.        // alert(txt);
  818.        */
  819.  
  820.        trade_state[ticker] = state;      
  821.        var txt = $.toJSON (trade_state);
  822.        sender.open("POST", "quoter.php", true);
  823.        var params = "action=upd_state&trade_state=" + encodeURIComponent(txt);
  824.        sender.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  825.        sender.send(params);        
  826.          
  827.     }
  828.  
  829.     function onTrade_1(data) { onTrade("btc_usd", data); }
  830.    
  831.     function checkDataLag()
  832.     {      
  833.       var now = new Date();  
  834.       var lag = now - time_last;
  835.       setHTML("lag", lag / 1000.0);
  836.      
  837.       var delay = 1000 - (lag % 1000);
  838.       if (delay < 100) delay += 1000;
  839.       setTimeout(checkDataLag, delay);
  840.       checks_count ++;
  841.       idle_ticks ++;
  842.      
  843.       if (checks_count > 1000 && 0 == work_queue.length && 0 == post_queue.length && 0 == kill_queue.length)
  844.           location.reload();
  845.          
  846.       if (idle_ticks > 100 && 0 == idle_ticks % 10)
  847.       { // memory optimization
  848.         killed_map = new Object(); //
  849.       }
  850.  
  851.       for (var index in trade_state)
  852.        if (index != "version")
  853.          {      
  854.             var item = trade_state[index];
  855.             setHTML(index + ".side",      item['side_last']);
  856.             setHTML(index + ".ticker",     index);
  857.             setHTML(index + ".price",      item['price_last']);
  858.             setHTML(index + ".qty",        item['qty_last']);                
  859.             setHTML(index + ".time",       item['time_last']);
  860.          };
  861.          
  862.     }
  863.    
  864.     function subscribeData(ticker, t_callback)
  865.     {
  866.       var channel = pusher.subscribe(ticker + '.trades');          
  867.       channel.bind('trades', t_callback);        
  868.       logMsg("#SUBSCRIBED: " + ticker);
  869.     }
  870.  
  871.     function parseTrades(data)
  872.     {
  873.       setHTML ("info2", "parseTrades - processing data");
  874.       positions = new Object();
  875.    
  876.       if (typeof data[0] != "undefined")  
  877.       {        
  878.      
  879.          var e = elem("tbody_trades");
  880.          var tab = ""; // e.innerHTML;  
  881.          var count = 0;
  882.          var bs = new Array("sell", "buy");  
  883.          var rows = new Array();
  884.          setHTML ("info4", "parseTrades - processing start");
  885.          $.each( data, function(key, val)
  886.           {          
  887.              // logMsg("#DEBUG: Added order " + key + " " + val.pair);            
  888.              // return;              
  889.              var r = "<tr><td>" + val.id;                    
  890.              amount = Number(val.qty);
  891.              if (0 == val.buy) amount = -amount;            
  892.              r = r + "<td>" + val.short_name + "<td>" + bs[val.buy] + "<td>" + val.qty + "<td>" + val.price + "<td>" + val.ts + "\n";
  893.              
  894.              rows.push (r);
  895.              if (volcheck(val.amount))
  896.                  positions[val.short_name] = arval(positions, val.short_name, 0) + amount;
  897.              last_trade[val.short_name] = Number(val.price);
  898.              
  899.           }
  900.          );
  901.          
  902.          while (rows.length > 15) rows.shift();
  903.          
  904.          if (navigator  &&  navigator.userAgent.match( /MSIE/i ))
  905.           setTBodyInnerHTML(e, rows.join("\n"));
  906.          else          
  907.           e.innerHTML = rows.join("\n");
  908.          e = elem("tbody_positions");
  909.          tab = "";
  910.          for (var pair in positions)
  911.          {
  912.             amount = arval(positions, pair, 0);
  913.             tab = tab + "<tr><td>" + pair + "<td>" + amount + "\n";  
  914.          }
  915.          if (navigator  &&  navigator.userAgent.match( /MSIE/i ))
  916.           setTBodyInnerHTML(e, tab);
  917.          else          
  918.           e.innerHTML = tab;        
  919.       }
  920.     }
  921.  
  922.     function requestTrades()
  923.     {        
  924.        $.ajax(
  925.          { dataType: "json",
  926.               cache: false,
  927.                 url: "brokserv.php?action=daily_trades&filter=34",              
  928.               error: function (jqXHR, status, err)  
  929.                      {
  930.                        setHTML ("info5", "loadTrades - ajax rqs failed" + status);
  931.                        in_progress.load_trades = 1;
  932.                        workFailed("load_trades", 0);
  933.                      },
  934.             timeout: 15000,  
  935.             success: function (data, status, jqXHR)            
  936.                      {  
  937.                         in_progress.load_trades = 1;
  938.                         if ("success" == status)
  939.                         {                    
  940.                            parseTrades(data);
  941.                            in_progress.load_trades = 0;
  942.                            workSuccess("load_trades", 0);
  943.                         }
  944.                         else
  945.                            workFailed("load_trades", 0);
  946.                      }
  947.          } );
  948.       setHTML ("info2", "requestTrades - ajax rqs created");      
  949.     }
  950.  
  951.  
  952.     function selOrder(cbx)
  953.     {
  954.       var id = cbx.id.substr(3);
  955.       //alert(id + " = " + cbx.checked);
  956.       sel_orders[id] = cbx.checked;    
  957.     }
  958.  
  959.     function parseOrders(data)
  960.     {    
  961.       var ret = data["return"];
  962.       setHTML("odump", "data = " + toString(data));
  963.      
  964.       if (typeof ret != "undefined")
  965.       {    
  966.          var e = elem("tbody_orders");
  967.          var tab = ""; // e.innerHTML;  
  968.          var count = 0;    
  969.          var prev_queued = kill_queue.length;
  970.          var dt = new Date();
  971.          setHTML ("info2", "parseOrders - processing start");
  972.          orders_received = true;              
  973.          orders_count = new Object();  
  974.          var sel_orders_new = new Object();
  975.                    
  976.          $.each( ret, function(key, val)
  977.           {          
  978.              // logMsg("#DEBUG: Added order " + key + " " + val.pair);            
  979.              // if (!volcheck(val.amount)) return;
  980.              count = count + 1;
  981.                            
  982.              var row = "<tr><td>" + count.toString() + "<td>" + key;
  983.              ts = val.timestamp_created;
  984.              dt.setTime( Number(ts) * 1000 );
  985.              row = row + "<td>" + val.pair + "<td>" + val.type + "<td>" + val.amount + "<td>" + val.rate + "<td>" + timeToStr(dt);
  986.              var rec = new Object();
  987.              rec.price = val.rate;
  988.              rec.pair  = val.pair;
  989.              rec.side  = val.type;
  990.              rec.qty   = val.amount;
  991.              
  992.              orders[key] = rec;
  993.              
  994.              active = arval(orders_count, rec.pair, 0) + 1;
  995.              orders_count[rec.pair] = active;
  996.              
  997.              // \"" + key + "\"
  998.              var chk = '';
  999.              if (sel_orders[key]) chk = 'checked=true';
  1000.              row = row + "<td><input id='cbx" + key + "' onclick='selOrder(this);'  type='checkbox' " + chk + " />";
  1001.              tab = tab + row;
  1002.              
  1003.              sel_orders_new[key] = sel_orders[key];
  1004.              
  1005.              if (o2kill[key] || active > 16)
  1006.              {
  1007.                 if (rec.qty < 10)  kill_queue.push(key);
  1008.              }                  
  1009.           }
  1010.          );
  1011.          sel_orders = sel_orders_new;  // forgot deprecated orders
  1012.          
  1013.          if (navigator  &&  navigator.userAgent.match( /MSIE/i ))
  1014.            setTBodyInnerHTML(e, tab);
  1015.          else
  1016.            e.innerHTML = tab;
  1017.                
  1018.          // logMsg("#DBG: parseOrders processed " + String(count) + " rows");
  1019.                
  1020.          if (kill_queue.length > 0 && 0 == prev_queued && checks_count < 100)
  1021.          {
  1022.             kill_timer = 5;
  1023.             logMsg("#WARN: some orders scheduled for cancel. Total active orders = " + String(count));            
  1024.          }
  1025.          // loadTrades();
  1026.          if (readyForWork("load_trades", 0))
  1027.          {      
  1028.             var w = addWork("load_trades", 0);
  1029.             w.timeout = 3000;
  1030.          }
  1031.          
  1032.       }
  1033.       else
  1034.         logMsg("#ERROR(parseOrders): invalid object " + data);
  1035.     }
  1036.  
  1037.    
  1038.     function loadOrders()
  1039.     {
  1040.        setTimeout(loadOrders, 500);          
  1041.        
  1042.        if (in_progress.load_orders > 0)      
  1043.        {
  1044.           in_progress.load_orders--;
  1045.           setHTML ("info3", timeToStr(new Date()) + " in_progress.load_orders = " + String(in_progress.load_orders));          
  1046.        }
  1047.        else
  1048.        {            
  1049.           if (!readyForWork("load_orders", 0)) return; // busy      
  1050.           in_progress.load_orders = 20;
  1051.           var w = addWork("load_orders", 0);
  1052.           w.timeout = 3000;
  1053.        }        
  1054.     }
  1055.    
  1056.     function requestOrders()
  1057.     {
  1058.        setHTML ("info2", "requestOrders - ajax rqs created");
  1059.         $.ajax(
  1060.          { dataType: "json",
  1061.               cache: false,
  1062.                 url: "brokserv.php?action=orders",              
  1063.               error: function (jqXHR, status, err)  
  1064.                       { logMsg ("#ERROR(loadOrders): " + status);
  1065.                         workFailed("load_orders", 0);
  1066.                         in_progress.load_orders = 3;
  1067.                       },
  1068.             timeout: 15000,  
  1069.             success: function (data, status, jqXHR)
  1070.                      {
  1071.                         if ("success" == status)
  1072.                         {
  1073.                           parseOrders(data);
  1074.                           in_progress.load_orders = 20;                          
  1075.                           setHTML ("info5", "requestOrders - ajax rqs status = " + status);
  1076.                           workSuccess("load_orders", 0);
  1077.                         }
  1078.                         else
  1079.                           workFailed("load_orders", 0);
  1080.                      }
  1081.          } );      
  1082.     } // requestOrders
  1083.    
  1084.    
  1085.     function connectPusher()
  1086.     {
  1087.       pusher = new Pusher('c354d4d129ee0faa5c92');
  1088.       subscribeData("btc_usd", function (data)
  1089.                                { onTrade("btc_usd", data);} );
  1090.       subscribeData("nvc_usd", function (data)
  1091.                                { onTrade("nvc_usd", data);} );
  1092.       subscribeData("nvc_btc", function (data)
  1093.                                { onTrade("nvc_btc", data);} );                            
  1094.                                                            
  1095.     }
  1096.    
  1097.    
  1098.     function afterLoad()
  1099.     {                      
  1100.       setHTML("info", "afterLoad.1");
  1101.       setTimeout(checkDataLag,  1000);      
  1102.       setTimeout(connectPusher, 2000);      
  1103.       setHTML("info", "afterLoad.2");            
  1104.       // var data = new Array(0);
  1105.       // data[0] = new Array ("buy", "279.3", "1");
  1106.       // onTrade_1(data);
  1107.            
  1108.       loadOrders ();
  1109.       processAction();
  1110.       processWork();
  1111.       // setHTML("info", "afterLoad.3");
  1112.     }        
  1113.    
  1114.     </script>
  1115.  
  1116.   </head>
  1117.   <body onLoad="afterLoad()">
  1118.     <h1>Last trades</h1>
  1119.     <?php
  1120.              
  1121.        function add_hcells($data)
  1122.        {
  1123.          foreach ($data as $text) echo("<th>$text</th>\n");
  1124.        }
  1125.        function add_dcells($data)
  1126.        { foreach ($data as $text) echo("<td>$text</td>\n"); }
  1127.        
  1128.        function add_ticker_table($ticker)    
  1129.        {            
  1130.           $tab_header = '<table border="1" width="400" cellpadding="7" style="border-collapse:collapse;">'."\n";
  1131.           echo($tab_header);
  1132.           echo("<tr>");
  1133.           add_hcells( array("Side", "Ticker", "Price", "Qty", "Received") );
  1134.           echo("<tr>");
  1135.           $flds = array("side", "ticker", "price", "qty", "time");
  1136.           foreach ($flds as $fld) add_dcells( array("<div id='$ticker.$fld'></div>") );
  1137.           echo("</table>");  
  1138.        }
  1139.    
  1140.        add_ticker_table("btc_usd");
  1141.        add_ticker_table("nvc_btc");
  1142.        add_ticker_table("nvc_usd");
  1143.        add_ticker_table("ltc_btc");
  1144.     ?>
  1145.    
  1146.  
  1147.    
  1148.    
  1149.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">
  1150.      <tr>
  1151.        <td>Target ask price<td><div id="ask_target"></div>
  1152.      <tr>
  1153.        <td>Target bid price<td><div id="bid_target"></div>  
  1154.     </table>
  1155.  
  1156.  
  1157.     <h2>Orders</h2>
  1158.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">
  1159.       <tr><th width=50>№<th>ID<th>Pair<th>Side<th>Qty<th>Price<th>Time
  1160.       <tbody id="tbody_orders">
  1161.       </tbody>
  1162.     </table>
  1163.    
  1164.     <input type="button" value="Cancel selected" onclick="cancelSelected();" /><br />
  1165.    
  1166.     <h2>Trades</h2>
  1167.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">
  1168.       <tr><th>ID<th>Pair<th>Side<th>Qty<th>Price<th>Time
  1169.       <tbody id="tbody_trades">
  1170.       </tbody>
  1171.     </table>
  1172.    
  1173.     <h2>Positions</h2>
  1174.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">
  1175.       <tr><th>Pair<th>Amount
  1176.       <tbody id="tbody_positions">
  1177.       </tbody>
  1178.     </table>
  1179.    
  1180.  
  1181.     <h2>Works/Jobs</h2>
  1182.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">
  1183.       <thead><tr><th width="250">Name<th width="150">Target<th width="300">Status</thead>
  1184.       <tbody id="tbody_jobs">
  1185.       </tbody>
  1186.     </table>
  1187.    
  1188.     <h2>Status & Log</h2>
  1189.     <table border="1" width="700" cellpadding="7" style="border-collapse:collapse;">      
  1190.       <tr><td width=200>received records:<td width=500><span id="counter">0</span>  
  1191.       <tr><td>Status 1<td><span id="info">WARN: Script not worked!</span>
  1192.       <tr><td>Status 2<td><span id="info2">info 2</span></td></tr>
  1193.       <tr><td>Status 3<td><span id="info3">info 3</span></td></tr>
  1194.       <tr><td>Status 4<td><span id="info4">info 4</span></td></tr>      
  1195.       <tr><td>Last Error:<td><span id="info5">info 5</span></td></tr>
  1196.       <tr><td>Orders dump<td><span id="odump">orders</span></td></tr>
  1197.       <tr><td>Data lag:<td> <span id="lag">0 ms</span> sec.</td></tr>
  1198.     </table>
  1199.      <p>Debug: <div id="debug_log"></div></p>
  1200.   </body>
  1201. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement