예제 #1
0
 public StrategyTransaction SaveStrategyTransaction(StrategyTransaction transaction, string brokerName)
 {
     WithStrategyClient(strategyClient =>
     {
         _transactionResult = strategyClient.SaveStrategyTransaction(transaction, brokerName);
     });
     return(_transactionResult);
 }
예제 #2
0
 public StrategyTransaction UpdateStrategyTransaction(StrategyTransaction transaction)
 {
     WithStrategyClient(strategyClient =>
     {
         _transactionResult = strategyClient.UpdateStrategyTransaction(transaction);
     });
     return(_transactionResult);
 }
예제 #3
0
 public StrategyTransaction GetStrategyTransaction(int transactionId)
 {
     WithStrategyClient(strategyClient =>
     {
         _transactionResult = strategyClient.GetStrategyTransaction(transactionId);
     });
     return(_transactionResult);
 }
예제 #4
0
        public async Task <StrategyTransaction> SaveStrategyTransactionAsync(StrategyTransaction transaction, string brokerName)
        {
            await WithStrategyClientAsync(async strategyClient =>
            {
                _transactionResult = await strategyClient.SaveStrategyTransactionAsync(transaction, brokerName);
            });

            return(_transactionResult);
        }
예제 #5
0
        public async Task <StrategyTransaction> UpdateStrategyTransactionAsync(StrategyTransaction transaction)
        {
            await WithStrategyClientAsync(async strategyClient =>
            {
                _transactionResult = await strategyClient.UpdateStrategyTransactionAsync(transaction);
            });

            return(_transactionResult);
        }
예제 #6
0
        public async Task <StrategyTransaction> GetStrategyTransactionAsync(int transactionId)
        {
            await WithStrategyClientAsync(async strategyClient =>
            {
                _transactionResult = await strategyClient.GetStrategyTransactionAsync(transactionId);
            });

            return(_transactionResult);
        }
예제 #7
0
        protected virtual async Task AddStrategyTransaction(StrategyTransaction transaction)
        {
            StrategyTransaction updatedTransaction = await StrategyCaller.Instance().UpdateStrategyTransactionAsync(transaction);

            _strategy.Transactions.Add(updatedTransaction);

            string message = "New Transaction: " + updatedTransaction.Side + " : " + updatedTransaction.Instrument;

            await AddAlgorithmMessage(message, true, TraceEventType.Information);
        }
예제 #8
0
        public StrategyTransaction UpdateStrategyTransaction(StrategyTransaction transaction)
        {
            return(ExecuteFaultHandledOperation(() =>
            {
                string brokerName = GetBroker(transaction.BrokerID).Name;

                StrategyTransaction updatedEntity = SaveStrategyTransaction(transaction, brokerName);

                return updatedEntity;
            }));
        }
예제 #9
0
        public StrategyTransaction GetStrategyTransaction(int transactionId)
        {
            return(ExecuteFaultHandledOperation(() =>
            {
                IStrategyTransactionRepository transactionRepository = _DataRepositoryFactory.GetDataRepository <IStrategyTransactionRepository>();

                StrategyTransaction transaction = transactionRepository.Get(transactionId);

                if (transaction == null)
                {
                    NotFoundFault fault = new NotFoundFault(string.Format("No transaction found with id '{0}'.", transactionId));
                    throw new FaultException <NotFoundFault>(fault, fault.Message);
                }

                return transaction;
            }));
        }
예제 #10
0
        protected StrategyTransaction CreateFillTransaction(Transaction t)
        {
            StrategyTransaction strategyTransaction = CreateStrategyTransaction(t.instrument, t.side, t.time, t.type, t.price, t.takeProfitPrice, t.stopLossPrice, t.id.ToString(), t.orderId.ToString(), null);

            IOrder tradeOrder = Orders.FirstOrDefault(o => o.id == t.orderId);

            if (tradeOrder != null)
            {
                ((MarketMinerOrder)tradeOrder).Filled = true;

                MarketMinerTrade tradeOpened = new MarketMinerTrade(t.tradeOpened);
                tradeOpened.SignalID = ((MarketMinerOrder)tradeOrder).SignalID;
                tradeOpened.StrategyTransactionID = strategyTransaction.StrategyTransactionID;
                AddOrUpdateAlgorithmTrade(tradeOpened);
            }

            return(strategyTransaction);
        }
