Exemple #1
0
        /// <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);

            MarketMinerOrder currentOrder = Orders.FirstOrDefault(o => o.id == orderId) as MarketMinerOrder;

            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;

            // round and review
            int places = ((FibonacciRetracement)thrust.Study).LevelPlaces();

            bool updateOrder = false;

            if (currentOrder == null)
            {
                updateOrder = true;
            }
            else
            {
                if (Math.Round(entryPrice, places) != currentOrder.price)
                {
                    updateOrder = true;
                }
                if (Math.Round(stopLossPrice, places) != currentOrder.stopLoss)
                {
                    updateOrder = true;
                }
                if (Math.Round(takeProfitPrice, places) != currentOrder.takeProfit)
                {
                    updateOrder = true;
                }
            }

            if (updateOrder)
            {
                int tradeUnits = await TradeUnitsCapacity(thrust.Instrument, entryPrice, stopLossPrice, true);

                // order size should never increase
                tradeUnits = currentOrder != null?Math.Min(currentOrder.units, tradeUnits) : tradeUnits;

                if (tradeUnits > 0)
                {
                    // 12 hours for now .. how should this change?
                    string expiry = MAOE.Utilities.GetTimeAsXmlSerializedUtc(DateTime.UtcNow.AddHours(12));

                    // 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 updatedOrder = await Rest.PatchOrderAsync(_accountId, orderId, patchData);

                    if (updatedOrder != null)
                    {
                        MarketMinerOrder mmUpdatedOrder = new MarketMinerOrder(updatedOrder);
                        mmUpdatedOrder.SignalID = thrust.SignalID;
                        mmUpdatedOrder.StrategyTransactionID = orderTransaction.StrategyTransactionID;

                        AddOrUpdateAlgorithmOrder(mmUpdatedOrder);

                        DateTime transactionTime = Convert.ToDateTime(updatedOrder.time).ToUniversalTime();
                        thrust.SetOrUpdatePrices(entryPrice, takeProfitPrice, stopLossPrice, places, transactionTime);
                    }
                }
                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);
                }
            }
        }
        protected async Task <bool> UpdateOrdersAndTrades()
        {
            AddAlgorithmMessage("Updating instance orders and trades ...", false, TraceEventType.Information);

            short orderCount = 0;
            short tradeCount = 0;

            MCE.Signal[] signals = await SubscriptionCaller.Instance().GetActiveSignalsByTypeAsync(MACC.Constants.SignalType.Thrust);

            foreach (MCE.Signal signal in signals)
            {
                if (signal.StrategyTransactionID.HasValue)
                {
                    IEnumerable <StrategyTransaction> transactions;
                    StrategyTransaction orderTransaction, tradeTransaction, exitTransaction;

                    // get transaction collection from db
                    int orderTransactionID = signal.StrategyTransactionID.Value;
                    transactions = StrategyCaller.Instance().GetStrategyTransactionsCollectionAsync(orderTransactionID).Result;
                    transactions = transactions.Where(t => t.StrategyID == _strategy.StrategyID);
                    transactions = transactions.OrderBy(t => t.BrokerTransactionID);

                    orderTransaction = transactions.FirstOrDefault(t => t.StrategyTransactionID == orderTransactionID);
                    tradeTransaction = transactions.FirstOrDefault(t => t.Type == MACC.Constants.TransactionTypes.OrderFilled);
                    exitTransaction  = transactions.FirstOrDefault(t => t.BrokerTradeID != null && t.Type != MACC.Constants.TransactionTypes.TradeUpdate);

                    if (exitTransaction != null)
                    {
                        signal.Active = false;
                        SubscriptionCaller.Instance().UpdateSignalAsync(signal);

                        continue;
                    }

                    if (tradeTransaction != null)
                    {
                        tradeCount++;

                        long tradeId = Convert.ToInt64(tradeTransaction.BrokerTransactionID);

                        TradeData oandaTrade = await Rest.GetTradeDetailsAsync(_accountId, tradeId);

                        MarketMinerTrade mmTrade = new MarketMinerTrade(oandaTrade)
                        {
                            SignalID = signal.SignalID,
                            StrategyTransactionID = signal.StrategyTransactionID,
                            Closed = exitTransaction != null
                        };

                        AddOrUpdateAlgorithmTrade(mmTrade);

                        continue;
                    }

                    if (orderTransaction != null)
                    {
                        orderCount++;

                        long orderId = Convert.ToInt64(orderTransaction.BrokerTransactionID);

                        Order oandaOrder = await Rest.GetOrderDetailsAsync(_accountId, orderId);

                        MarketMinerOrder mmOrder = new MarketMinerOrder(oandaOrder)
                        {
                            SignalID = signal.SignalID,
                            StrategyTransactionID = signal.StrategyTransactionID,
                            Filled    = tradeTransaction != null,
                            Cancelled = tradeTransaction != null
                        };

                        AddOrUpdateAlgorithmOrder(mmOrder);
                    }
                }
            }

            AddAlgorithmMessage(string.Format("{0} open orders updated.", orderCount), false, TraceEventType.Information);

            AddAlgorithmMessage(string.Format("{0} open trades updated.", tradeCount), false, TraceEventType.Information);

            return(true);
        }
Exemple #3
0
        /// <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);

            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);

                    DateTime transactionTime = Convert.ToDateTime(response.time).ToUniversalTime();
                    thrust.SetOrUpdatePrices(entryPrice, takeProfitPrice, stopLossPrice, places, transactionTime);
                }
            }
            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);
        }