Ejemplo n.º 1
0
        private MyOperationData InitializeOperationData(Operation op)
        {
            var execData = op.ExecutorData as MyOperationData;

            if (execData == null)
            {
                execData = new MyOperationData();
                if (op.Type == OperationType.BuyThenSell)
                {
                    execData.EntryDirection = TradeDirection.Buy;
                    execData.ExitDirection  = TradeDirection.Sell;
                }
                else if (op.Type == OperationType.SellThenBuy)
                {
                    execData.EntryDirection = TradeDirection.Sell;
                    execData.ExitDirection  = TradeDirection.Buy;
                }
                else
                {
                    throw new NotSupportedException("Only supports buyThenSell and SellThenBuy operations");
                }
            }
            return(execData);
        }
Ejemplo n.º 2
0
        private async Task ManageSymbol(SymbolData symData, TimeSlice slice)
        {
            var symbol = symData.Feed.Symbol;

            //foreach operation check if the entry is enough
            foreach (Operation operation in symData.ActiveOperations)
            {
                MyOperationData execData = InitializeOperationData(operation);

                //check if it needs to be closed
                if (operation.IsEntryExpired(Algo.Time) && (operation.AmountInvested <= 0 || operation.AmountRemaining / operation.AmountInvested <= 0.03m))
                {
                    operation.ScheduleClose(Algo.Time.AddSeconds(5));
                    continue;
                }

                //check if entry needed
                if (operation.AmountInvested <= 0 && !operation.IsEntryExpired(Algo.Time) && !Algo.EntriesSuspended)
                {
                    var gotEntry = operation.Type == OperationType.BuyThenSell ?
                                   (decimal)symData.Feed.Ask <= operation.Signal.PriceEntry :
                                   (decimal)symData.Feed.Bid >= operation.Signal.PriceEntry;
                    //todo  check if the last entry order was effectively executed
                    //check if we have already sent an order
                    if (execData.LastEntryOrder == null)
                    {
                        var originalAmount = AssetAmount.Convert(operation.AmountTarget, operation.Symbol.Asset, symData.Feed);
                        var stillToBuy     = originalAmount - operation.AmountInvested;
                        if (stillToBuy / originalAmount > 0.2m)
                        {
                            //TODO check requirements for order: price precision, minimum amount, min notional, available money
                            var orderInfo = new OrderInfo()
                            {
                                Symbol        = symbol.Key,
                                Type          = OrderType.Market,
                                Effect        = Algo.DoMarginTrading ? MarginOrderEffect.OpenPosition : MarginOrderEffect.None,
                                Amount        = stillToBuy,
                                ClientOrderId = operation.GetNewOrderId(),
                                Direction     = execData.EntryDirection
                            };
                            var ticket = await Algo.Market.PostNewOrder(orderInfo);

                            if (ticket.Status == RequestStatus.Completed)
                            {
                                //Market order was executed - we should expect the trade on next update
                                execData.LastEntryOrder = ticket.Result;
                            }
                            else
                            {
                                //todo log error
                            }
                        }
                    }
                }

                //check if exit needed
                if (execData.LastExitOrder == null)
                {
                    var shouldExit = operation.Signal.ExpireDate < Algo.Time;
                    var gotTarget  = operation.Type == OperationType.BuyThenSell ?
                                     (decimal)symData.Feed.Bid >= operation.Signal.PriceTarget :
                                     (decimal)symData.Feed.Ask <= operation.Signal.PriceTarget;

                    if (shouldExit || gotTarget)
                    {
                        var amount = operation.AmountRemaining;
                        //TODO check requirements for order: price precision, minimum amount, min notional, available money
                        var orderInfo = new OrderInfo()
                        {
                            Symbol        = symbol.Key,
                            Type          = OrderType.Market,
                            Effect        = Algo.DoMarginTrading ? MarginOrderEffect.ClosePosition : MarginOrderEffect.None,
                            Amount        = amount,
                            ClientOrderId = operation.GetNewOrderId(),
                            Direction     = execData.ExitDirection
                        };
                        var ticket = await Algo.Market.PostNewOrder(orderInfo);

                        if (ticket.Status == RequestStatus.Completed)
                        {
                            //Market order was executed - we should expect the trade on next update
                            execData.LastExitOrder = ticket.Result;
                        }
                        else
                        {
                            //TODO log error
                        }
                    }
                }
            }
        }