コード例 #1
0
        private async Task RunOrdersTest()
        {
            // 2013-12-06T20:36:06Z
            var expiry = DateTime.Now.AddMonths(1);

            // XmlConvert.ToDateTime and ToString can be used for going to/from RCF3339
            //string expiryString = XmlConvert.ToString(expiry, XmlDateTimeSerializationMode.Utc);

            // oco: dunno if this works yet .. req'd due to portable class library
            string expiryString = XmlConvert.ToString(expiry, "yyyy-MM-ddTHH:mm:ssZ");

            // create new pending order
            var request = new Dictionary <string, string>
            {
                { "instrument", TestInstrument },
                { "units", "1" },
                { "side", "buy" },
                { "type", "marketIfTouched" },
                { "expiry", expiryString },
                { "price", "1.0" }
            };
            var response = await Rest.PostOrderAsync(_accountId, request);

            _results.Verify(response.orderOpened != null && response.orderOpened.id > 0, "Order successfully opened");
            // Get open orders
            var orders = await Rest.GetOrderListAsync(_accountId);

            // Get order details
            if (orders.Count == 0)
            {
                _results.Add("Error: No orders to request details for...");
            }
            else
            {
                var order = await Rest.GetOrderDetailsAsync(_accountId, orders[0].id);

                _results.Verify(order.id > 0, "Order details retrieved");
            }

            // Modify an Existing order
            request["units"] += 10;
            var patchResponse = await Rest.PatchOrderAsync(_accountId, orders[0].id, request);

            _results.Verify(patchResponse.id > 0 && patchResponse.id == orders[0].id && patchResponse.units.ToString() == request["units"], "Order patched");

            // close an order
            var deletedOrder = await Rest.DeleteOrderAsync(_accountId, orders[0].id);

            _results.Verify(deletedOrder.id > 0 && deletedOrder.units == patchResponse.units, "Order deleted");
        }
