예제 #1
0
        /// <summary>Return the value of this order if it was to be closed at the given price tick</summary>
        public QuoteCurrency ValueAt(PriceTick price, bool consider_sl, bool consider_tp)
        {
            // Closing a Buy means selling to the highest *bid*er
            var p = TradeType == TradeType.Buy ? price.Bid : price.Ask;

            return(ValueAt(p, consider_sl, consider_tp));
        }
예제 #2
0
        ///// <summary>Incorporate a candle into this trade</summary>
        //public void AddCandle(Candle candle)
        //{
        //	// Adding a candle "open"s an unknown trade
        //	if (Result == EResult.Unknown)
        //		Result = EResult.Open;

        //	// If the trade is pending, look for an entry trigger
        //	if (Result == EResult.LimitOrder)
        //	{

        //		if ((TradeType == TradeType.Buy  && candle.Close >= EP) ||
        //			(TradeType == TradeType.Sell && candle.Close <= EP))
        //		{
        //			Result = EResult.Open;
        //			EntryIndex = candle.Index;
        //		}
        //	}
        //	if (Result == EResult.StopEntryOrder)
        //	{
        //	}

        //	// Trade has closed out
        //	if (Result == EResult.HitSL || Result == EResult.HitTP)
        //		return;

        //	// Otherwise, if this is an open trade.
        //	if (Result == EResult.Open)
        //	{
        //		// Assume the worst for order of prices within a candle
        //		var prices = TradeType.Sign() > 0
        //			? new[] {candle.Open, candle.Low, candle.High, candle.Close }
        //			: new[] {candle.Open, candle.High, candle.Low, candle.Close };

        //		// Check each price value against the trade
        //		var sign = TradeType.Sign();
        //		foreach (var p in prices)
        //		{
        //			// If the trade is a buy, then it closes at the bid price.
        //			var price = sign > 0 ? (QuoteCurrency)p : p + Instrument.Spread;

        //			// SL hit
        //			if (SL != null && sign * (price - SL.Value) < 0)
        //			{
        //				NetProfit = sign * Instrument.Symbol.QuoteToAcct(SL.Value - EP) * Volume;
        //				MaxAdverseExcursion  = sign * (EP - SL.Value);
        //				Result = EResult.HitSL;
        //				Expiration = candle.TimestampUTC.DateTime;
        //				break;
        //			}

        //			// TP hit
        //			if (TP != null && sign * (price - TP.Value) > 0)
        //			{
        //				NetProfit = sign * Instrument.Symbol.QuoteToAcct(TP.Value - EP) * Volume;
        //				MaxFavourableExcursion = sign * (TP.Value - EP);
        //				Result = EResult.HitTP;
        //				Expiration = candle.TimestampUTC.DateTime;
        //				break;
        //			}

        //			// Update the current profit
        //			NetProfit = sign * Instrument.Symbol.QuoteToAcct(price - EP) * Volume;

        //			// Record the peaks
        //			MaxFavourableExcursion = Math.Max(MaxFavourableExcursion, sign * (price - EP));
        //			MaxAdverseExcursion = Math.Max(MaxAdverseExcursion, sign * (EP - price));
        //		}

        //		ExitIndex = candle.Index;
        //	}
        //}

        /// <summary>Simulate the behaviour of this trade by adding a stream of price ticks</summary>
        public void Simulate(PriceTick price)
        {
            var sign = TradeType.Sign();

            // Adding a price tick 'open's an unknown trade
            if (Result == EResult.Unknown)
            {
                Result = EResult.Open;
            }

            // If the trade is pending, look for an entry trigger
            if ((Result == EResult.LimitOrder && Math.Sign(EP - price.Price(sign)) == sign) ||
                (Result == EResult.StopEntryOrder && Math.Sign(price.Price(sign) - EP) == sign))
            {
                Result     = EResult.Open;
                EntryIndex = price.Index;
            }

            // Trade has closed out
            if (Result == EResult.HitSL ||
                Result == EResult.HitTP)
            {
                return;
            }

            // Otherwise, if this is an open trade.
            if (Result == EResult.Open)
            {
                // SL hit
                if (SL != null && sign * (price.Price(-sign) - SL.Value) < 0)
                {
                    NetProfit           = sign * Instrument.Symbol.QuoteToAcct(SL.Value - EP) * Volume;
                    MaxAdverseExcursion = sign * (EP - SL.Value);
                    Result     = EResult.HitSL;
                    Expiration = price.TimestampUTC.DateTime;
                }

                // TP hit
                else if (TP != null && sign * (price.Price(-sign) - TP.Value) > 0)
                {
                    NetProfit = sign * Instrument.Symbol.QuoteToAcct(TP.Value - EP) * Volume;
                    MaxFavourableExcursion = sign * (TP.Value - EP);
                    Result     = EResult.HitTP;
                    Expiration = price.TimestampUTC.DateTime;
                }

                // Update the current profit
                else
                {
                    NetProfit = sign * Instrument.Symbol.QuoteToAcct(price.Price(-sign) - EP) * Volume;

                    // Record the peaks
                    MaxFavourableExcursion = Math.Max(MaxFavourableExcursion, sign * (price.Price(-sign) - EP));
                    MaxAdverseExcursion    = Math.Max(MaxAdverseExcursion, sign * (EP - price.Price(-sign)));
                }

                ExitIndex = price.Index;
            }
        }
예제 #3
0
        /// <summary>Return the normalised value ([-1,+1]) of this order at 'price'. Only valid if the order has SL and TP levels</summary>
        public double ValueFrac(PriceTick price)
        {
            if (SL == null || TP == null)
            {
                return(0.0);
            }

            var sign = TradeType.Sign();
            var win  = Maths.Frac(EP, price.Price(+sign), TP.Value);
            var los  = Maths.Frac(EP, price.Price(-sign), SL.Value);

            if (win < 0)
            {
                return(-los);
            }
            if (los < 0)
            {
                return(+win);
            }
            return(win > los ? win : -los);
        }
예제 #4
0
 /// <summary>Incorporate 'price' into this candle</summary>
 public void Update(PriceTick price)
 {
     High  = Math.Max(High, price.Bid);
     Low   = Math.Min(Low, price.Bid);
     Close = price.Bid;
 }
예제 #5
0
 /// <summary>Return the normalised value of a position/trade</summary>
 public static QuoteCurrency ValueFrac(this ITrade pos, PriceTick price)
 {
     return(new Order(pos, true).ValueFrac(price));
 }
예제 #6
0
 /// <summary>Return the normalised value of a position/trade</summary>
 public static QuoteCurrency ValueFrac(this PendingOrder pos, PriceTick price)
 {
     return(new Order(pos).ValueFrac(price));
 }
예제 #7
0
 /// <summary>Return the value of this position if it was to be closed at the given price tick</summary>
 public static QuoteCurrency ValueAt(this ITrade pos, PriceTick price, bool consider_sl = true, bool consider_tp = true)
 {
     return(new Order(pos, true).ValueAt(price, consider_sl, consider_tp));
 }