public void Rank_FooShouldBeLowest() { IOrderedEnumerable <TradeInstruction> rankedTrades = tradeRepo.Rank(); TradeInstruction lastRankedTrade = rankedTrades.Last(); Assert.AreEqual(Entity.foo, lastRankedTrade.Entity); }
public void AddTradeExit(TradeInstruction trade) { trades.Add(trade); //update the amount available to trade _amountAvailableForTrade += (trade.Price * trade.Lots); }
public void PlaceOrderExpected() { IDeserializer deserializer = null; var restMock = new Mock <IRestClient>(MockBehavior.Strict); restMock.SetupAllProperties(); restMock.Setup(x => x.AddHandler("application/json", It.IsAny <IDeserializer>())).Callback <string, IDeserializer>((ct, d) => deserializer = d); restMock.Setup(x => x.Execute <ResponseSingle <TradeOrder> >(It.IsAny <IRestRequest>())).Returns <IRestRequest>(request => { var responseMock = new Mock <IRestResponse <ResponseSingle <TradeOrder> > >(MockBehavior.Strict); responseMock.SetupAllProperties(); responseMock.Object.Content = Properties.Resources.PlaceOrderResponse; responseMock.Object.Request = request; responseMock.Object.Data = deserializer.Deserialize <ResponseSingle <TradeOrder> >(responseMock.Object); return(responseMock.Object); }); var client = new BitsoClient(restMock.Object, ServiceUrlMock, ApiKeyMock, ApiSecretMock); var instruction = new TradeInstruction(); instruction.Price = 1000; instruction.MajorCurrencyAmount = 1; instruction.OrderType = TradeOrderType.Limit; instruction.Side = MarketSide.Buy; instruction.BookName = "btc_mxn"; var res = client.PlaceOrder(instruction); Assert.IsNotNull(res); }
public void Rank_BarShouldBeHighest() { IOrderedEnumerable <TradeInstruction> rankedTrades = tradeRepo.Rank(); TradeInstruction firstRankedTrade = rankedTrades.First(); Assert.AreEqual(Entity.bar, firstRankedTrade.Entity); }
internal static DateTimeOffset GetValidSettlementDate(TradeInstruction trade) { int iDaysToAdd = 0; if (!CheckValidSettlement(trade)) { if (trade.Currency.Equals(Currency.AED) || trade.Currency.Equals(Currency.SAR)) { // Valid DayOfWeek values are 0 to 4 if (trade.SettlementDate.DayOfWeek == DayOfWeek.Friday) { iDaysToAdd = 2; } else if (trade.SettlementDate.DayOfWeek == DayOfWeek.Saturday) { iDaysToAdd = 1; } } else if (trade.SettlementDate.DayOfWeek == DayOfWeek.Saturday) { iDaysToAdd = 2; } else if (trade.SettlementDate.DayOfWeek == DayOfWeek.Sunday) { iDaysToAdd = 1; } } return(trade.SettlementDate.AddDays(iDaysToAdd)); }
void OnRealTimeTickDataUpdate(string sender, MarketTickData message) { //TODO: This depends on the mode of when the trade signal should be run if (m_TradingModel.IsDaily && !m_IsDailyTradeSignalRan) { m_IsDailyTradeSignalRan = true; RunTradeSignal(); } if (m_SignalState != TradingModelSignalState.TradeSignal) { //signal is already generated, Run Entry/Exit if (m_SignalState == TradingModelSignalState.TradeEntry) { m_TradeEntryInstruction = m_TradingModel.TradeEntry(); if (m_TradeEntryInstruction != null) { //add the bar index for entry position m_TradeEntryInstruction.BarIndex = m_CurrentBarIndex; m_SignalState = TradingModelSignalState.TradeExit; //add Trade entry to the money manager m_moneyMgr.AddTradeEntry(m_TradeEntryInstruction); } } if (m_SignalState == TradingModelSignalState.TradeExit) { m_TradeExitInstruction = m_TradingModel.TradeExit(m_TradeEntryInstruction); if (m_TradeExitInstruction != null) { //log the bar index for exit signal m_TradeExitInstruction.BarIndex = m_CurrentBarIndex; //add Trade exit to the money manager m_moneyMgr.AddTradeExit(m_TradeExitInstruction); //unsubscribe from all events m_BarDataHandler.BarDataCreatedCompleted -= OnBarDataCreatedCompleted; m_TickDataHandler.OnRealTimeTickDataUpdate -= OnRealTimeTickDataUpdate; m_TickDataHandler.OnRealTimeTickDataDateChange -= OnRealTimeTickDataDateChange; if (CallbackTradePositionCloseReceived != null) { CallbackTradePositionCloseReceived.Invoke(m_ref, m_TradeEntryInstruction, m_TradeExitInstruction); } } } } if (CallbackTickDataUpdateReceived != null) { CallbackTickDataUpdateReceived.Invoke(m_jobId, message, m_CurrentBarIndex); } }
public TradeInstruction NewOrder() { var price = TICKDATA.Price(0); var ask = TICKDATA.Ask(0); var bid = TICKDATA.Bid(0); #region Position Entry - BREAK PRICE HIGH if (price > 0 && ask > 0 && price >= Parameters.BreakPriceHigh) { Parameters.StopPriceLong = ask.Value - Parameters.StopDailyTicks; //ask - Parameters.TargetTicks; //NOTE: Ask = Price we pay for the trade var tradePosition = new TradeInstruction { Direction = TradeDirection.Long, PositionType = TradePositionType.Entry, Price = ask.Value, Stop = Parameters.StopPriceLong.Value, Target = ask.Value + Parameters.TargetTicks.Value }; tradePosition.Lots = MONEYMANAGER.GetLotSize(tradePosition); return(tradePosition); } #endregion #region Position Entry - BREAK PRICE LOW if (price > 0 && bid > 0 && price <= Parameters.BreakPriceLow) { Parameters.StopPriceShort = bid.Value + Parameters.StopDailyTicks; var tradePosition = new TradeInstruction { Direction = TradeDirection.Short, Lots = lots, PositionType = TradePositionType.Entry, Price = bid.Value, Stop = Parameters.StopPriceShort.Value, Target = bid.Value - Parameters.TargetTicks.Value }; return(tradePosition); } #endregion return(null); }
internal static bool CheckValidSettlement(TradeInstruction trade) { bool validSettlement = false; if (!CurrencySettlementDays.ContainsKey(trade.Currency)) { throw new UnknownCurrencyException(); } HashSet <DayOfWeek> validSettlementDays = CurrencySettlementDays.GetValueOrDefault(trade.Currency); if (validSettlementDays != null) { validSettlement = validSettlementDays.Contains(trade.SettlementDate.DayOfWeek); } return(validSettlement); }
/// <summary> /// Generates trades with randomised values based on the numOfTrades passed in /// </summary> /// <param name="repo">The repository to populate</param> /// <param name="numOfTrades">The number of trades to create</param> public void Seed(ITradeInstructionRepository repo, int numOfTrades) { for (int i = 0; i < numOfTrades; i++) { TradeInstruction trade = new TradeInstruction { Entity = getRandomEnum <Entity>(), InstructionFlag = getRandomEnum <InstructionFlag>(), Currency = getRandomEnum <Currency>(), InstructionDate = getRandomDate(offsetDays: 100), SettlementDate = getRandomDate(offsetDays: 100), AgreedFx = getRandomDecimal(maxValue: 2), Price = getRandomDecimal(maxValue: 500), Units = getRandomInt(maxValue: 1000) }; repo.Add(trade); } }
private static void OnTradePositionReceived(int reference, TradeInstruction entry, TradeInstruction exit) { double tradePositionPnL = 0; if (exit != null) { tradePositionPnL = (exit.Direction == TradeDirection.Short) ? exit.Price - entry.Price : entry.Price - exit.Price; pnl += tradePositionPnL; } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Trade position closed for reference :{0} | Entry :{1}{2} | Exit :{3}{4}", reference, entry.Price, entry.Direction, exit.Price, exit.Direction); Console.WriteLine("RUNNING PNL IN TICKS = {0}", pnl); Console.ForegroundColor = ConsoleColor.White; m_JobStat.AddTradeSignal(new TradeSignalStat { Reference = reference, TradePosition = entry, PositionType = "Entry", BarIndex = entry.BarIndex }); m_JobStat.AddTradeSignal(new TradeSignalStat { Reference = reference, TradePosition = exit, PositionType = "Exit", BarIndex = entry.BarIndex }); m_JobStat.AddEquityStat( new EquityStat { Reference = reference, PnL = tradePositionPnL }); }
/// <summary> /// Adds a Trade Instruction to the Trade Repository /// </summary> /// <param name="entity"></param> public void AddTradeInstruction(TradeInstruction entity) { _logger.Log(LogLevel.Information, $"Adding {entity.ToString()} to repository"); TradeRepository.Add(entity); }
public TradeInstruction ExitSignal(TradeInstruction tradePositionEntry) { double currentTargetTicks = Parameters.TargetTicks2.Value; if (lotsNotFilled < lots) { currentTargetTicks = Parameters.TargetTicks.Value; } #region Exit LONG if (tradePositionEntry.Direction == TradeDirection.Long) { var ask = TICKDATA.Ask(0); // DAILYBARDATA //profit #region Position Exit - Take Profit if (ask > 0 && ask >= tradePositionEntry.Price + currentTargetTicks) { /* logPublisher.Publish(LoggingType.INFO, new LogMessage {Message = string.Format("(Exit-Profit) Trade Long Position Price : {0} Target : {1} Exit Price : {2}", * tradePositionEntry.Price, currentTargetTicks, ask)});*/ lotsNotFilled = lotsNotFilled - (lots / 2); //we have hit the first target profit if (lotsNotFilled < lots) { Parameters.StopPriceLong = ask.Value - Parameters.TargetTicks; } return(new TradeInstruction { Direction = TradeDirection.Short, Lots = lots / 2, PositionType = TradePositionType.Exit, Price = ask.Value, Stop = tradePositionEntry.Price - ((lotsNotFilled < lots) ? Parameters.TargetTicks.Value : Parameters.TargetTicks2.Value), Target = tradePositionEntry.Price + ((lotsNotFilled < lots)?Parameters.TargetTicks.Value:Parameters.TargetTicks2.Value) }); } #endregion #region Position Exit - Limit Loss //stop(loss) var bid = TICKDATA.Bid(0); if (bid > 0 && bid <= Parameters.StopPriceLong) { /*logPublisher.Publish(LoggingType.INFO, new LogMessage * { * Message = string.Format("(Exit-Stop Loss) Trade Long Position Price : {0} Stop : {1} Exit Price : {2}", * tradePositionEntry.Price, Parameters.StopPriceLong, bid) * });*/ return(new TradeInstruction { Direction = TradeDirection.Short, Lots = lotsNotFilled, PositionType = TradePositionType.Exit, Price = bid.Value, Stop = Parameters.StopPriceLong.Value, Target = tradePositionEntry.Price + currentTargetTicks }); } #endregion } #endregion #region Exit SHORT if (tradePositionEntry.Direction == TradeDirection.Short) { var bid = TICKDATA.Bid(0); var ask = TICKDATA.Ask(0); //profit #region Position Exit - Take Profit if (bid > 0 && bid <= tradePositionEntry.Price - currentTargetTicks) { /*logPublisher.Publish(LoggingType.INFO, new LogMessage * { * Message = string.Format("(Exit-Profit) Trade Short Position Price : {0} Target Ticks: {1} Exit Price : {2}", * tradePositionEntry.Price, currentTargetTicks, bid) * });*/ lotsNotFilled = lotsNotFilled - (lots / 2); //we have hit the first target profit if (lotsNotFilled < lots) { Parameters.StopPriceShort = bid.Value + Parameters.TargetTicks; } return(new TradeInstruction { Direction = TradeDirection.Long, Lots = lots / 2, PositionType = TradePositionType.Exit, Price = bid.Value, Stop = tradePositionEntry.Price + ((lotsNotFilled < lots) ? Parameters.TargetTicks.Value : Parameters.TargetTicks2.Value), Target = tradePositionEntry.Price - ((lotsNotFilled < lots) ? Parameters.TargetTicks.Value : Parameters.TargetTicks2.Value) }); } #endregion //stop(loss) #region Position Exit - Limit Loss if (ask > 0 && ask >= Parameters.StopPriceShort) { //logPublisher.Publish(LoggingType.INFO, new LogMessage //{ // Message = string.Format("(Exit-Stop Loss) Trade Short Position Price : {0} Stop : {1} Exit Price : {2}", // tradePositionEntry.Price, Parameters.StopPriceLong, bid) //}); return(new TradeInstruction { Direction = TradeDirection.Long, Lots = lotsNotFilled, PositionType = TradePositionType.Exit, Price = ask.Value, Stop = Parameters.StopPriceShort.Value, Target = tradePositionEntry.Price - currentTargetTicks }); } #endregion } #endregion return(null); }
public TradeInstruction TradeExit(TradeInstruction entrySignal) { return(ExitSignal(entrySignal)); }
/// <summary> /// Gets the lots size for the current trade , making sure the current risk parameters are honoured /// </summary> /// <param name="trade"></param> /// <returns></returns> public int GetLotSize(TradeInstruction trade) { double ticksInRisk = Math.Abs(trade.Price - trade.Stop); return(Convert.ToInt32(CurrentTradingAccountAmountAvailableToTrade * RiskPerTrade / ticksInRisk)); }
public void CalculatedValue_BarShouldBe14899() { TradeInstruction barTrade = tradeRepo.List.Where(t => t.Entity.Equals(Entity.bar)).FirstOrDefault(); Assert.AreEqual(_barCalculatedValue, barTrade.CalculatedValue); }
public void CalculatedValue_FooShouldBe1500() { TradeInstruction fooTrade = tradeRepo.List.Where(t => t.Entity.Equals(Entity.foo)).FirstOrDefault(); Assert.AreEqual(_fooCalculatedValue, fooTrade.CalculatedValue); }
public TradeInstruction TradeExit(TradeInstruction entrySignal) { return(null); }