private void CalculateShortestPath()
        {
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(m_a.Rows);

            for (int v = 0; v < m_a.Rows; v++)
            {
                for (int w = 0; w < m_a.Cols; w++)
                {
                    DirectedEdge e = new DirectedEdge(v, w, -Math.Log(m_a[v, w]));
                    G.addEdge(e);
                }
            }

            BellmanFordSP spt = new BellmanFordSP(G, 0);

            if (spt.negativeCycleCount > 2)
            {
                double stake     = 25000;
                double arbitrage = 1;

                ArbitrageCycle cycle = new ArbitrageCycle(m_currentTime);

                foreach (DirectedEdge e in spt.negativeCycle)
                {
                    double weight = Math.Exp(-e.Weight);
                    arbitrage *= weight;
                    cycle.Edges.Add(new DirectedEdge(e.From, e.To, weight));
                }

                if (!m_activeArbitrage.Contains(cycle, ARBITRAGE_CYCLE_COMPARER))
                {
                    m_activeArbitrage.Add(cycle);
                    Status(cycle.Summary);
                    Status("arbitrage(" + arbitrage + ") stake(" + stake + ") balance(" + (arbitrage * stake) + ") profit(" + Math.Round(((arbitrage * stake) / stake) - 1, 5) + "%)");
                }
            }
        }
        private void FillWatchArbitrage()
        {
            int currencyCount = m_a.Rows;
            int offset        = 0;

            m_watchArbitrage.Clear();

            for (int i = 0; i < currencyCount; i++)
            {
                for (int j = 0; j < currencyCount; j++)
                {
                    int first  = i;
                    int second = j;

                    if (first == second)
                    {
                        continue;
                    }

                    for (int k = 0; k < currencyCount; k++)
                    {
                        int third = k;

                        if (third == first)
                        {
                            continue;
                        }
                        if (third == second)
                        {
                            continue;
                        }

                        ArbitrageCycle c = new ArbitrageCycle(DateTime.Now);
                        c.Edges.Add(new DirectedEdge(first, second, offset++));
                        c.Edges.Add(new DirectedEdge(second, third, offset++));
                        c.Edges.Add(new DirectedEdge(third, first, offset++));
                        if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                        {
                            m_watchArbitrage.Add(c);
                        }

                        c = new ArbitrageCycle(DateTime.Now);
                        c.Edges.Add(new DirectedEdge(first, third, offset++));
                        c.Edges.Add(new DirectedEdge(third, second, offset++));
                        c.Edges.Add(new DirectedEdge(second, first, offset++));
                        if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                        {
                            m_watchArbitrage.Add(c);
                        }

                        /*
                         * for (int l = 0; l < currencyCount; l++)
                         * {
                         *  int forth = l;
                         *
                         *  if (forth == first) continue;
                         *  if (forth == second) continue;
                         *  if (forth == third) continue;
                         *
                         *  c = new ArbitrageCycle(DateTime.Now);
                         *  c.Edges.Add(new DirectedEdge(first, second, offset++));
                         *  c.Edges.Add(new DirectedEdge(second, third, offset++));
                         *  c.Edges.Add(new DirectedEdge(third, forth, offset++));
                         *  c.Edges.Add(new DirectedEdge(forth, first, offset++));
                         *  if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *  {
                         *      m_watchArbitrage.Add(c);
                         *
                         *
                         *      c = new ArbitrageCycle(DateTime.Now);
                         *      c.Edges.Add(new DirectedEdge(first, second, offset++));
                         *      c.Edges.Add(new DirectedEdge(second, forth, offset++));
                         *      c.Edges.Add(new DirectedEdge(forth, third, offset++));
                         *      c.Edges.Add(new DirectedEdge(third, first, offset++));
                         *      if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *      {
                         *          m_watchArbitrage.Add(c);
                         *      }
                         *
                         *      c = new ArbitrageCycle(DateTime.Now);
                         *      c.Edges.Add(new DirectedEdge(first, third, offset++));
                         *      c.Edges.Add(new DirectedEdge(third, forth, offset++));
                         *      c.Edges.Add(new DirectedEdge(forth, second, offset++));
                         *      c.Edges.Add(new DirectedEdge(second, first, offset++));
                         *      if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *      {
                         *          m_watchArbitrage.Add(c);
                         *      }
                         *
                         *      c = new ArbitrageCycle(DateTime.Now);
                         *      c.Edges.Add(new DirectedEdge(first, third, offset++));
                         *      c.Edges.Add(new DirectedEdge(third, second, offset++));
                         *      c.Edges.Add(new DirectedEdge(second, forth, offset++));
                         *      c.Edges.Add(new DirectedEdge(forth, first, offset++));
                         *      if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *      {
                         *          m_watchArbitrage.Add(c);
                         *      }
                         *
                         *      c = new ArbitrageCycle(DateTime.Now);
                         *      c.Edges.Add(new DirectedEdge(first, forth, offset++));
                         *      c.Edges.Add(new DirectedEdge(forth, third, offset++));
                         *      c.Edges.Add(new DirectedEdge(third, second, offset++));
                         *      c.Edges.Add(new DirectedEdge(second, first, offset++));
                         *      if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *      {
                         *          m_watchArbitrage.Add(c);
                         *      }
                         *
                         *
                         *      c = new ArbitrageCycle(DateTime.Now);
                         *      c.Edges.Add(new DirectedEdge(first, forth, offset++));
                         *      c.Edges.Add(new DirectedEdge(forth, second, offset++));
                         *      c.Edges.Add(new DirectedEdge(second, third, offset++));
                         *      c.Edges.Add(new DirectedEdge(third, first, offset++));
                         *      if (!m_watchArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                         *      {
                         *          m_watchArbitrage.Add(c);
                         *      }
                         *  }
                         * }*/
                    }
                }
            }
        }
        private void CalculateHistorical()
        {
            IOrderedEnumerable <ArbitrageCycle> set = m_activeArbitrage.OrderByDescending(a => a);

            for (int i = 0; i < set.Count(); i++)
            {
                ArbitrageCycle cycle = set.ElementAt(i);
                cycle.Current = m_currentTime;
                for (int j = 0; j < cycle.Edges.Count; j++)
                {
                    DirectedEdge edge = cycle.Edges[j];
                    cycle.Edges[j] = new DirectedEdge(edge.From, edge.To, m_a[edge.From, edge.To]);
                }

                if (cycle.Profit < 0.001d)
                {
                    m_historicalArbitrage.Add(cycle);
                    m_activeArbitrage.Remove(cycle);
                }

                Dispatcher.Invoke(() =>
                {
                    if (m_activeListBox.Items.Count > i)
                    {
                        m_activeListBox.Items[i] = cycle.Summary;
                    }
                    else
                    {
                        m_activeListBox.Items.Add(cycle.Summary);
                    }
                });
            }

            /*for (int i = 0; i < m_activeArbitrage.Count; i++ )
             * {
             *  ArbitrageCycle cycle = m_activeArbitrage.ToList()[i];
             *  cycle.Current = m_currentTime;
             *  for (int j = 0; j < cycle.Edges.Count; j++)
             *  {
             *      DirectedEdge edge = cycle.Edges[j];
             *      cycle.Edges[j] = new DirectedEdge(edge.From, edge.To, m_a[edge.From, edge.To]);
             *  }
             *
             *  if (cycle.Profit < 0.001d)
             *  {
             *      m_historicalArbitrage.Add(cycle);
             *      m_activeArbitrage.Remove(cycle);
             *  }
             *
             *
             *  Dispatcher.Invoke(() =>
             *  {
             *      if (m_activeListBox.Items.Count > i)
             *          m_activeListBox.Items[i] = cycle.Summary;
             *      else
             *          m_activeListBox.Items.Add(cycle.Summary);
             *  });
             * }*/

            Dispatcher.Invoke(() =>
            {
                for (int j = m_activeListBox.Items.Count - 1; j >= m_activeArbitrage.Count; j--)
                {
                    m_activeListBox.Items.RemoveAt(j);
                }
            });

            set = m_historicalArbitrage.OrderByDescending(a => a);
            for (int i = 0; i < set.Count(); i++)
            {
                ArbitrageCycle cycle = set.ElementAt(i);

                Dispatcher.Invoke(() =>
                {
                    if (m_historicListBox.Items.Count > i)
                    {
                        m_historicListBox.Items[i] = cycle.Summary;
                    }
                    else
                    {
                        m_historicListBox.Items.Add(cycle.Summary);
                    }
                });
            }

            Dispatcher.Invoke(() =>
            {
                for (int j = m_historicListBox.Items.Count - 1; j >= m_historicalArbitrage.Count; j--)
                {
                    m_historicListBox.Items.RemoveAt(j);
                }
            });

            set = m_watchArbitrage.OrderByDescending(a => a);
            for (int i = 0; i < set.Count(); i++)
            {
                ArbitrageCycle cycle = set.ElementAt(i);
                cycle.Current = m_currentTime;
                for (int j = 0; j < cycle.Edges.Count; j++)
                {
                    DirectedEdge edge = cycle.Edges[j];
                    cycle.Edges[j] = new DirectedEdge(edge.From, edge.To, m_a[edge.From, edge.To]);
                }

                Dispatcher.Invoke(() =>
                {
                    if (m_watchListBox.Items.Count > i)
                    {
                        m_watchListBox.Items[i] = cycle.Summary;
                    }
                    else
                    {
                        m_watchListBox.Items.Add(cycle.Summary);
                    }
                });
            }

            Dispatcher.Invoke(() =>
            {
                for (int j = m_watchListBox.Items.Count - 1; j >= m_watchArbitrage.Count; j--)
                {
                    m_watchListBox.Items.RemoveAt(j);
                }
            });

            foreach (ArbitrageCycle c in m_activeArbitrage)
            {
                if (c.Profit > 0.05d && c.Profit < 1000 && !m_stasisArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                {
                    m_stasisArbitrage.Add((ArbitrageCycle)c.Clone());
                }
            }

            foreach (ArbitrageCycle c in m_watchArbitrage)
            {
                if (c.Profit > 0.05d && c.Profit < 1000 && !m_stasisArbitrage.Contains(c, ARBITRAGE_CYCLE_COMPARER))
                {
                    m_stasisArbitrage.Add((ArbitrageCycle)c.Clone());
                }
            }

            IEnumerable <ArbitrageCycle> set2 = m_stasisArbitrage.AsEnumerable();

            for (int i = 0; i < set2.Count(); i++)
            {
                ArbitrageCycle cycle = set2.ElementAt(i);

                Dispatcher.Invoke(() =>
                {
                    if (m_stasisListBox.Items.Count > i)
                    {
                        m_stasisListBox.Items[i] = cycle.Summary;
                    }
                    else
                    {
                        m_stasisListBox.Items.Add(cycle.Summary);
                    }
                });
            }

            Dispatcher.Invoke(() =>
            {
                for (int j = m_stasisListBox.Items.Count - 1; j >= m_stasisArbitrage.Count; j--)
                {
                    m_stasisListBox.Items.RemoveAt(j);
                }
            });
        }