public override void OnExitTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { fills.Clear(); SetFlatBidAsk(); bestIndifferenceLine[0] = double.NaN; if (!comboTrade.Completed) { throw new InvalidOperationException("Trade must be completed."); } totalVolume += comboTrade.Volume; maxExcursionLine[0] = double.NaN; if (maxDrawDown < 500.00) { lessThan100Count++; } else { var pnl = Performance.ComboTrades.CurrentProfitLoss; Log.Info(Math.Round(maxDrawDown, 2) + "," + Math.Round(pnl, 2) + "," + Performance.Equity.CurrentEquity + "," + lessThan100Count + "," + comboTrade.EntryTime + "," + comboTrade.ExitTime); } //if (maxTradeSize <= 100 * lotSize) //{ // lessThan100Count++; //} //else //{ // Log.Info((maxTradeSize / lotSize) + "," + lessThan100Count + "," + fill.Time); //} maxTradeSize = 0; LogFills("OnEnterTrade"); }
private void TryDrawTrade(LogicalOrder order, LogicalFill fill) { if (drawTrade != null && strategy != null && strategy.Performance.GraphTrades) { drawTrade(order, fill); } }
public void ExitComboTrade(LogicalFill fill) { TransactionPairBinary comboTrade = comboTradesBinary.Tail; comboTrade.Exit(fill.Price, fill.Time, fill.PostedTime, model.Chart.ChartBars.BarCount, fill.OrderId, fill.OrderSerialNumber); comboTradesBinary.Tail = comboTrade; double pnl = profitLoss.CalculateProfit(comboTrade.Direction, comboTrade.EntryPrice, comboTrade.ExitPrice); pnl = Math.Round(pnl, 2); Equity.OnChangeClosedEquity(pnl); if (trace) { log.Trace("Exit Trade: " + comboTrade); } if (tradeDebug && !model.QuietMode) { tradeLog.Debug(model.Name + "," + Equity.ClosedEquity + "," + pnl + "," + comboTrade); } if (model is Strategy) { Strategy strategy = (Strategy)model; LogicalOrder filledOrder; if (!strategy.TryGetOrderById(fill.OrderId, out filledOrder)) { throw new ApplicationException("A fill for order id: " + fill.OrderId + " was incorrectly routed to: " + strategy.Name); } strategy.OnExitTrade(fill, filledOrder); } if (model is Portfolio) { var portfolio = (Portfolio)model; portfolio.OnExitTrade(); } }
private void UpdateOrderCache(LogicalOrder order, LogicalFill fill) { var strategyPosition = (StrategyPosition)order.Strategy; if (debug) { log.Debug("Adjusting strategy position to " + order.Position + ", strategy position was " + strategyPosition.Position); } strategyPosition.Position = fill.Position; // orderCache.RemoveInactive(order); }
public override void OnExitTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { lastMidpoint = double.NaN; direction = Direction.Sideways; fills.Clear(); SetFlatBidAsk(); if (!comboTrade.Completed) { throw new InvalidOperationException("Trade must be completed."); } totalVolume += comboTrade.Volume; }
public override void OnChangeTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { lastMidpoint = double.NaN; if (fill.Position % lotSize != 0) { return; } var size = Math.Abs(comboTrade.CurrentPosition); var change = size - lastSize; totalVolume += change; lastSize = size; if (change > 0) { fills.AddFirst(new LocalFill(change, fill.Price, fill.Time)); SetupBidAsk(fill.Price); } else { change = Math.Abs(change); for (var current = fills.First; current != null; current = current.Next) { var prevFill = current.Value; if (change > prevFill.Size) { change -= prevFill.Size; fills.Remove(current); if (fills.Count > 0) { SetupBidAsk(fill.Price); } } else { prevFill.Size -= change; if (prevFill.Size == 0) { fills.Remove(current); if (fills.Count > 0) { SetupBidAsk(fill.Price); } } break; } } } }
public override void OnEnterTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { lastSize = Math.Abs(comboTrade.CurrentPosition); nextIncreaseLots = 50; bestIndifferenceLine[0] = CalcIndifferencePrice(comboTrade); fills.AddFirst(new LocalFill(fill)); maxExcursionLine[0] = fill.Price; sequentialIncreaseCount = 0; lastMarketAsk = MarketAsk; lastMarketBid = MarketBid; ResetRubberBand(); maxEquity = Performance.Equity.CurrentEquity; maxDrawDown = 0D; drawDown = 0D; SetupBidAsk(fill.Price); LogFills("OnEnterTrade"); }
private void ChangeComboSize(LogicalFill fill) { TransactionPairBinary combo = comboTradesBinary.Tail; combo.ChangeSize(fill.Position, fill.Price); comboTradesBinary.Tail = combo; if (model is Strategy) { Strategy strategy = (Strategy)model; LogicalOrder filledOrder; if (!strategy.TryGetOrderById(fill.OrderId, out filledOrder)) { throw new ApplicationException("A fill for order id: " + fill.OrderId + " was incorrectly routed to: " + strategy.Name); } strategy.OnChangeTrade(fill, filledOrder); } }
public void ProcessFill(StrategyInterface strategyInterface, LogicalFill fill) { if (debug) { Log.Debug("ProcessFill: " + fill + " for strategy " + strategyInterface); } var strategy = (Strategy)strategyInterface; int orderId = fill.OrderId; LogicalOrder filledOrder = null; if (strategyInterface.TryGetOrderById(fill.OrderId, out filledOrder)) { if (debug) { Log.Debug("Matched fill with orderId: " + orderId); } if (!doStrategyOrders && filledOrder.TradeDirection != TradeDirection.ExitStrategy) { if (debug) { Log.Debug("Skipping fill, strategy order fills disabled."); } return; } if (!doExitStrategyOrders && filledOrder.TradeDirection == TradeDirection.ExitStrategy) { if (debug) { Log.Debug("Skipping fill, exit strategy orders fills disabled."); } return; } TryDrawTrade(filledOrder, fill.Price, fill.Position); if (debug) { Log.Debug("Changed strategy position to " + fill.Position + " because of fill."); } changePosition(strategy.Data.SymbolInfo, fill); } else { throw new ApplicationException("A fill for order id: " + orderId + " was incorrectly routed to: " + strategyInterface.Name); } }
public void EnterComboTrade(LogicalFill fill) { TransactionPairBinary pair = TransactionPairBinary.Create(); pair.Enter(fill.Position, fill.Price, fill.Time, fill.PostedTime, model.Chart.ChartBars.BarCount, fill.OrderId, fill.OrderSerialNumber); comboTradesBinary.Add(pair); if (trace) { log.Trace("Enter trade: " + pair); } if (model is Strategy) { Strategy strategy = (Strategy)model; LogicalOrder filledOrder; if (!strategy.TryGetOrderById(fill.OrderId, out filledOrder)) { throw new ApplicationException("A fill for order id: " + fill.OrderId + " was incorrectly routed to: " + strategy.Name); } strategy.OnEnterTrade(fill, filledOrder); } }
public override void OnEnterTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { switch (_State) { case TradeState.MarketSellTradeWaitFill: Log.Notice("MarketSell Trade Filled"); _State = TradeState.MarketSellTradeFilled; break; case TradeState.MarketBuyTradeWaitFill: Log.Notice("Market Buy Trade Filled"); _State = TradeState.MarketBuyTradeFilled; break; case TradeState.LimitWaitFill: if (Position.IsLong) { _State = TradeState.LimitBuyFilled; } else { _State = TradeState.LimitSellFilled; }; break; case TradeState.LimitBuyFilled: case TradeState.LimitSellFilled: _State = TradeState.LimitBuyAndSellFilled; break; default: throw new ApplicationException("Trade Entered on unknown state"); } base.OnEnterTrade(comboTrade, fill, filledOrder); }
public override void OnExitTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { switch (_State) { case TradeState.MarketSellTradeCloseing: Log.Notice("MarketSell Trade Closed"); _State = TradeState.MarketSellTradeClosed; break; case TradeState.MarketBuyTradeCloseing: Log.Notice("MarketBuy Trade Closed"); _State = TradeState.MarketBuyTradeClosed; break; case TradeState.LimitBuyFilled: case TradeState.LimitSellFilled: _State = TradeState.LimitBuyAndSellFilled; break; default: throw new ApplicationException("Trade exited on unknown state"); } base.OnExitTrade(comboTrade, fill, filledOrder); }
public virtual void OnExitTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { OnExitTrade(); }
public bool OnProcessFill(LogicalFill fill) { if (debug) { log.Debug(model + ": OnProcessFill: " + fill); } if (fill.IsSimulated) { if (debug) { log.Debug("Ignoring fill since it's a simulated fill meaning that the strategy already exited via a money management exit like stop loss or target profit, etc."); } return(true); } if (model is Portfolio) { var portfolio = (Portfolio)model; var portfolioPosition = portfolio.Result.Position; fill = new LogicalFillBinary(portfolioPosition.Current, portfolioPosition.Price, fill.Time, fill.UtcTime, fill.OrderId, fill.OrderSerialNumber, fill.OrderPosition, false); if (debug) { log.Debug("For portfolio, converted to fill: " + fill); } } if (transactionDebug && !model.QuietMode && !(model is PortfolioInterface)) { transactionLog.Debug(model.Name + "," + model.Data.SymbolInfo + "," + fill); } if (fill.Position != position.Current) { if (position.IsFlat) { EnterComboTrade(fill); } else if (fill.Position == 0) { if (model is Strategy) { var strategy = model as Strategy; LogicalOrder filledOrder; strategy.TryGetOrderById(fill.OrderId, out filledOrder); if (filledOrder.TradeDirection != TradeDirection.Change) { ExitComboTrade(fill); } } else { ExitComboTrade(fill); } } else if ((fill.Position > 0 && position.IsShort) || (fill.Position < 0 && position.IsLong)) { // The signal must be opposite. Either -1 / 1 or 1 / -1 if (model is Strategy) { var strategy = model as Strategy; LogicalOrder filledOrder; strategy.TryGetOrderById(fill.OrderId, out filledOrder); if (filledOrder.TradeDirection == TradeDirection.Change) { ChangeComboSize(fill); } else { ExitComboTrade(fill); EnterComboTrade(fill); } } else { ExitComboTrade(fill); EnterComboTrade(fill); } } else { // Instead it has increased or decreased position size. ChangeComboSize(fill); } } position.Change(model.Data.SymbolInfo, fill); if (model is Strategy) { Strategy strategy = (Strategy)model; if (debug) { log.Debug("Changing strategy result position to " + position.Current); } strategy.Result.Position.Copy(position); } // if( model is Portfolio) { // Portfolio portfolio = (Portfolio) model; // double tempNetPortfolioEquity = 0; // tempNetPortfolioEquity += portfolio.Performance.Equity.ClosedEquity; // tempNetPortfolioEquity -= portfolio.Performance.Equity.StartingEquity; // } return(true); }
public virtual void OnExitTrade(LogicalFill fill, LogicalOrder filledOrder) { OnExitTrade(); }
public override void OnEnterTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { lastSize = Math.Abs(comboTrade.CurrentPosition); fills.AddFirst(new LocalFill(fill)); SetupBidAsk(fill.Price); }
public override void OnChangeTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { var tick = Ticks[0]; var midpoint = (tick.Ask + tick.Bid) / 2; if (!fill.IsComplete) { return; } if (Position.Size > maxTradeSize) { maxTradeSize = Position.Size; } if (comboTrade.CurrentPosition > 0 && fill.Price < maxExcursionLine[0]) { maxExcursionLine[0] = fill.Price; } if (comboTrade.CurrentPosition < 0 && fill.Price > maxExcursionLine[0]) { maxExcursionLine[0] = fill.Price; } var size = Math.Abs(comboTrade.CurrentPosition); var lots = size / lotSize; var change = size - lastSize; lastSize = size; if (change > 0) { if (enableManageRisk) { state = StrategyState.HighRisk; } var tempIndifference = CalcIndifferencePrice(comboTrade); if (Position.IsLong && tempIndifference < bestIndifferenceLine[0]) { bestIndifferenceLine[0] = tempIndifference; } if (Position.IsShort && tempIndifference > bestIndifferenceLine[0]) { bestIndifferenceLine[0] = tempIndifference; } if (lots > nextIncreaseLots) { nextIncreaseLots = (nextIncreaseLots * 3) / 2; } sequentialIncreaseCount++; var changed = false; change = Math.Abs(change); if (fills.First != null) { var firstFill = fills.First.Value; if (firstFill.Size + change <= lotSize) { firstFill.Size += change; changed = true; } } if (!changed) { fills.AddFirst(new LocalFill(change, fill.Price, fill.Time)); } SetupBidAsk(fill.Price); } else { sequentialIncreaseCount = 0; change = Math.Abs(change); var prevFill = fills.First.Value; if (change <= prevFill.Size) { prevFill.Size -= change; if (prevFill.Size == 0) { fills.RemoveFirst(); if (fills.Count > 0) { SetupBidAsk(fill.Price); } } return; } change -= prevFill.Size; fills.RemoveFirst(); SetupBidAsk(fill.Price); return; //for (var current = fills.Last; current != null; current = current.Previous) //{ // prevFill = current.Value; // if (change > prevFill.Size) // { // change -= prevFill.Size; // fills.Remove(current); // if (fills.Count > 0) // { // SetupBidAsk(fill.Price); // } // } // else // { // prevFill.Size -= change; // if (prevFill.Size == 0) // { // fills.Remove(current); // if (fills.Count > 0) // { // SetupBidAsk(fill.Price); // } // } // break; // } //} } LogFills("OnChange"); }
public override void OnChangeTrade(TransactionPairBinary comboTrade, LogicalFill fill, LogicalOrder filledOrder) { ProcessChange(comboTrade); }
public LocalFill(LogicalFill fill) { Size = Math.Abs(fill.Position); Price = fill.Price; Time = fill.Time; }
public virtual void Change(SymbolInfo symbol, LogicalFill fill) { this.orderId = fill.OrderId; Change(fill.Position, fill.Price, fill.Time); }