public Alert EntryAlertCreate(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop) { this.checkThrowEntryBarIsValid(entryBar); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (entryMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(entryMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); // ALREADY_ALIGNED_AFTER GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming double entryPriceScript = entryBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, entryMarketLimitStop); double shares = this.executor.PositionSizeCalculate(entryBar, entryPriceScript); Alert alert = new Alert(entryBar, shares, entryPriceScript, entrySignalName, direction, entryMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); return(alert); }
public Alert ExitAlertCreate(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop) { this.checkThrowEntryBarIsValid(exitBar); this.checkThrowPositionToCloseIsValid(position); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (exitMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(exitMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); double exitPriceScript = exitBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, exitMarketLimitStop); Alert alert = new Alert(exitBar, position.Shares, exitPriceScript, signalName, direction, exitMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); alert.PositionAffected = position; // moved to CallbackAlertFilled - we can exit by TP or SL - and position has no clue which Alert was filled!!! //position.ExitCopyFromAlert(alert); alert.PositionAffected.ExitAlertAttach(alert); return alert; }
public Alert EntryAlertCreate(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop) { this.checkThrowEntryBarIsValid(entryBar); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (entryMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(entryMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); // ALREADY_ALIGNED_AFTER GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming double entryPriceScript = entryBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, entryMarketLimitStop); double shares = this.executor.PositionSizeCalculate(entryBar, entryPriceScript); Alert alert = new Alert(entryBar, shares, entryPriceScript, entrySignalName, direction, entryMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); return alert; }
private double getStreamingPriceForMarketOrder(MarketLimitStop entryMarketLimitStop, Direction direction, out OrderSpreadSide priceSpreadSide) { double priceForMarketAlert = -1; priceSpreadSide = OrderSpreadSide.Unknown; switch (entryMarketLimitStop) { case MarketLimitStop.Market: priceForMarketAlert = this.executor.DataSource.StreamingProvider.StreamingDataSnapshot .GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming( this.executor.Bars.Symbol, direction, out priceSpreadSide, false); break; case MarketLimitStop.AtClose: string msg = "[" + direction + "]At[" + entryMarketLimitStop + "]" + " when LastBar[" + (this.executor.Bars.Count - 1) + "]; No way I can bring you a future price," + " even by executing your order right now" + "; can't do inequivalent repacement to LastBar.Close"; throw new Exception(msg); //break; case MarketLimitStop.Stop: case MarketLimitStop.Limit: case MarketLimitStop.StopLimit: string msg2 = "STREAMING_BID_ASK_IS_IRRELEVANT_FOR_STOP_OR_LIMIT_ALERT [" + direction + "]At[" + entryMarketLimitStop + "]" + " when LastBar[" + (this.executor.Bars.Count - 1) + "]"; throw new Exception(msg2); default: throw new Exception("no handler for MarketLimitStop.[" + entryMarketLimitStop + "]"); } return(priceForMarketAlert); }
public Alert(Bar bar, double qty, double priceScript, string signalName, Direction direction, MarketLimitStop marketLimitStop, OrderSpreadSide orderSpreadSide, Strategy strategy) : this() { if (direction == Direction.Unknown) { string msg = "ALERT_CTOR_DIRECTION_MUST_NOT_BE_UNKNOWN: when creating an Alert, direction parameter can't be null"; throw new Exception(msg); } if (bar == null) { string msg = "ALERT_CTOR_BAR_MUST_NOT_BE_NULL: when creating an Alert, bar parameter can't be null"; throw new Exception(msg); } if (bar.ParentBars == null) { string msg = "ALERT_CTOR_PARENT_BARS_MUST_NOT_BE_NULL: when creating an Alert, bar.ParentBars can't be null"; throw new Exception(msg); } this.Bars = bar.ParentBars; this.PlacedBar = bar; this.PlacedBarIndex = bar.ParentBarsIndex; this.Symbol = bar.Symbol; this.BarsScaleInterval = this.Bars.ScaleInterval; if (this.Bars.SymbolInfo != null) { SymbolInfo symbolInfo = this.Bars.SymbolInfo; this.SymbolClass = (string.IsNullOrEmpty(symbolInfo.SymbolClass) == false) ? symbolInfo.SymbolClass : "UNKNOWN_CLASS"; this.MarketOrderAs = symbolInfo.MarketOrderAs; } this.AccountNumber = "UNKNOWN_ACCOUNT"; if (this.DataSource.BrokerProvider != null && this.DataSource.BrokerProvider.AccountAutoPropagate != null && string.IsNullOrEmpty(this.Bars.DataSource.BrokerProvider.AccountAutoPropagate.AccountNumber) != false) { this.AccountNumber = this.Bars.DataSource.BrokerProvider.AccountAutoPropagate.AccountNumber; } this.Qty = qty; this.PriceScript = priceScript; this.SignalName = signalName; this.Direction = direction; this.MarketLimitStop = marketLimitStop; this.OrderSpreadSide = orderSpreadSide; this.Strategy = strategy; if (this.Strategy != null) { this.StrategyID = this.Strategy.Guid; this.StrategyName = this.Strategy.Name; } if (this.Strategy.Script != null) { string msg = "Looks like a manual Order submitted from the Chart"; return; } }
public Alert ExitAlertCreate(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop) { this.checkThrowEntryBarIsValid(exitBar); this.checkThrowPositionToCloseIsValid(position); double priceScriptOrStreaming = stopOrLimitPrice; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; if (exitMarketLimitStop == MarketLimitStop.Market) { priceScriptOrStreaming = this.getStreamingPriceForMarketOrder(exitMarketLimitStop, direction, out orderSpreadSide); } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); double exitPriceScript = exitBar.ParentBars.SymbolInfo.RoundAlertPriceToPriceLevel( priceScriptOrStreaming, true, longShortFromDirection, exitMarketLimitStop); Alert alert = new Alert(exitBar, position.Shares, exitPriceScript, signalName, direction, exitMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); alert.PositionAffected = position; // moved to CallbackAlertFilled - we can exit by TP or SL - and position has no clue which Alert was filled!!! //position.ExitCopyFromAlert(alert); alert.PositionAffected.ExitAlertAttach(alert); return(alert); }
public Alert CreateStopLossFromPositionPrototype(Position position) { //if (this.executor.checkPrototypeAlreadyPlaced(position)) return; PositionPrototype proto = position.Prototype; if (proto.StopLossNegativeOffset == 0) { string msg = "What should Activator do with proto.StopLossNegativeOffset=0?"; throw new Exception(msg); } if (proto.StopLossNegativeOffset == 0) { string msg = this.ReasonWhyNewStopLossOffsetDoesntMakeSense(position, proto.StopLossNegativeOffset); if (String.IsNullOrEmpty(msg) == false) { string msg2 = "What should Activator do with sense-less proto.StopLossNegativeOffset[" + proto.StopLossNegativeOffset + "], "; throw new Exception(msg2, new Exception(msg)); } } MarketLimitStop simpleStopIfActivationZero = (proto.StopLossActivationNegativeOffset == 0) ? MarketLimitStop.Stop : MarketLimitStop.StopLimit; Alert alertStopLoss = executor.SellOrCoverAlertCreateDontRegister( executor.Bars.BarStreaming, position, proto.PriceStopLoss, "protoStopLossExit:" + proto.StopLossActivationNegativeOffset + "@" + proto.StopLossNegativeOffset + " for " + position.EntrySignal, MarketConverter.ExitDirectionFromLongShort(proto.LongShort), simpleStopIfActivationZero); if (alertStopLoss == null) { string msg = "alertStopLoss should NOT be null"; throw new Exception(msg); } alertStopLoss.PriceStopLimitActivation = 0; if (proto.StopLossActivationNegativeOffset < 0) { alertStopLoss.PriceStopLimitActivation = proto.PriceStopLossActivation; } if (proto.StopLossAlertForAnnihilation != null && this.executor.Backtester.IsBacktestingNow == false) { string msg = "CLEANUP: I was trying to catch MoveStopLoss::if(proto.StopLossAlertForAnnihilation==null)" + " so I thought there is a new prototype assigned to a position," + " since we never put null directly proto.StopLossAlertForAnnihilation"; throw new Exception(msg); } proto.StopLossAlertForAnnihilation = alertStopLoss; return(alertStopLoss); }
public string ReasonWhyPlacingProtoDoesntMakeSense(PositionPrototype proto, bool internalCallee = false) { double lastPrice = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetPriceForMarketOrder(proto.Symbol); Quote quote = executor.DataSource.StreamingProvider.StreamingDataSnapshot.LastQuoteGetForSymbol(proto.Symbol); double priceBestBidAsk = executor.DataSource.StreamingProvider.StreamingDataSnapshot.BidOrAskFor(proto.Symbol, proto.LongShort); bool willBeExecutedImmediately = false; MarketLimitStop planningEntryUsing = MarketConverter.EntryMarketLimitStopFromDirection( executor.Bars.BarStreamingCloneReadonly.Close, proto.PriceEntry, proto.LongShort); string msg = ""; Direction dir = MarketConverter.EntryDirectionFromLongShort(proto.LongShort); switch (dir) { case Direction.Buy: if (proto.PriceEntry > priceBestBidAsk) { willBeExecutedImmediately = true; msg = "proto.PriceEntry[" + proto.PriceEntry + "] > Bid[" + priceBestBidAsk + "]" + " your Alert.EntryPrice goes above current price" + " so the planningEntryUsing[" + planningEntryUsing + "] will be activated/filled immediately..." + " //proto[" + proto + "]"; } break; case Direction.Short: if (proto.PriceEntry < priceBestBidAsk) { willBeExecutedImmediately = true; msg = "proto.PriceEntry[" + proto.PriceEntry + "] < Ask[" + priceBestBidAsk + "]" + " your Alert.EntryPrice goes below current price" + " so the planningEntryUsing[" + planningEntryUsing + "] will be activated/filled immediately..." + " //proto[" + proto + "]"; } break; default: msg = "I refuse to PlaceOnce(proto) for.Direction=[" + dir + "] - must be Buy or Sell only!!!"; break; } if (internalCallee == true) { msg += " (Script is strongly recommented to check proto.EntryPrice first so we don't pass unexpected position entries to the Market)"; } return(msg); }
public Alert() // called by Json.Deserialize() { PlacedBarIndex = -1; FilledBarIndex = -1; //TimeCreatedServerBar = DateTime.MinValue; this.QuoteCreatedThisAlertServerTime = DateTime.MinValue; Symbol = "UNKNOWN_JUST_DESERIALIZED"; //SymbolClass = ""; //QUIK //AccountNumber = ""; PriceScript = 0; PriceDeposited = -1; // for a Future, we pay less that it's quoted (GUARANTEE DEPOSIT) Qty = 0; MarketLimitStop = MarketLimitStop.Unknown; MarketOrderAs = MarketOrderAs.Unknown; Direction = Direction.Unknown; SignalName = ""; StrategyID = Guid.Empty; StrategyName = "NO_STRATEGY"; BarsScaleInterval = new BarScaleInterval(BarScale.Unknown, 0); OrderFollowed = null; MreOrderFollowedIsNotNull = new ManualResetEvent(false); }
public override double CalculateCommission(Direction direction, MarketLimitStop marketLimitStop, double orderPrice, double shares, Bars bars) { return(0); }
public abstract double CalculateCommission(Direction direction, MarketLimitStop marketLimitStop, double orderPrice, double shares, Bars bars);
public double OrderCommissionCalculate(Direction direction, MarketLimitStop marketLimitStop, double price, double shares, Bars bars) { double ret = 0; if (this.Strategy.ScriptContextCurrent.ApplyCommission && this.CommissionCalculator != null) { ret = this.CommissionCalculator.CalculateCommission(direction, marketLimitStop, price, shares, bars); } return ret; }
public Alert ExitAlertCreate(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop) { if (position == null) { string msg = "do not SellOrCover(position = null) please"; throw new Exception(msg); return null; } if (position.NoExitBarOrStreaming == false) return null; //Bars bars = position.Bars; // backtest substitutes StrategyExecutor.Bars, so exit(bar+1) should point on StreamingBar, not backtested! //Bars backtestingOrStreamingBars = this.executor.Bars; Direction posDirection = MarketConverter.ExitDirectionFromLongShort(position.PositionLongShort); if (posDirection != direction) { string msg = "here is the case when you Sell a Short once again or Cover a Long, what's the matter with you?"; throw new Exception(msg); } PositionLongShort positionDirection = PositionLongShort.Long; switch (direction) { case Direction.Sell: positionDirection = PositionLongShort.Long; break; case Direction.Cover: positionDirection = PositionLongShort.Short; break; default: throw new Exception("NYI direction[" + direction + "]"); } if (positionDirection != position.PositionLongShort) { string msg = "pass positionDirection to AlignAlertPriceToPriceLevel!!! you should close with an opposite alignment"; throw new Exception(msg); } double exitPriceScript = stopOrLimitPrice; int barSmallestAllowed = 0; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; switch (exitMarketLimitStop) { case MarketLimitStop.Market: //if (exitBar >= this.executor.Bars.Count) { //bar+1 if (exitBar.IsBarStreaming) { //bar+1 if (this.executor.IsStreaming) { //basisPrice = 0; this.executor.DataSource.StreamingProvider.StreamingDataSnapshot.GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming( this.executor.Bars.Symbol, posDirection, out exitPriceScript, out orderSpreadSide, false); } else { //basisPrice = this.executor.Bars[bar].Open; //basisPrice = this.executor.Bars.LastBar.Close; //if (bar > this.executor.Bars.Count) { //bar+2 // exitPriceScript = this.executor.Bars[exitBar - 1].Close; // string msg = "[" + direction + "]At[" + exitMarketLimitStop + "](bar=[" + exitBar + "])" // + " when LastBar[" + (this.executor.Bars.Count - 1) + "]; No way I can bring you" // + " price from the future, even by executing your order right now" // + "; can't do inequivalent repacement to LastBar.Open"; // log.Fatal(msg, new Exception(msg)); string msg = "[" + direction + "]At[" + exitMarketLimitStop + "](bar=[" + exitBar + "])"; throw new Exception("UNABLE_TO_REFACTOR#2 " + msg); //} } } else { //exitPriceScript = this.executor.Bars[exitBar].Open; exitPriceScript = exitBar.Open; } barSmallestAllowed = 1; break; case MarketLimitStop.AtClose: //if (exitBar >= this.executor.Bars.Count) { //bar+1 if (exitBar.IsBarStreaming) { //bar+1 exitPriceScript = 0; string msg = "[" + direction + "]At[" + exitMarketLimitStop + "](bar=[" + exitBar + "])" + " when LastBar[" + this.executor.Bars.BarStaticLast + "]; No way I can bring you price from the future," + " even by executing your order right now" + "; can't do inequivalent repacement to LastBar.Close"; log.Fatal(msg, new Exception(msg)); } else { //exitPriceScript = this.executor.Bars[exitBar].Close; exitPriceScript = exitBar.Close; } barSmallestAllowed = 0; break; case MarketLimitStop.Stop: break; case MarketLimitStop.Limit: break; case MarketLimitStop.StopLimit: break; default: throw new Exception("no handler for exitMarketLimitStop.[" + exitMarketLimitStop + "]"); } //BAR_NOT_NULL_CHECKED_UPSTACK_IN_ScriptExecutor.SellOrCoverAlertCreateRegister() this.executor._throwWhenBarOutsideInterval(exitBar, barSmallestAllowed, this.executor.Bars.Count, this.executor.Bars); //if (exitBar < this.executor.Bars.Count) { if (exitBar.IsBarStreaming == false) { this.basisPriceZeroCheckThrow(exitPriceScript); } //if (position == Position.AllPositions) { // bool result = false; // int num = this.executor.ExecutionDataSnapshot.PositionsOpenNow.Count; // for (int i = this.executor.ExecutionDataSnapshot.PositionsMaster.Count - 1; i >= 0; i--) { // if (num == 0) return result; // bool soldOrCovered = SellOrCover(exitBar, this.executor.ExecutionDataSnapshot.PositionsMaster[i], // stopOrLimitPrice, signalName, direction, exitMarketLimitStop); // if (this.executor.ExecutionDataSnapshot.PositionsMaster[i].NoExitBarOrStreaming && soldOrCovered) { result = true; num--; } // } // return result; //} //if (exitBar < this.executor.Bars.Count) { if (exitBar.IsBarStreaming == false) { //BAR_NOT_NULL_CHECKED_UPSTACK_IN_ScriptExecutor.SellOrCoverAlertCreateRegister() this.executor._throwWhenBarOutsideInterval(exitBar, position.EntryBarIndex, position.Bars.Count, position.Bars); //switch (direction) { // case Direction.Sell: // if (this.executor._IsDayLimitedDownWithBarsBy(position.Bars, exitBar) == false) return null; // if (position.PositionLongShort != PositionLongShort.Long) return null; // break; // case Direction.Cover: // if (this.executor._IsDayLimitedUpWithBarsBy(position.Bars, exitBar) == false) return null; // if (position.PositionLongShort != PositionLongShort.Short) return null; // break; // default: // throw new Exception("NYI direction[" + direction + "]"); //} } PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); exitPriceScript = this.executor.AlignAlertPriceToPriceLevel(this.executor.Bars, exitPriceScript, true, longShortFromDirection, exitMarketLimitStop); Alert alert = new Alert(exitBar, position.Shares, exitPriceScript, signalName, direction, exitMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); alert.PositionAffected = position; // moved to CallbackAlertFilled - we can exit by TP or SL - and position has no clue which Alert was filled!!! //position.ExitCopyFromAlert(alert); return alert; }
public override double CalculateCommission(Direction direction, MarketLimitStop marketLimitStop, double orderPrice, double shares, Bars bars) { return 0; }
public Position BuyOrShortAlertCreateDontRegister(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop) { return BuyOrShortAlertCreateRegister(entryBar, stopOrLimitPrice, entrySignalName, direction, entryMarketLimitStop, false); }
public Alert() { // called by Json.Deserialize() PlacedBarIndex = -1; FilledBarIndex = -1; //TimeCreatedServerBar = DateTime.MinValue; this.QuoteCreatedThisAlertServerTime = DateTime.MinValue; Symbol = "UNKNOWN_JUST_DESERIALIZED"; //SymbolClass = ""; //QUIK //AccountNumber = ""; PriceScript = 0; PriceDeposited = -1; // for a Future, we pay less that it's quoted (GUARANTEE DEPOSIT) Qty = 0; MarketLimitStop = MarketLimitStop.Unknown; MarketOrderAs = MarketOrderAs.Unknown; Direction = Direction.Unknown; SignalName = ""; StrategyID = Guid.Empty; StrategyName = "NO_STRATEGY"; BarsScaleInterval = new BarScaleInterval(BarScale.Unknown, 0); OrderFollowed = null; MreOrderFollowedIsNotNull = new ManualResetEvent(false); }
public double AlignOrderPriceToPriceLevel(double orderPrice, Direction direction, MarketLimitStop marketLimitStop) { bool buyOrShort = true; PositionLongShort positionLongShort = PositionLongShort.Long; switch (direction) { case Direction.Buy: buyOrShort = true; positionLongShort = PositionLongShort.Long; break; case Direction.Sell: buyOrShort = false; positionLongShort = PositionLongShort.Long; break; case Direction.Short: buyOrShort = true; positionLongShort = PositionLongShort.Short; break; case Direction.Cover: buyOrShort = false; positionLongShort = PositionLongShort.Short; break; default: throw new Exception("add new handler for new Direction[" + direction + "] besides {Buy,Sell,Cover,Short}"); } return(this.RoundAlertPriceToPriceLevel(orderPrice, buyOrShort, positionLongShort, marketLimitStop)); }
public double RoundAlertPriceToPriceLevel(double orderPrice, bool buyOrShort, PositionLongShort positionLongShort0, MarketLimitStop marketLimitStop0) { double d = orderPrice / this.PriceLevelSizeForBonds; string a = d.ToString("N6"); string b = Math.Truncate(d).ToString("N6"); if (a == b) { return(orderPrice); } PriceLevelRoundingMode rounding; switch (marketLimitStop0) { case MarketLimitStop.Limit: if (positionLongShort0 == PositionLongShort.Long) { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundDown : PriceLevelRoundingMode.RoundUp); } else { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundUp : PriceLevelRoundingMode.RoundDown); } break; case MarketLimitStop.Stop: case MarketLimitStop.StopLimit: if (positionLongShort0 == PositionLongShort.Long) { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundUp : PriceLevelRoundingMode.RoundDown); } else { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundDown : PriceLevelRoundingMode.RoundUp); } break; default: rounding = PriceLevelRoundingMode.DontRound; break; } double lowerLevel = Math.Truncate(orderPrice / this.PriceLevelSizeForBonds); lowerLevel *= this.PriceLevelSizeForBonds; double upperLevel = lowerLevel + this.PriceLevelSizeForBonds; switch (rounding) { case PriceLevelRoundingMode.RoundDown: if (lowerLevel >= upperLevel) { return(upperLevel); } return(lowerLevel); case PriceLevelRoundingMode.RoundUp: if (lowerLevel <= upperLevel) { return(upperLevel); } return(lowerLevel); default: double distanceUp = Math.Abs(orderPrice - upperLevel); double distanceDown = Math.Abs(orderPrice - lowerLevel); if (distanceUp >= distanceDown) { return(upperLevel); } return(lowerLevel); } }
public double RoundAlertPriceToPriceLevel(double orderPrice, bool buyOrShort, PositionLongShort positionLongShort0, MarketLimitStop marketLimitStop0) { double d = orderPrice / this.PriceLevelSizeForBonds; string a = d.ToString("N6"); string b = Math.Truncate(d).ToString("N6"); if (a == b) return orderPrice; PriceLevelRoundingMode rounding; switch (marketLimitStop0) { case MarketLimitStop.Limit: if (positionLongShort0 == PositionLongShort.Long) { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundDown : PriceLevelRoundingMode.RoundUp); } else { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundUp : PriceLevelRoundingMode.RoundDown); } break; case MarketLimitStop.Stop: case MarketLimitStop.StopLimit: if (positionLongShort0 == PositionLongShort.Long) { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundUp : PriceLevelRoundingMode.RoundDown); } else { rounding = (buyOrShort ? PriceLevelRoundingMode.RoundDown : PriceLevelRoundingMode.RoundUp); } break; default: rounding = PriceLevelRoundingMode.DontRound; break; } double lowerLevel = Math.Truncate(orderPrice / this.PriceLevelSizeForBonds); lowerLevel *= this.PriceLevelSizeForBonds; double upperLevel = lowerLevel + this.PriceLevelSizeForBonds; switch (rounding) { case PriceLevelRoundingMode.RoundDown: if (lowerLevel >= upperLevel) { return upperLevel; } return lowerLevel; case PriceLevelRoundingMode.RoundUp: if (lowerLevel <= upperLevel) { return upperLevel; } return lowerLevel; default: double distanceUp = Math.Abs(orderPrice - upperLevel); double distanceDown = Math.Abs(orderPrice - lowerLevel); if (distanceUp >= distanceDown) { return upperLevel; } return lowerLevel; } }
public Position BuyOrShortAlertCreateRegister(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop, bool registerInNew = true) { this.CheckThrowAlertCanBeCreated(entryBar, "BARS.BARSTREAMING_OR_BARS.BARLASTSTATIC_IS_NULL_BuyOrShortAlertCreateRegister() "); Alert alert = null; // real-time streaming should create its own Position after an Order gets filled if (this.IsStreaming) { alert = this.MarketRealStreaming.EntryAlertCreate(entryBar, stopOrLimitPrice, entrySignalName, direction, entryMarketLimitStop); } else { //alert = this.MarketSimStatic.EntryAlertCreate(entryBar, stopOrLimitPrice, entrySignalName, // direction, entryMarketLimitStop); Debugger.Break(); } Alert similar = this.ExecutionDataSnapshot.FindSimilarNotSamePendingAlert(alert); if (similar != null) { return similar.PositionAffected; } this.ExecutionDataSnapshot.AlertEnrichedRegister(alert, registerInNew); // ok for single-entry strategies; nogut if we had many Streaming alerts and none of orders was filled yet... // MOVED_TO_ON_ALERT_FILLED_CALBACK Position pos = new Position(alert, alert.PriceScript); alert.PositionAffected = pos; return pos; }
public double AlignOrderPriceToPriceLevel(double orderPrice, Direction direction, MarketLimitStop marketLimitStop) { bool buyOrShort = true; PositionLongShort positionLongShort = PositionLongShort.Long; switch (direction) { case Direction.Buy: buyOrShort = true; positionLongShort = PositionLongShort.Long; break; case Direction.Sell: buyOrShort = false; positionLongShort = PositionLongShort.Long; break; case Direction.Short: buyOrShort = true; positionLongShort = PositionLongShort.Short; break; case Direction.Cover: buyOrShort = false; positionLongShort = PositionLongShort.Short; break; default: throw new Exception("add new handler for new Direction[" + direction + "] besides {Buy,Sell,Cover,Short}"); } return this.RoundAlertPriceToPriceLevel(orderPrice, buyOrShort, positionLongShort, marketLimitStop); }
public Alert SellOrCoverAlertCreateDontRegister(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop) { return this.SellOrCoverAlertCreateRegister(exitBar, position, stopOrLimitPrice, signalName, direction, exitMarketLimitStop, false); }
private double getStreamingPriceForMarketOrder(MarketLimitStop entryMarketLimitStop, Direction direction, out OrderSpreadSide priceSpreadSide) { double priceForMarketAlert = -1; priceSpreadSide = OrderSpreadSide.Unknown; switch (entryMarketLimitStop) { case MarketLimitStop.Market: priceForMarketAlert = this.executor.DataSource.StreamingProvider.StreamingDataSnapshot .GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming( this.executor.Bars.Symbol, direction, out priceSpreadSide, false); break; case MarketLimitStop.AtClose: string msg = "[" + direction + "]At[" + entryMarketLimitStop + "]" + " when LastBar[" + (this.executor.Bars.Count - 1) + "]; No way I can bring you a future price," + " even by executing your order right now" + "; can't do inequivalent repacement to LastBar.Close"; throw new Exception(msg); //break; case MarketLimitStop.Stop: case MarketLimitStop.Limit: case MarketLimitStop.StopLimit: string msg2 = "STREAMING_BID_ASK_IS_IRRELEVANT_FOR_STOP_OR_LIMIT_ALERT [" + direction + "]At[" + entryMarketLimitStop + "]" + " when LastBar[" + (this.executor.Bars.Count - 1) + "]"; throw new Exception(msg2); default: throw new Exception("no handler for MarketLimitStop.[" + entryMarketLimitStop + "]"); } return priceForMarketAlert; }
public Alert SellOrCoverAlertCreateRegister(Bar exitBar, Position position, double stopOrLimitPrice, string signalName, Direction direction, MarketLimitStop exitMarketLimitStop, bool registerInNewAfterExec = true) { this.CheckThrowAlertCanBeCreated(exitBar, "BARS.BARSTREAMING_OR_BARS.BARLASTSTATIC_IS_NULL_SellOrCoverAlertCreateRegister() "); if (position == null) throw new Exception("POSITION_CAN_NOT_BE_NULL_SellOrCoverAlertCreateRegister()"); Alert alert = null; if (position.Prototype != null) { if (signalName.Contains("protoTakeProfitExit") && position.Prototype.TakeProfitAlertForAnnihilation != null && this.Backtester.IsBacktestingNow == false) { string msg = "I won't create another protoTakeProfitExit because" + " position.Prototype.TakeProfitAlertForAnnihilation != null" + " position[" + position + "]"; this.PopupException(msg); return position.ExitAlert; } if (signalName.Contains("protoStopLossExit") && position.Prototype.StopLossAlertForAnnihilation != null && this.Backtester.IsBacktestingNow == false) { string msg = "I won't create another protoStopLossExit because" + " position.Prototype.StopLossAlertForAnnihilation != null" + " position[" + position + "]"; this.PopupException(msg); return position.ExitAlert; } } else { if (position.ExitAlert != null) { string msg = "POSITION_ALREADY_HAS_AN_EXIT_ALERT_REPLACE_INSTEAD_OF_ADDING_SECOND_SellOrCoverAlertCreateRegister();" + " Strategy[" + this.Strategy.ToString() + "] position.Prototype=null position[" + position + "]"; this.PopupException(msg); return position.ExitAlert; } foreach (Alert closingAlertForPosition in this.ExecutionDataSnapshot.AlertsPending) { if (closingAlertForPosition.PositionAffected == position && closingAlertForPosition.IsExitAlert) { string msg = "PENDING_EXIT_ALERT_FOUND_WHILE_POSITION.EXITALERT=NULL" + "; position.ExitAlert[" + position.ExitAlert + "] != closingAlertForPosition[" + closingAlertForPosition + "]"; this.PopupException(msg); return closingAlertForPosition; } } } if (this.IsStreaming) { alert = this.MarketRealStreaming.ExitAlertCreate(exitBar, position, stopOrLimitPrice, signalName, direction, exitMarketLimitStop); } else { //alert = this.MarketSimStatic.ExitAlertCreate(exitBar, position, stopOrLimitPrice, signalName, // direction, exitMarketLimitStop); Debugger.Break(); } this.ExecutionDataSnapshot.AlertEnrichedRegister(alert, registerInNewAfterExec); return alert; }
public double AlignAlertPriceToPriceLevel(Bars bars, double orderPrice, bool buyOrShort, PositionLongShort positionLongShort0, MarketLimitStop marketLimitStop0) { if (this.Strategy.ScriptContextCurrent.NoDecimalRoundingForLimitStopPrice) return orderPrice; if (bars == null) bars = this.Bars; if (bars.SymbolInfo.PriceLevelSizeForBonds == 0.0) { string text = "1"; if (this.Strategy.ScriptContextCurrent.PriceLevelSizeForBonds > 0) { text = text.PadRight(this.Strategy.ScriptContextCurrent.PriceLevelSizeForBonds + 1, '0'); bars.SymbolInfo.PriceLevelSizeForBonds = 1.0 / (double)Convert.ToInt32(text); } return orderPrice; } orderPrice = bars.SymbolInfo.RoundAlertPriceToPriceLevel(orderPrice, buyOrShort, positionLongShort0, marketLimitStop0); return orderPrice; }
public Alert EntryAlertCreate(Bar entryBar, double stopOrLimitPrice, string entrySignalName, Direction direction, MarketLimitStop entryMarketLimitStop) { //if (direction == Direction.Buy // && this.executor._BarsLimitedUpBy(entryBar) == false) return null; //if (direction == Direction.Short // && this.executor._BarsLimitedDownBy(entryBar) == false) return null; double entryPriceScript = stopOrLimitPrice; int barSmallestAllowed = 0; OrderSpreadSide orderSpreadSide = OrderSpreadSide.Unknown; switch (entryMarketLimitStop) { case MarketLimitStop.Market: //if (entryBar >= this.executor.Bars.Count) { if (entryBar.IsBarStreaming) { if (this.executor.IsStreaming) { //basisPrice = 0; this.executor.DataSource.StreamingProvider.StreamingDataSnapshot.GetAlignedBidOrAskForTidalOrCrossMarketFromStreaming( this.executor.Bars.Symbol, direction, out entryPriceScript, out orderSpreadSide, false); } else { //basisPrice = this.executor.Bars.LastBar.Open; //if (bar > this.executor.Bars.Count) { // throw new Exception("got LastBar.Open while MarketOrder is placed few bars further from LastBar"); //} // entryPriceScript = this.executor.Bars[entryBar - 1].Close; // string msg = "[" + direction + "]At[" + entryMarketLimitStop + "](bar=[" + entryBar + "])" // + " when LastBar[" + (this.executor.Bars.Count - 1) + "]; No way I can bring you price from the future, even by executing your order right now" // + "; can't do inequivalent repacement to LastBar.Open"; // log.Fatal(msg, new Exception(msg)); string msg = "[" + direction + "]At[" + entryMarketLimitStop + "](bar=[" + entryBar + "])"; throw new Exception("UNABLE_TO_REFACTOR#1 " + msg); } } else { //entryPriceScript = this.executor.Bars[entryBar].Open; entryPriceScript = entryBar.Open; } barSmallestAllowed = 1; break; case MarketLimitStop.AtClose: //basisPrice = this.executor.Bars[bar - 1].Close; //if (entryBar >= this.executor.Bars.Count) { //bar+1 if (entryBar.IsBarStreaming) { entryPriceScript = 0; string msg = "[" + direction + "]At[" + entryMarketLimitStop + "](bar=[" + entryBar + "])" + " when LastBar[" + (this.executor.Bars.Count - 1) + "]; No way I can bring you a future price," + " even by executing your order right now" + "; can't do inequivalent repacement to LastBar.Close"; log.Fatal(msg, new Exception(msg)); } else { //entryPriceScript = this.executor.Bars[entryBar].Close; entryPriceScript = entryBar.Close; } barSmallestAllowed = 0; break; case MarketLimitStop.Stop: break; case MarketLimitStop.Limit: break; default: throw new Exception("no handler for Direction.[" + direction + "]"); } //BAR_NOT_NULL_CHECKED_UPSTACK_IN_ScriptExecutor.BuyOrShortAlertCreateRegister() this.executor._throwWhenBarOutsideInterval(entryBar, barSmallestAllowed, this.executor.Bars.Count, this.executor.Bars); //if (entryBar < this.executor.Bars.Count) { this.basisPriceZeroCheckThrow(entryPriceScript); //} PositionLongShort longShortFromDirection = MarketConverter.LongShortFromDirection(direction); entryPriceScript = this.executor.AlignAlertPriceToPriceLevel(this.executor.Bars, entryPriceScript, true, longShortFromDirection, entryMarketLimitStop); if (entryPriceScript == 0) { int a = 1; } double shares = this.executor.PositionSizeCalculator.CalcPositionSize(entryBar, entryPriceScript, longShortFromDirection, this.executor.ScriptExecutorConfig.RiskStopLevel, true); Alert alert = new Alert(entryBar, shares, entryPriceScript, entrySignalName, direction, entryMarketLimitStop, orderSpreadSide, //this.executor.Script, this.executor.Strategy); alert.AbsorbFromExecutor(executor); return alert; }