예제 #11
0
        protected virtual StrategyTransaction SaveStrategyTransaction(Transaction t)
        {
            // create a new record for oanda transactions
            StrategyTransaction transaction = null;

            if (!CoreUtilities.InList <string>(t.type
                                               , MACC.Constants.TransactionTypes.LimitOrderCreate
                                               , MACC.Constants.TransactionTypes.MarketIfTouchedOrderCreate
                                               , MACC.Constants.TransactionTypes.MarketOrderCreate))
            {
                if (t.tradeOpened != null) // fill
                {
                    transaction = CreateFillTransaction(t);
                }
                else if (t.type == MACC.Constants.TransactionTypes.OrderCancel)
                {
                    transaction = CreateOrderCancelTransaction(t, t.instrument, t.side, t.time, t.type, t.price, t.id.ToString(), t.orderId.ToString(), t.reason);
                }
                else if (t.type == MACC.Constants.TransactionTypes.OrderUpdate)
                {
                    transaction = CreateOrderUpdateTransaction(t.instrument, t.side, t.time, t.type, t.price, t.takeProfitPrice, t.stopLossPrice, t.id.ToString(), t.orderId.ToString());
                }
                else if (t.type == MACC.Constants.TransactionTypes.TradeUpdate)
                {
                    transaction = CreateTradeUpdateTransaction(t, t.instrument, t.side, t.time, t.type, t.price, t.takeProfitPrice, t.stopLossPrice, t.id.ToString(), t.tradeId.ToString());
                }
                else if (t.tradeId > 0 ||
                         CoreUtilities.InList <string>(t.type
                                                       , MACC.Constants.TransactionTypes.StopLossFilled
                                                       , MACC.Constants.TransactionTypes.TakeProfitFilled
                                                       , MACC.Constants.TransactionTypes.TradeClose)) // close
                {
                    transaction = CreateExitTransaction(t, t.instrument, t.side, t.time, t.type, t.price, t.id.ToString(), t.tradeId.ToString());
                }

                if (transaction != null)
                {
                    StrategyCaller.Instance().SaveStrategyTransactionAsync(transaction, MarketMiner.Common.Constants.Brokers.OANDA);
                }
            }

            return(transaction);
        }
예제 #12
0
        public StrategyTransaction[] GetStrategyTransactionsCollection(int entryStrategyTransactionId)
        {
            return(ExecuteFaultHandledOperation(() =>
            {
                // get the entry order transaction
                StrategyTransaction transaction = GetStrategyTransaction(entryStrategyTransactionId);

                // add it to the return collection
                List <StrategyTransaction> transactions = new List <StrategyTransaction>()
                {
                    transaction
                };

                IStrategyTransactionRepository transactionRepository = _DataRepositoryFactory.GetDataRepository <IStrategyTransactionRepository>();

                List <string> searchIds = new List <string>()
                {
                    transaction.BrokerTransactionID
                };

                // find the related transactions
                while (searchIds.Count > 0)
                {
                    string searchId = searchIds.First();

                    searchIds.RemoveAt(0);

                    List <StrategyTransaction> relatedTransactions = transactionRepository.Get().Where(t => t.BrokerOrderID == searchId || t.BrokerTradeID == searchId).ToList();

                    // grab their BrokerTransactionId's
                    relatedTransactions.ForEach(t => searchIds.Add(t.BrokerTransactionID));

                    // add them to the collection
                    transactions.AddRange(relatedTransactions);
                }

                return transactions.ToArray();
            }));
        }
