public static IReadOnlyList <PriceCandle> GetPriceCandles(TradingSymbol trading_symbol, TimeScale time_scale) { string data_path = Path.Combine(binary_data_root_path, trading_symbol.Broker, trading_symbol.Account, trading_symbol.Symbol, ToolsEnum.EnumToString(time_scale)); if (!Directory.Exists(data_path)) { throw new Exception("No data for trading symbol: " + trading_symbol); } string[] files = Directory.GetFiles(data_path); if (files.Length == 0) { throw new Exception("No data for trading symbol: " + trading_symbol); } using (BinaryReader reader = new BinaryReader(new FileStream(files[0], FileMode.Open))) { int count = reader.ReadInt32(); List <PriceCandle> candles = new List <PriceCandle>(count); for (int candle_index = 0; candle_index < count; candle_index++) { candles.Add(PriceCandle.Read(reader)); } return(candles); } }
public List <PriceCandle> RemapResponseToDb(object jsonObj) { List <PriceCandle> candleList = new List <PriceCandle>(); if (jsonObj is CandleJson candleJson) { foreach (var candle in candleJson.Candles) { if (candle.Complete == true) { PriceCandle priceCandle = new PriceCandle { Granularity = candleJson.Granularity, Instrument = candleJson.Instrument, PriceTime = DateTime.Parse(candle.Time).ToUniversalTime(), Volume = candle.Volume, BidOpen = decimal.Parse(candle.Bid.Open), BidHigh = decimal.Parse(candle.Bid.High), BidLow = decimal.Parse(candle.Bid.Low), BidClose = decimal.Parse(candle.Bid.Close), AskOpen = decimal.Parse(candle.Ask.Open), AskHigh = decimal.Parse(candle.Ask.High), AskLow = decimal.Parse(candle.Ask.Low), AskClose = decimal.Parse(candle.Ask.Close) }; candleList.Add(priceCandle); } } } return(candleList); }
public void CloseOrderNoLimitTest() { double spread = 0.1; Dictionary <int, TradingOrder> OpenOrders = new Dictionary <int, TradingOrder>(); PriceCandle candle = new PriceCandle(DateTimeUTC.Now, TimeScale.Second1, 1, 1.2, 0.8, 1, spread); TradingOrder order_0 = new TradingOrder(TradingOrderType.Long, 0, DateTimeUTC.Now, 1, 1, 0.01); OpenOrders.Add(order_0.OrderTicket, order_0); List <TradingOrder> orders = MarketModelSimulation.CheckOrderLimits(OpenOrders, candle); Assert.AreEqual(orders.Count, 0); }
protected override Task PriceCandleTask() { Console.WriteLine("Running daily candle task"); using (IServiceScope scope = _provider.CreateScope()) { //Sets a default starting date DateTime from = new DateTime(2000, 1, 1); try { // Finds the timestamp for the latest db entry and offset the date by // +1 day, in order to fetch data starting from the next available day var readOps = scope.ServiceProvider.GetRequiredService <IReadOps>(); PriceCandle latestCandle = readOps.FindLatestEntryForPair("EUR_USD"); from = latestCandle.PriceTime.AddDays(1).ToUniversalTime(); } catch (Exception e) { Console.WriteLine("Error in getting most recent db entry, using default start date"); } List <PriceCandle> priceCandles = FetchData("Oanda", "D", from); List <PriceCandle> validatedCandles = Validator.ContinuousDataCheck(priceCandles); var context = scope.ServiceProvider.GetRequiredService <Broker_Data_ServiceContext>(); foreach (var candle in validatedCandles) { try { context.PriceCandle.Add(candle); context.SaveChanges(); Console.WriteLine("Saved Success"); } catch (Exception e) { Console.WriteLine("Saving data unsuccessful"); } } } return(Task.CompletedTask); }
public Transmitter(string sym, MainUI model, ManualResetEvent send, ManualResetEvent quit) { SymbolCode = sym; TimeFrames = new [] { ETimeFrame.Min1, ETimeFrame.Hour1 }; Model = model; m_send = send; m_quit = quit; m_now = new DateTime(2000, 1, 1, 0, 0, 0).Ticks; m_rng = new Random(0); m_candle = new PriceCandle(m_now, 0, 0, 0, 0, 0, 0); m_price = 1.0; m_lock = new object(); m_thread = new Thread(Run) { Name = "{0} Transmitter".Fmt(SymbolCode) }; m_thread.SetApartmentState(ApartmentState.STA); m_thread.Start(); }
public void CloseOrderLimit() { double spread = 0.05; Dictionary <int, TradingOrder> OpenOrders0 = new Dictionary <int, TradingOrder>(); Dictionary <int, TradingOrder> OpenOrders1 = new Dictionary <int, TradingOrder>(); Dictionary <int, TradingOrder> OpenOrders2 = new Dictionary <int, TradingOrder>(); Dictionary <int, TradingOrder> OpenOrders3 = new Dictionary <int, TradingOrder>(); Dictionary <int, TradingOrder> OpenOrders4 = new Dictionary <int, TradingOrder>(); Dictionary <int, TradingOrder> OpenOrders5 = new Dictionary <int, TradingOrder>(); PriceCandle candle = new PriceCandle(DateTimeUTC.Now, TimeScale.Second1, 1, 1.2, 0.8, 1, spread); TradingOrder order_0 = new TradingOrder(TradingOrderType.Long, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 0.7, 1.1); OpenOrders0.Add(order_0.OrderTicket, order_0); TradingOrder order_1 = new TradingOrder(TradingOrderType.Long, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 0.9, 1.3); OpenOrders1.Add(order_0.OrderTicket, order_1); TradingOrder order_2 = new TradingOrder(TradingOrderType.Short, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 1.1, 0.7); OpenOrders2.Add(order_0.OrderTicket, order_2); TradingOrder order_3 = new TradingOrder(TradingOrderType.Short, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 1.3, 0.9); OpenOrders3.Add(order_0.OrderTicket, order_3); TradingOrder order_4 = new TradingOrder(TradingOrderType.Long, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 0.7, 1.3); OpenOrders4.Add(order_0.OrderTicket, order_4); TradingOrder order_5 = new TradingOrder(TradingOrderType.Short, 0, DateTimeUTC.Now, 1, 1, 0.01, true, 1.3, 0.7); OpenOrders5.Add(order_0.OrderTicket, order_5); Assert.AreEqual(1, MarketModelSimulation.CheckOrderLimits(OpenOrders0, candle).Count); Assert.AreEqual(1, MarketModelSimulation.CheckOrderLimits(OpenOrders1, candle).Count); Assert.AreEqual(1, MarketModelSimulation.CheckOrderLimits(OpenOrders2, candle).Count); Assert.AreEqual(1, MarketModelSimulation.CheckOrderLimits(OpenOrders3, candle).Count); Assert.AreEqual(0, MarketModelSimulation.CheckOrderLimits(OpenOrders4, candle).Count); Assert.AreEqual(0, MarketModelSimulation.CheckOrderLimits(OpenOrders5, candle).Count); }
/// <summary>Send market data</summary> private void SendMarketData(MarketSeriesData data) { // Get the latest symbol (price data) information var sym = Symbol; if (sym == null) { return; } // Collect additional stats AverageSpread.Add(Math.Abs(sym.Bid - sym.Ask)); // Post at least every X seconds, changed or not var post = DateTimeOffset.UtcNow - data.LastUpdateUTC > TimeSpan.FromSeconds(10); // Post the symbol price data var price_data = new PriceData( sym.Ask, sym.Bid, AverageSpread.Mean, sym.LotSize, sym.PipSize, sym.PipValue, sym.VolumeMin, sym.VolumeStep, sym.VolumeMax); // Only transmit if different if (post || !price_data.Equals(data.LastTransmittedPriceData)) { if (Model.Post(new InMsg.SymbolData(sym.Code, price_data))) { data.LastTransmittedPriceData = price_data; post = true; } } // Post the latest candle data if (data.Series.Close.Count != 0) { var candle = new PriceCandle( data.Series.OpenTime.LastValue.Ticks, data.Series.Open.LastValue, data.Series.High.LastValue, data.Series.Low.LastValue, data.Series.Close.LastValue, data.Series.Median.LastValue, data.Series.TickVolume.LastValue); // Only transmit if different if (post || !candle.Equals(data.LastTransmittedCandle)) { if (Model.Post(new InMsg.CandleData(sym.Code, data.Series.TimeFrame.ToTradeeTimeframe(), candle))) { data.LastTransmittedCandle = candle; post = true; } } } // Record this update attempt data.LastUpdateUTC = DateTimeOffset.UtcNow; data.LastTransmitUTC = post ? DateTimeOffset.UtcNow : data.LastTransmitUTC; }
public Candle(PriceCandle rhs) : base(rhs) { }
/// <summary>Add a candle value to the data</summary> public void Add(ETimeFrame tf, PriceCandle price_candle) { // Sanity check var candle = new Candle(price_candle); Debug.Assert(candle.Valid()); Debug.Assert(candle.Timestamp != 0); Debug.Assert(tf != ETimeFrame.None); // If this candle is the newest we've seen, then a new candle has started. // Get the latest candle before inserting 'candle' into the database var new_candle = tf == TimeFrame && candle.Timestamp > Latest.Timestamp; // Insert the candle into the database if the sim isn't running. // The sim draws it's data from the database, so there's no point in writing // the same data back in. Plus it might in the future do things to emulate sub-candle // updates, which I don't want to overwrite the actual data. if (!Model.SimActive) { m_db.Execute(SqlExpr.InsertCandle(tf), 1, SqlExpr.InsertCandleParams(candle)); } // If the candle is for the current time frame and within the // cached data range, update the cache to avoid invalidating it. if (tf == TimeFrame) { // Within the currently cached data? // Note: this is false if 'candle' is the start of a new candle if (!new_candle) { // Find the index in the cache for 'candle'. If not an existing cache item, then just reset the cache var cache_idx = m_cache.BinarySearch(x => x.Timestamp.CompareTo(candle.Timestamp)); if (cache_idx >= 0) { m_cache[cache_idx].Update(candle); } else { InvalidateCachedData(); } } // If the cached range ends at the latest candle (excluding the new candle) // then we can preserve the cache and append the new candle to the cache data else if (m_index_range.Endi == Count) { // If adding 'candle' will make the cache too big, just flush if (m_cache.Count > MaxCacheSize) { InvalidateCachedData(); } // Otherwise, append the new candle to the cache else { m_cache.Add(candle); m_index_range.End++; m_impl_count = null; m_impl_total = null; m_latest = null; } } // Otherwise the candle is not within the cache, just invalidate else { InvalidateCachedData(); } } // Record the last time data was received LastUpdatedUTC = Model.UtcNow; // Notify data added/changed OnDataChanged(new DataEventArgs(this, tf, candle, new_candle)); }