/// <summary> /// /// </summary> /// <param name="tradeId"></param> /// <param name="takeProfitPrice"></param> /// <param name="stopLossPrice"></param> /// <returns></returns> protected virtual async Task UpdateOpenTrade(Thrust thrust, long tradeId, double?takeProfitPrice, double?stopLossPrice, int?places) { // create patch Dictionary <string, string> patchData = new Dictionary <string, string>(); if (takeProfitPrice.GetValueOrDefault() > 0) { patchData.Add("takeProfit", takeProfitPrice.ToString()); } if (stopLossPrice.GetValueOrDefault() > 0) { patchData.Add("stopLoss", stopLossPrice.ToString()); } TradeData response = null; // send patch if (patchData.Count > 0) { try { response = await Rest.PatchTradeAsync(_accountId, tradeId, patchData); } catch (Exception e) { throw e; } thrust.SetTradePrices(null, takeProfitPrice, stopLossPrice, places); } }
/// <summary> /// /// </summary> /// <param name="orderTransaction"></param> /// <param name="thrust"></param> /// <param name="retracement"></param> /// <returns></returns> protected virtual async Task UpdateEntryOrder(StrategyTransaction orderTransaction, Chart chart, Thrust thrust) { long orderId = Convert.ToInt64(orderTransaction.BrokerTransactionID); string side = thrust.Side; Tuple <double, double, double> orderPrices = GetOrderPrices(chart.HistoricBidAskSpread, side, thrust); double entryPrice = orderPrices.Item1; double stopLossPrice = orderPrices.Item2; double takeProfitPrice = orderPrices.Item3; int tradeUnits = await TradeUnitsCapacity(thrust.Instrument, entryPrice, stopLossPrice, true); if (tradeUnits > 0) { // 12 hours for now .. how should this change? string expiry = MAOE.Utilities.GetTimeAsXmlSerializedUtc(DateTime.UtcNow.AddHours(12)); int places = ((FibonacciRetracement)thrust.Study).LevelPlaces(); // create patch var patchData = new Dictionary <string, string> { { "units", tradeUnits.ToString() }, { "expiry", expiry }, { "price", Math.Round(entryPrice, places).ToString() }, { "stopLoss", Math.Round(stopLossPrice, places).ToString() }, { "takeProfit", Math.Round(takeProfitPrice, places).ToString() } }; // what if the fill happens just as execution arrives here? // this bit should somehow affirm that the order remains unfilled Order order = await Rest.PatchOrderAsync(_accountId, orderId, patchData); if (order != null) { MarketMinerOrder orderUpdated = new MarketMinerOrder(order); orderUpdated.SignalID = thrust.SignalID; orderUpdated.StrategyTransactionID = orderTransaction.StrategyTransactionID; orderTransaction.Price = orderUpdated.price; orderTransaction.Time = Convert.ToDateTime(orderUpdated.time).ToUniversalTime(); orderTransaction = await StrategyCaller.Instance().UpdateStrategyTransactionAsync(orderTransaction); AddOrUpdateAlgorithmOrder(orderUpdated); thrust.SetTradePrices(entryPrice, takeProfitPrice, stopLossPrice, places); } } else { thrust.Active = false; // cancel the order await Rest.DeleteOrderAsync(_accountId, orderId); // clear the chart PurgeThrust(chart, thrust); string missedTradeReason = Utilities.GetMissedTradeReason(tradeUnits); AddAlgorithmMessage(string.Format("Missed trade: {0} for signalId: {1}", missedTradeReason, thrust.SignalID), true, TraceEventType.Information); } }
/// <summary> /// /// </summary> /// <param name="signal"></param> /// <param name="instrument"></param> /// <param name="retracement"></param> /// <returns></returns> protected virtual async Task <int> CreateEntryOrder(MCE.Signal signal, Chart chart, Thrust thrust) { StrategyTransaction transaction = null; Tuple <double, double, double> orderPrices = GetOrderPrices(chart.HistoricBidAskSpread, signal.Side, thrust); double entryPrice = orderPrices.Item1; double stopLossPrice = orderPrices.Item2; double takeProfitPrice = orderPrices.Item3; int tradeUnits = await TradeUnitsCapacity(chart.Instrument, entryPrice, stopLossPrice); // catch bad orders here until I fix this //if (signal.Side == MACC.Constants.SignalSide.Buy) //{ // if (entryPrice > takeProfitPrice) tradeUnits = -96; // if (entryPrice < stopLossPrice) tradeUnits = -97; //} //else //{ // if (entryPrice < takeProfitPrice) tradeUnits = -98; // if (entryPrice > stopLossPrice) tradeUnits = -99; //} if (tradeUnits > 0) { // 12 hours for now .. how should this change? .. read from metaSetting? string expiry = MAOE.Utilities.GetTimeAsXmlSerializedUtc(DateTime.UtcNow.AddHours(12)); string type = "limit"; string side = signal.Side == MACC.Constants.SignalSide.Buy ? "buy" : "sell"; int places = ((FibonacciRetracement)thrust.Study).LevelPlaces(); // create order var orderData = new Dictionary <string, string> { { "instrument", chart.Instrument }, { "units", tradeUnits.ToString() }, { "side", side }, { "type", type }, { "expiry", expiry }, { "price", Math.Round(entryPrice, places).ToString() }, { "stopLoss", Math.Round(stopLossPrice, places).ToString() }, { "takeProfit", Math.Round(takeProfitPrice, places).ToString() } }; PostOrderResponse response = await PlaceLimitOrder(orderData); if (response.orderOpened != null && response.orderOpened.id > 0) { MarketMinerOrder orderOpened = new MarketMinerOrder(response.orderOpened); orderOpened.SignalID = signal.SignalID; transaction = CreateEntryTransaction(chart.Instrument, orderOpened.side, response.time, type, response.price.GetValueOrDefault(), orderOpened.takeProfit, orderOpened.stopLoss, orderOpened.id.ToString()); transaction = await StrategyCaller.Instance().SaveStrategyTransactionAsync(transaction, MarketMiner.Common.Constants.Brokers.OANDA); orderOpened.StrategyTransactionID = transaction.StrategyTransactionID; // add entry trans id to the signal signal.StrategyTransactionID = transaction.StrategyTransactionID; await SubscriptionCaller.Instance().UpdateSignalAsync(signal); AddOrUpdateAlgorithmOrder(orderOpened); thrust.SetTradePrices(entryPrice, takeProfitPrice, stopLossPrice, places); } } else { string missedTradeReason = Utilities.GetMissedTradeReason(tradeUnits); AddAlgorithmMessage(string.Format("Missed trade: {0} for signalId: {1}", missedTradeReason, signal.SignalID), true, TraceEventType.Information); } return(transaction == null ? 0 : transaction.StrategyTransactionID); }