예제 #13
0
        protected virtual StrategyTransaction CreateStrategyTransaction(string instrument, string side, string time, string type, double price, double?takeProfit, double?stopLoss, string id, string orderId, string tradeId)
        {
            StrategyTransaction strategyTransaction = new StrategyTransaction()
            {
                BrokerID            = 0, // this will be updated server side
                BrokerTransactionID = id,
                BrokerOrderID       = orderId,
                BrokerTradeID       = tradeId,
                AccountID           = Credentials.GetDefaultCredentials().DefaultAccountId.ToString(),
                StrategyID          = _strategy.StrategyID,
                Instrument          = instrument,
                Side = string.IsNullOrEmpty(side)
               ? MACC.Constants.SignalSide.None
               : side.ToLower() == "buy" ? MACC.Constants.SignalSide.Buy : MACC.Constants.SignalSide.Sell,
                Time       = Convert.ToDateTime(time).ToUniversalTime(),
                Type       = type.ToUpper(),
                Price      = price,
                TakeProfit = takeProfit,
                StopLoss   = stopLoss
            };

            return(strategyTransaction);
        }
예제 #14
0
        public StrategyTransaction SaveStrategyTransaction(StrategyTransaction transaction, string brokerName)
        {
            return(ExecuteFaultHandledOperation(() =>
            {
                StrategyTransaction updatedEntity = null;
                Strategy strategy = GetStrategy(transaction.StrategyID);

                if (strategy != null)
                {
                    IStrategyTransactionRepository transactionRepository = _DataRepositoryFactory.GetDataRepository <IStrategyTransactionRepository>();

                    if (transaction.StrategyTransactionID == 0)
                    {
                        transaction.BrokerID = GetBrokerByName(brokerName).BrokerID;
                        updatedEntity = transactionRepository.Add(transaction);
                    }
                    else
                    {
                        updatedEntity = transactionRepository.Update(transaction);
                    }
                }
                return updatedEntity;
            }));
        }
예제 #15
0
 public StrategyTransaction SaveStrategyTransaction(StrategyTransaction transaction, string brokerName)
 {
     return(Channel.SaveStrategyTransaction(transaction, brokerName));
 }
예제 #16
0
 public StrategyTransaction UpdateStrategyTransaction(StrategyTransaction transaction)
 {
     return(Channel.UpdateStrategyTransaction(transaction));
 }
예제 #17
0
 public Task <StrategyTransaction> SaveStrategyTransactionAsync(StrategyTransaction transaction, string brokerName)
 {
     return(Channel.SaveStrategyTransactionAsync(transaction, brokerName));
 }
예제 #18
0
 public Task <StrategyTransaction> UpdateStrategyTransactionAsync(StrategyTransaction transaction)
 {
     return(Channel.UpdateStrategyTransactionAsync(transaction));
 }
예제 #19
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);
        }
예제 #20
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);
                }
            }
        }
