Ejemplo n.º 1
0
        /// <summary>
        /// Do a tick and handle trading
        /// </summary>
        /// <returns>A task</returns>
        public async Task Tick()
        {
            // Collect tradeable instrument granularities
            var tradeableGranularities = GetInstrumentGranularities().Where(granularity => granularity.IsTradeable);

            // Collect latest candles for all relevant granularities for the tick time
            var tickRelevantGranularities = tradeableGranularities.Where(granularity => IsTickRelevant(granularity.Granularity));
            var instrumentTicks           = new List <InstrumentWithCandles>();

            foreach (var granularity in tickRelevantGranularities)
            {
                var lastTwoCandles = await GetLastTwoCandles(granularity.Instrument.Name, granularity.Granularity);

                // Last candle is not complete -> market is open
                if (!lastTwoCandles.ElementAt(1).Complete)
                {
                    instrumentTicks.Add(new InstrumentWithCandles()
                    {
                        InstrumentName = granularity.Instrument.Name,
                        Granularity    = granularity.Granularity,
                        Candles        = new List <Candle>()
                        {
                            _mapper.Map <Candle>(lastTwoCandles.ElementAt(0))
                        }
                    });
                }
            }

            if (instrumentTicks.Count() == 0)
            {
                // Do not execute engine tick
                return;
            }

            // Save them to the storage account
            foreach (var tick in instrumentTicks)
            {
                // Let's eliminate storage account speed, failures should be handles
                // within the service anyway so don't care is a safe option here
                _ = _instrumentStorageService.StoreInstrumentCandles(tick);
            }

            // Tick them to the engine
            var tradeSignals = await TickToEngine(instrumentTicks);

            // Save trade signals generated
            var tradeSignalsToDb = _mapper.Map <IEnumerable <Database.Trade.TradeSignal> >(tradeSignals);

            _dbContext.AddRange(tradeSignalsToDb);
            _dbContext.SaveChanges();

            // Make a trade for each for each connection
            var connections = GetConnections();

            foreach (var conn in connections)
            {
                // Oanda
                if (conn.Broker == DbConnections.Broker.Oanda)
                {
                    var oandaServer     = conn.Type == ContractConnections.ConnectionType.Demo ? OandaConnectionType.FxPractice : OandaConnectionType.FxTrade;
                    var oandaConnection = _oandaApiConnectionFactory.CreateConnection(oandaServer, await _connectionsSecretService.GetConnectionSecret(conn.Id));

                    foreach (var ts in tradeSignals)
                    {
                        // Use the 40% of liquid cash
                        var account = await oandaConnection.GetAccount(conn.ExternalAccountId).GetDetailsAsync();

                        var positionSize = (account.Balance + account.UnrealizedPL) * .4;

                        await oandaConnection
                        .GetAccount(conn.ExternalAccountId)
                        .Trades
                        .OpenTradeAsync(
                            _mapper.Map <GeriRemenyi.Oanda.V20.Client.Model.InstrumentName>(ts.Instrument),
                            _mapper.Map <SdkTrade.TradeDirection>(ts.Direction),
                            Convert.ToInt64(Math.Floor(positionSize)),
                            900     // Stop loss: 900 pips
                            );
                    }
                }
            }
        }