Ejemplo n.º 1
0
        /// <summary>Generate simulated market depth for 'pair', using 'latest' as the reference for the current spot price</summary>
        private MarketDepth GenerateMarketDepth(TradePair pair, Candle latest, ETimeFrame time_frame)
        {
            // Notes:
            //  - This is an expensive call when back testing is running so minimise allocation, resizing, and sorting.
            //  - Do all calculations using double's for speed.

            // Get the market data for 'pair'.
            // Market data is maintained independently to the pair's market data instance because the
            // rest of the application expects the market data to periodically overwrite the pair's order books.
            var md = m_depth[pair];

            // Get the Q2B (bid) spot price from the candle close. (This is the minimum of the Q2B offers)
            // The B2Q spot price is Q2B - spread, which will be the maximum of the B2Q offers
            var spread     = latest.Close * m_spread_frac;
            var best_q2b   = latest.Close;
            var best_b2q   = latest.Close - spread;
            var base_value = (double)(decimal)pair.Base.Value;

            md.Q2B.Offers.Resize(m_orders_per_book);
            md.B2Q.Offers.Resize(m_orders_per_book);

            // Generate offers with a normal distribution about 'best'
            var range = 0.2 * 0.5 * (best_q2b + best_b2q);

            for (var i = 0; i != m_orders_per_book; ++i)
            {
                var p = range * Math_.Sqr((double)i / m_orders_per_book);
                md.Q2B.Offers[i] = new Offer(((decimal)(best_q2b + p))._(pair.RateUnits), RandomAmountBase()._(pair.Base));
                md.B2Q.Offers[i] = new Offer(((decimal)(best_b2q - p))._(pair.RateUnits), RandomAmountBase()._(pair.Base));
            }
            return(md);

            decimal RandomAmountBase()
            {
                // Generate an amount to trade in the application common currency (probably USD).
                // Then convert that to base currency using the 'live' value.
                var common_value = Math.Abs(m_rng.Double(m_order_value_range.Beg, m_order_value_range.End));
                var amount_base  = (decimal)Math_.Div(common_value, base_value, common_value);

                return(amount_base);
            }
        }