コード例 #2
0
 public override async Task MakeRequest()
 {
     await InternalMakeRequest(() => Rest.DeleteOrderAsync(AccountDataSource.DefaultDataSource.Id, RequestHelpers.lastOrderId));
 }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="thrust"></param>
        /// <param name="retracement"></param>
        protected virtual async void ManageOrder(Chart chart, Thrust thrust)
        {
            StrategyTransaction[] transactions = null;
            StrategyTransaction   orderTransaction, fillTransaction, cancelTransaction, exitTransaction;

            // get transaction collection from db
            int orderTransactionID = thrust.StrategyTransactionID.GetValueOrDefault();

            transactions = await StrategyCaller.Instance().GetStrategyTransactionsCollectionAsync(orderTransactionID);

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

            bool purgeInActiveThrust = true;

            if (fillTransaction == null)
            {
                if (cancelTransaction != null)
                {
                    // order cancelled

                    thrust.Active = false;
                }
                else
                {
                    // order open

                    if (!thrust.Active)
                    {
                        // cancel the order
                        // the cancel transaction will be written to the db by the event stream handler
                        await Rest.DeleteOrderAsync(_accountId, Convert.ToInt64(orderTransaction.BrokerTransactionID));
                    }
                    else
                    {
                        if (thrust.FocusChanged() || (thrust.FillZoneReached() && thrust.TakeProfitZoneReached()))
                        {
                            AddAlgorithmMessage(string.Format("UPDATE ORDER: {0}: FCH-{1}: FZR-{2}: TPR-{3}", orderTransaction.Instrument, thrust.FocusChanged(), thrust.FillZoneReached(), thrust.TakeProfitZoneReached()));
                            UpdateEntryOrder(orderTransaction, chart, thrust);
                        }
                    }
                }
            }
            else
            {
                if (exitTransaction == null)
                {
                    // order filled

                    purgeInActiveThrust = false;
                    FibonacciRetracement retracement = (FibonacciRetracement)thrust.Study;

                    #region get open trade info
                    long  tradeId   = Convert.ToInt64(fillTransaction.BrokerTransactionID);
                    Frame fillFrame = chart.Frames.LastOrDefault(f => Convert.ToDateTime(f.Bar.time).ToUniversalTime() <= fillTransaction.Time);
                    int   fillIndex = chart.Frames.IndexOf(fillFrame);
                    #endregion

                    #region get takeProfitPrice and stopLossPrice
                    int profitWaitPeriods = Parameters.GetInteger("thrustProfitWaitPeriods") ?? 6;
                    thrust.ProfitWindowClosed = (fillIndex + profitWaitPeriods) < chart.Frames.Count;

                    IPriceBar lastBar   = chart.Frames.Last().Bar;
                    bool      hasProfit = orderTransaction.Side == MACC.Constants.SignalSide.Buy ? lastBar.closeMid > fillTransaction.Price : lastBar.closeMid < fillTransaction.Price;

                    #region stopLossPrice & takeProfitPrice logic
                    // adjust stopLossPrice and takeProfitPrice
                    // if a buy ...
                    //    move the stop to the lower of the .500 fib price or [patern lowMid price set by the post-fill price action]
                    //    move the profit target to 1 or 2 pips under .618 * (thrust.FocusPrice - [pattern lowMid price set by the post-fill price action])
                    // if a sell ...
                    //    move the stop to the higher of the .500 fib price or [patern highMid price set by the post-fill price action]
                    //    move the profit target to 1 or 2 pips above .618 * ([pattern lowMid price set by the post-fill price action] - thrust.FocusPrice)
                    #endregion

                    double?takeProfitPrice = GetAdjustedTakeProfitPrice(chart, thrust.Side, retracement);
                    AddAlgorithmMessage(string.Format("GET SLP: {0}: TPZ-{1}: PWC-{2}: XTP-{3}: CLP-{4}: PFT-{5}", fillTransaction.Instrument, thrust.TakeProfitZoneReached(), thrust.ProfitWindowClosed, retracement.ExtremaPrice, lastBar.closeMid, hasProfit));
                    double?stopLossPrice = GetAdjustedStopLossPrice(chart, thrust.Side, thrust, hasProfit);
                    #endregion

                    #region kill or update the trade
                    // not profitable && beyond r500 .. kill it
                    if (stopLossPrice.GetValueOrDefault() == -1)
                    {
                        thrust.Active       = false;
                        purgeInActiveThrust = true;

                        try
                        {
                            await Rest.DeleteTradeAsync(_accountId, tradeId);
                        }
                        catch (Exception e)
                        {
                            AddAlgorithmMessage(string.Format("CLOSE TRADE {0} Failed: {1}", tradeId, e.Message), true, TraceEventType.Error);
                        }
                    }
                    else
                    {
                        if ((takeProfitPrice ?? thrust.TakeProfitPrice) != thrust.TakeProfitPrice || (stopLossPrice ?? thrust.StopLossPrice) != thrust.StopLossPrice)
                        {
                            AddAlgorithmMessage(string.Format("UPDATE TRADE: {0}: TPZ-{1}: PWC-{2}: XTP-{3}: CLP-{4}: TP-{5}: TTP-{6}: SL-{7}: TSL-{8}", fillTransaction.Instrument, thrust.TakeProfitZoneReached(), thrust.ProfitWindowClosed, retracement.ExtremaPrice, lastBar.closeMid, takeProfitPrice, thrust.TakeProfitPrice, stopLossPrice, thrust.StopLossPrice));
                            UpdateOpenTrade(thrust, tradeId, takeProfitPrice, stopLossPrice, retracement.LevelPlaces());
                        }
                    }
                    #endregion
                }
                else
                {
                    // trade closed

                    #region about closed trades
                    // if coll includes a stopLossFilled or takeProfitFilled ..
                    // set thrust.Active = false
                    // this be done server side when the strategyTransaction from the stream is saved
                    // the signal should be found on the server and signal.Active should be set to false
                    // do it here also
                    #endregion

                    thrust.Active = false;
                }
            }

            if (!thrust.Active && purgeInActiveThrust)
            {
                await PurgeThrust(chart, thrust);
            }
        }
コード例 #4
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);
                }
            }
        }