예제 #21
0
        protected virtual Thrust GetActiveThrust()
        {
            Thrust thrust = null;
            Signal signal = null;

            signal = SubscriptionCaller.Instance().GetActiveSignalsByType(MACC.Constants.SignalType.Thrust).FirstOrDefault(s => s.Granularity == _chart.Granularity && s.Instrument == _chart.Instrument);

            if (signal != null)
            {
                thrust           = new Thrust();
                thrust.Direction = signal.Side == MACC.Constants.SignalSide.Buy ? EPatternDirection.Up : EPatternDirection.Down;
                thrust.InjectWith(signal);

                if (signal.StrategyTransactionID.HasValue)
                {
                    IEnumerable <StrategyTransaction> transactions;
                    StrategyTransaction orderTransaction, lastOrderUpdate, lastTradeUpdate;

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

                    orderTransaction = transactions.FirstOrDefault(t => t.StrategyTransactionID == orderTransactionID);
                    lastOrderUpdate  = transactions.LastOrDefault(t => t.Type == MACC.Constants.TransactionTypes.OrderUpdate);

                    // update prices
                    if (lastOrderUpdate != null)
                    {
                        thrust.SetOrUpdatePrices(lastOrderUpdate.Price, lastOrderUpdate.TakeProfit, lastOrderUpdate.StopLoss, null);
                    }
                    else
                    {
                        thrust.SetOrUpdatePrices(orderTransaction.Price, orderTransaction.TakeProfit, orderTransaction.StopLoss, null);
                    }

                    lastTradeUpdate = transactions.LastOrDefault(t => t.Type == MACC.Constants.TransactionTypes.TradeUpdate);
                    if (lastTradeUpdate != null)
                    {
                        thrust.SetOrUpdatePrices(null, lastTradeUpdate.TakeProfit, lastTradeUpdate.StopLoss, null);
                    }

                    // update price times
                    List <StrategyTransaction> updateTransactions = transactions.Where(t => t.Type == MACC.Constants.TransactionTypes.OrderUpdate || t.Type == MACC.Constants.TransactionTypes.TradeUpdate).ToList();

                    StrategyTransaction lastTakeProfitUpdate    = orderTransaction;
                    StrategyTransaction lastStopLossPriceUpdate = orderTransaction;

                    if (updateTransactions.Count() > 0)
                    {
                        updateTransactions.OrderByDescending(t => t.BrokerTransactionID).ToList().ForEach(t =>
                        {
                            if (t.TakeProfit != lastTakeProfitUpdate.TakeProfit)
                            {
                                lastTakeProfitUpdate = t;
                            }
                            if (t.StopLoss != lastStopLossPriceUpdate.StopLoss)
                            {
                                lastStopLossPriceUpdate = t;
                            }
                        });
                    }

                    thrust.SetOrUpdatePriceUpdatedTimes(null, lastTakeProfitUpdate.Time, lastStopLossPriceUpdate.Time);
                }
            }

            return(thrust);
        }
예제 #22
0
        protected async Task <bool> UpdateStrategyTransactions()
        {
            AddAlgorithmMessage("Retrieving latest OANDA transactions ...", false, TraceEventType.Information);

            bool finished = false;

            try
            {
                // get from database the most recent transaction received from oanda
                StrategyTransaction lastTransaction = StrategyCaller.Instance().GetStrategyTransactions(1, true).FirstOrDefault();

                int newCount = 0;

                if (lastTransaction != null)
                {
                    _faultMissedTransactions.Clear();

                    // get from oanda all transactions after the most recent received
                    int    requestCount = 500;
                    string minId        = lastTransaction.BrokerTransactionID;

                    while (!finished)
                    {
                        var parameters = new Dictionary <string, string>
                        {
                            { "minId", minId },
                            { "count", requestCount.ToString() }
                        };

                        List <Transaction> transactions = await Rest.GetTransactionListAsync(_accountId, parameters);

                        if (transactions.Count > 0)
                        {
                            if (transactions.Exists(t => t.id.ToString() == minId))
                            {
                                transactions.RemoveAll(t => t.id.ToString() == minId);
                            }

                            if (transactions.Count > 0)
                            {
                                _faultMissedTransactions.AddRange(transactions);

                                newCount += transactions.Count;

                                // sort ascending
                                transactions.Sort((t1, t2) => t1.id.CompareTo(t2.id));

                                // save to the db
                                transactions.ForEach(t => SaveStrategyTransaction(t));

                                minId = transactions.Max(t => t.id).ToString();

                                // oanda limit: 1 per 60 secs.
                                // http://developer.oanda.com/rest-live/transaction-history/#pagination
                                if (transactions.Count < 499)
                                {
                                    finished = true;
                                }
                                else
                                {
                                    await Task.Delay(TimeSpan.FromSeconds(70));
                                }
                            }
                            else
                            {
                                finished = true;
                            }
                        }
                    }
                }

                AddAlgorithmMessage(string.Format("{0} new OANDA transactions retrieved.", newCount), false, TraceEventType.Information);

                return(true);
            }
            catch (Exception e)
            {
                throw new Exception("Could not retrieve and save latest OANDA transactions.", e);
            }
        }