public SnRLevel(double price, double width_in_pips, ETimeFrame max_time_frame = ETimeFrame.Monthly) { Id = Guid.NewGuid(); Price = price; WidthPips = width_in_pips; MaxTimeFrame = max_time_frame; }
/// <summary>Convert Tradee time frames to CAlgo time frames (Returns null for no corresponding value)</summary> public static TimeFrame ToCAlgoTimeframe(this ETimeFrame tf) { switch (tf) { default: return(null); case ETimeFrame.Min1: return(TimeFrame.Minute); case ETimeFrame.Min2: return(TimeFrame.Minute2); case ETimeFrame.Min3: return(TimeFrame.Minute3); case ETimeFrame.Min4: return(TimeFrame.Minute4); case ETimeFrame.Min5: return(TimeFrame.Minute5); case ETimeFrame.Min6: return(TimeFrame.Minute6); case ETimeFrame.Min7: return(TimeFrame.Minute7); case ETimeFrame.Min8: return(TimeFrame.Minute8); case ETimeFrame.Min9: return(TimeFrame.Minute9); case ETimeFrame.Min10: return(TimeFrame.Minute10); case ETimeFrame.Min15: return(TimeFrame.Minute15); case ETimeFrame.Min20: return(TimeFrame.Minute20); case ETimeFrame.Min30: return(TimeFrame.Minute30); case ETimeFrame.Min45: return(TimeFrame.Minute45); case ETimeFrame.Hour1: return(TimeFrame.Hour); case ETimeFrame.Hour2: return(TimeFrame.Hour2); case ETimeFrame.Hour3: return(TimeFrame.Hour3); case ETimeFrame.Hour4: return(TimeFrame.Hour4); case ETimeFrame.Hour6: return(TimeFrame.Hour6); case ETimeFrame.Hour8: return(TimeFrame.Hour8); case ETimeFrame.Hour12: return(TimeFrame.Hour12); case ETimeFrame.Day1: return(TimeFrame.Daily); case ETimeFrame.Day2: return(TimeFrame.Day2); case ETimeFrame.Day3: return(TimeFrame.Day3); case ETimeFrame.Weekly: return(TimeFrame.Weekly); case ETimeFrame.Monthly: return(TimeFrame.Monthly); } }
public Transmitter(string sym, string db_filepath) { SymbolCode = sym; TimeFrames = new ETimeFrame[0]; // Load the instrument candle database m_db = new Sqlite.Database(db_filepath, Sqlite.OpenFlags.ReadOnly); // Read the price data PriceData = m_db.EnumRows <PriceData>("select * from PriceData").First(); }
/// <summary>Return the chart data for a given pair, over a given time range</summary> protected override Task <List <Candle> > CandleDataInternal(TradePair pair, ETimeFrame timeframe, UnixSec time_beg, UnixSec time_end, CancellationToken?cancel) // Worker thread context { // Get the chart data var cp = new CurrencyPair(pair.Base, pair.Quote); var data = Api.CandleData[cp, ToMarketPeriod(timeframe), time_beg, time_end, cancel]; //var data = await Api.GetChartData(cp, ToMarketPeriod(timeframe), time_beg, time_end, cancel); // Convert it to candles var candles = data.Select(x => new Candle(x.Time.Ticks, x.Open, x.High, x.Low, x.Close, x.Median, x.Volume)).ToList(); return(Task.FromResult(candles)); }
/// <summary>Create a table of candles for a time frame</summary> public static string CandleTable(ETimeFrame time_frame) { return(Str.Build( "create table if not exists ", time_frame, " (\n", "[", nameof(Candle.Timestamp), "] integer unique,\n", "[", nameof(Candle.Open), "] real,\n", "[", nameof(Candle.High), "] real,\n", "[", nameof(Candle.Low), "] real,\n", "[", nameof(Candle.Close), "] real,\n", "[", nameof(Candle.Median), "] real,\n", "[", nameof(Candle.Volume), "] real)" )); }
/// <summary>Convert a time frame to the nearest market period</summary> private EMarketPeriod ToMarketPeriod(ETimeFrame tf) { switch (tf) { default: return(EMarketPeriod.None); case ETimeFrame.Tick1: case ETimeFrame.Min1: case ETimeFrame.Min2: case ETimeFrame.Min3: case ETimeFrame.Min4: case ETimeFrame.Min5: case ETimeFrame.Min6: case ETimeFrame.Min7: case ETimeFrame.Min8: case ETimeFrame.Min9: return(EMarketPeriod.Minutes5); case ETimeFrame.Min10: case ETimeFrame.Min15: return(EMarketPeriod.Minutes15); case ETimeFrame.Min20: case ETimeFrame.Min30: case ETimeFrame.Min45: return(EMarketPeriod.Minutes30); case ETimeFrame.Hour1: case ETimeFrame.Hour2: return(EMarketPeriod.Hours2); case ETimeFrame.Hour3: case ETimeFrame.Hour4: case ETimeFrame.Hour6: case ETimeFrame.Hour8: return(EMarketPeriod.Hours4); case ETimeFrame.Hour12: case ETimeFrame.Day1: case ETimeFrame.Day2: case ETimeFrame.Day3: case ETimeFrame.Week1: case ETimeFrame.Week2: case ETimeFrame.Month1: return(EMarketPeriod.Day); } }
public CSVQuotes Download(string ticker, DateTime from, DateTime to, ETimeFrame tf = ETimeFrame.Daily, bool header = true) { CSVQuotes result = null; string secFrom = ((int)(from - DateTime.Parse("1970/01/01")).TotalSeconds).ToString(); string secTo = ((int)(to - DateTime.Parse("1970/01/01")).TotalSeconds).ToString(); string url = string.Format(_baseUrl, ticker, secFrom, secTo, (tf == ETimeFrame.Daily ? "1d" : tf == ETimeFrame.Weekly ? "1wk" : "1mo")); int attempt = 0; while (attempt < _attempts && result == null) { try { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { string text = sr.ReadToEnd(); if (!string.IsNullOrEmpty(resp.Headers["Content-disposition"]) && resp.Headers["Content-disposition"].Contains("error")) { throw new InvalidOperationException(text); } result = new CSVQuotes(); result.Ticker = ticker.ToUpper(); result.Quotes = ParseCSV(text, header); } } catch (Exception ex) { ++attempt; System.Threading.Thread.Sleep(_attemptDelaySec * 1000); } } return(result); }
/// <summary>Return the time frame value from 'available' that is nearest to 'wanted'</summary> public static ETimeFrame Nearest(ETimeFrame wanted, IEnumerable <ETimeFrame> available) { var nearest = int.MaxValue; var closest = ETimeFrame.None; foreach (var tf in available) { var dist = Math.Abs((int)tf - (int)wanted); if (dist > nearest) { continue; } nearest = dist; closest = tf; } return(closest); }
/// <summary>Generate simulated market depth for 'pair', using 'latest' as the reference for the current spot price</summary> private MarketDepth GenerateMarketDepth(TradePair pair, Candle latest, ETimeFrame time_frame) { // Notes: // - This is an expensive call when back testing is running so minimise allocation, resizing, and sorting. // - Do all calculations using double's for speed. // Get the market data for 'pair'. // Market data is maintained independently to the pair's market data instance because the // rest of the application expects the market data to periodically overwrite the pair's order books. var md = m_depth[pair]; // Get the Q2B (bid) spot price from the candle close. (This is the minimum of the Q2B offers) // The B2Q spot price is Q2B - spread, which will be the maximum of the B2Q offers var spread = latest.Close * m_spread_frac; var best_q2b = latest.Close; var best_b2q = latest.Close - spread; var base_value = (double)(decimal)pair.Base.Value; md.Q2B.Offers.Resize(m_orders_per_book); md.B2Q.Offers.Resize(m_orders_per_book); // Generate offers with a normal distribution about 'best' var range = 0.2 * 0.5 * (best_q2b + best_b2q); for (var i = 0; i != m_orders_per_book; ++i) { var p = range * Math_.Sqr((double)i / m_orders_per_book); md.Q2B.Offers[i] = new Offer(((decimal)(best_q2b + p))._(pair.RateUnits), RandomAmountBase()._(pair.Base)); md.B2Q.Offers[i] = new Offer(((decimal)(best_b2q - p))._(pair.RateUnits), RandomAmountBase()._(pair.Base)); } return(md); decimal RandomAmountBase() { // Generate an amount to trade in the application common currency (probably USD). // Then convert that to base currency using the 'live' value. var common_value = Math.Abs(m_rng.Double(m_order_value_range.Beg, m_order_value_range.End)); var amount_base = (decimal)Math_.Div(common_value, base_value, common_value); return(amount_base); } }
/// <summary>Insert or replace a candle in table 'time_frame'</summary> public static string InsertCandle(ETimeFrame time_frame) { return(Str.Build( "insert or replace into ", time_frame, " (", "[", nameof(Candle.Timestamp), "],", "[", nameof(Candle.Open), "],", "[", nameof(Candle.High), "],", "[", nameof(Candle.Low), "],", "[", nameof(Candle.Close), "],", "[", nameof(Candle.Median), "],", "[", nameof(Candle.Volume), "])", " values (", "?,", // Timestamp "?,", // Open "?,", // High "?,", // Low "?,", // Close "?,", // Median "?)" // Volume )); }
private DateTime ToPeriodStart(DateTime end, ETimeFrame timeFrame) { DateTime result = end; switch (timeFrame) { case ETimeFrame.Daily: result = end; break; case ETimeFrame.Weekly: throw new NotImplementedException(); break; case ETimeFrame.Monthly: result = new DateTime(end.Year, end.Month, 1); break; } return(result); }
/// <summary>Return the best matching price data for 'pair' and 'time_frame'</summary> public PriceData Find(string pair_name, ETimeFrame time_frame, string preferred_exchange = null) { if (pair_name == null) { throw new ArgumentNullException(nameof(pair_name)); } if (time_frame == ETimeFrame.None) { throw new Exception("TimeFrame is None. No price data available"); } // Search for pairs that match 'pair_name' var pairs = Pairs.Where(x => x.Key.Name == pair_name && x.Key.Exchange.Enabled).ToList(); if (pairs.Count == 0) { return(null); } // Look for price data from the preferred exchange if (preferred_exchange != null) { var pair = pairs.FirstOrDefault(x => x.Key.Exchange.Name == preferred_exchange); if (pair.Key != null && pair.Value.TryGetValue(time_frame, out var data)) { return(data); } } // Look for price data in any of the pairs foreach (var pair in pairs) { if (pair.Value.TryGetValue(time_frame, out var data)) { return(data); } } return(null); }
private List <CSVRecord> ParseCSV(string text, bool header, out ETimeFrame timeframe) { timeframe = ETimeFrame.Monthly; List <CSVRecord> result = new List <CSVRecord>(); string[] lines = text.Split(new char[] { '\r', '\n' }); bool headerSkipped = false; foreach (var line in lines) { if (header && !headerSkipped) { headerSkipped = true; } else { string[] vals = line.Trim().Split(new char[] { ',' }); if (vals.Count() >= 5) { DateTime dtStart, dtEnd; ETimeFrame tf; ToStartDate(vals[1], vals[2], out dtStart, out dtEnd, out tf); timeframe = tf; CSVRecord rec = new CSVRecord(); rec.PeriodStart = dtStart; rec.PeriodEnd = dtEnd; rec.Value = Decimal.Parse(vals[4]); result.Add(rec); } } } return(result); }
// Notes: // - PriceData represents a single pair and TimeFrame on an exchange. // - Handles adding new data to the DB. // - Serves data from the DB to the Instruments. // - Use an 'Instrument' to view these data public PriceData(TradePair pair, ETimeFrame time_frame, CancellationToken shutdown) { try { Pair = pair; TimeFrame = time_frame; DataAvailable = pair.CandleDataAvailable.Contains(time_frame); UpdatePollRate = TimeSpan.FromMilliseconds(SettingsData.Settings.PriceDataUpdatePeriodMS); MainShutdownToken = shutdown; // Set up the ref count m_ref = new List <object>(); // Load the database of historic price data var db_filepath = DBFilePath(pair.Exchange.Name, pair.Name); DB = new SQLiteConnection($"Data Source={db_filepath};Version=3;journal mode=Memory;synchronous=Off"); // Ensure a table exists for the time frame if (DataAvailable) { DB.Execute( $"create table if not exists {TimeFrame} (\n" + $" [{nameof(Candle.Timestamp)}] integer unique primary key,\n" + $" [{nameof(Candle.Open)}] real not null,\n" + $" [{nameof(Candle.High)}] real not null,\n" + $" [{nameof(Candle.Low)}] real not null,\n" + $" [{nameof(Candle.Close)}] real not null,\n" + $" [{nameof(Candle.Median)}] real not null,\n" + $" [{nameof(Candle.Volume)}] real not null\n" + $")"); } } catch { Dispose(); throw; } }
/// <summary>Return the price data for 'pair' and 'time_frame'</summary> public PriceData this[TradePair pair, ETimeFrame time_frame] { get { if (pair == null) { throw new ArgumentNullException(nameof(pair)); } if (time_frame == ETimeFrame.None) { throw new Exception("TimeFrame is None. No price data available"); } if (!pair.Exchange.Enabled) { throw new Exception("Requesting a trading pair on an inactive exchange"); } // Get the TimeFrame to PriceData map for the given pair var tf_map = Pairs.TryGetValue(pair, out var tf) ? tf : Pairs.Add2(pair, new TFMap()); // Get the price data for the given time frame return(tf_map.TryGetValue(time_frame, out var pd) ? pd : tf_map.Add2(time_frame, new PriceData(pair, time_frame, Shutdown))); } }
/// <summary>Add a batch of candles</summary> public void Add(ETimeFrame tf, PriceCandles candles) { // Insert the candles into the database using (var t = m_db.NewTransaction()) using (var query = new Sqlite.Query(m_db, SqlExpr.InsertCandle(tf))) { foreach (var candle in candles.AllCandles.Select(x => new Candle(x))) { query.Reset(); query.BindParms(1, SqlExpr.InsertCandleParams(candle)); query.Run(); } t.Commit(); } // Don't bother maintaining the cache, just invalidate it InvalidateCachedData(); // Record the last time data was received LastUpdatedUTC = Model.UtcNow; // Notify data added/changed DataChanged.Raise(this, new DataEventArgs(this, tf, null, false)); }
public static double TimeSpanToTimeFrame(TimeSpan ts, ETimeFrame time_frame) { return(TicksToTimeFrame(ts.Ticks, time_frame)); }
///// <summary>Convert a Bitfinex trade type to ETradeType</summary> //public static ETradeType TradeType(global::Bitfinex.API.EOrderType order_type) //{ // switch (order_type) // { // default: throw new Exception("Unknown trade type string"); // case global::Bitfinex.API.EOrderType.Buy: return ETradeType.Q2B; // case global::Bitfinex.API.EOrderType.Sell: return ETradeType.B2Q; // } //} /// <summary>Convert a time value into units of 'time_frame'. e.g if 'time_in_ticks' is 4.3 hours, and 'time_frame' is Hour1, the 4.3 is returned</summary> public static double TicksToTimeFrame(long time_in_ticks, ETimeFrame time_frame) { switch (time_frame) { default: throw new Exception("Unknown time frame"); case ETimeFrame.Tick1: return(new TimeSpan(time_in_ticks).TotalSeconds); case ETimeFrame.Min1: return(new TimeSpan(time_in_ticks).TotalMinutes); case ETimeFrame.Min2: return(new TimeSpan(time_in_ticks).TotalMinutes / 2.0); case ETimeFrame.Min3: return(new TimeSpan(time_in_ticks).TotalMinutes / 3.0); case ETimeFrame.Min4: return(new TimeSpan(time_in_ticks).TotalMinutes / 4.0); case ETimeFrame.Min5: return(new TimeSpan(time_in_ticks).TotalMinutes / 5.0); case ETimeFrame.Min6: return(new TimeSpan(time_in_ticks).TotalMinutes / 6.0); case ETimeFrame.Min7: return(new TimeSpan(time_in_ticks).TotalMinutes / 7.0); case ETimeFrame.Min8: return(new TimeSpan(time_in_ticks).TotalMinutes / 8.0); case ETimeFrame.Min9: return(new TimeSpan(time_in_ticks).TotalMinutes / 9.0); case ETimeFrame.Min10: return(new TimeSpan(time_in_ticks).TotalMinutes / 10.0); case ETimeFrame.Min15: return(new TimeSpan(time_in_ticks).TotalMinutes / 15.0); case ETimeFrame.Min20: return(new TimeSpan(time_in_ticks).TotalMinutes / 20.0); case ETimeFrame.Min30: return(new TimeSpan(time_in_ticks).TotalMinutes / 30.0); case ETimeFrame.Min45: return(new TimeSpan(time_in_ticks).TotalMinutes / 45.0); case ETimeFrame.Hour1: return(new TimeSpan(time_in_ticks).TotalHours); case ETimeFrame.Hour2: return(new TimeSpan(time_in_ticks).TotalHours / 2.0); case ETimeFrame.Hour3: return(new TimeSpan(time_in_ticks).TotalHours / 3.0); case ETimeFrame.Hour4: return(new TimeSpan(time_in_ticks).TotalHours / 4.0); case ETimeFrame.Hour6: return(new TimeSpan(time_in_ticks).TotalHours / 6.0); case ETimeFrame.Hour8: return(new TimeSpan(time_in_ticks).TotalHours / 8.0); case ETimeFrame.Hour12: return(new TimeSpan(time_in_ticks).TotalHours / 12.0); case ETimeFrame.Day1: return(new TimeSpan(time_in_ticks).TotalDays); case ETimeFrame.Day2: return(new TimeSpan(time_in_ticks).TotalDays / 2.0); case ETimeFrame.Day3: return(new TimeSpan(time_in_ticks).TotalDays / 3.0); case ETimeFrame.Week1: return(new TimeSpan(time_in_ticks).TotalDays / 7.0); case ETimeFrame.Week2: return(new TimeSpan(time_in_ticks).TotalDays / 14.0); case ETimeFrame.Month1: return(new TimeSpan(time_in_ticks).TotalDays / 30.0); } }
/// <summary>Add a candle value to the database</summary> private void Add(ETimeFrame tf, Candle candle) { // Sanity check Debug.Assert(candle.Valid()); Debug.Assert(candle.Timestamp != 0); Debug.Assert(tf != ETimeFrame.None); Debug.Assert(tf == TimeFrame); if (Model.BackTesting) { throw new Exception("Should not be adding candles to the DB while back testing"); } // This is a new candle if it's time stamp is one TimeFrame period after the Newest candle. // This is an update to the latest candle if within a TimeFrame period of the Newest candle. // Otherwise it's an unknown range. var tf_ticks = Misc.TimeFrameToTicks(1.0, TimeFrame); var update_type = Newest == null ? DataEventArgs.EUpdateType.Range : candle.Timestamp == Newest.Timestamp + tf_ticks ? DataEventArgs.EUpdateType.New : candle.Timestamp.Within(Newest.Timestamp, Newest.Timestamp + tf_ticks) ? DataEventArgs.EUpdateType.Current : DataEventArgs.EUpdateType.Range; // Insert the candle into the database UpsertCandle(candle); // Record the last time data was received LastUpdatedUTC = Model.UtcNow; // Update/Invalidate cached values switch (update_type) { case DataEventArgs.EUpdateType.New: { m_newest = candle; m_current = m_newest; m_total += 1; break; } case DataEventArgs.EUpdateType.Current: { m_newest.Update(candle); m_current = m_newest; break; } default: { // This must be an update to some random candle in the middle. // Just invalidate the cached values. Shouldn't ever happen really. m_total = null; m_newest = null; m_oldest = null; m_current = null; break; } } // Notify data added/changed OnDataChanged(new DataEventArgs(update_type, this, new RangeI(Count - 1, Count), candle)); }
public CSVQuotes Download(string ticker, DateTime from, DateTime to, string country = "US", ETimeFrame tf = ETimeFrame.Daily, bool header = true) { CSVQuotes result = null; string url = string.Format(_baseUrl, ticker, country, from.ToString("yyyyMMdd"), to.ToString("yyyyMMdd"), (tf == ETimeFrame.Daily ? "d" : tf == ETimeFrame.Weekly ? "w" : "m")); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { string text = sr.ReadToEnd(); if (!string.IsNullOrEmpty(resp.Headers["Content-disposition"]) && resp.Headers["Content-disposition"].Contains("error")) { throw new InvalidOperationException(text); } result = new CSVQuotes(); result.Ticker = ticker.ToUpper(); result.Quotes = ParseCSV(text, header); } return(result); }
/// <summary>Return this time value in a different time frame</summary> public TFTime To(ETimeFrame tf) { return(new TFTime(this, tf)); }
void ToStartDate(string year, string period, out DateTime periodStart, out DateTime periodEnd, out ETimeFrame timeframe) { string periodId = period.Substring(1, period.Length - 1); string periodType = period.Substring(0, 1); int nYear = Int32.Parse(year); int nPeriod = Int32.Parse(periodId); switch (periodType) { case "M": timeframe = ETimeFrame.Monthly; periodStart = new DateTime(nYear, nPeriod, 1); periodEnd = nPeriod < 12 ? new DateTime(nYear, nPeriod + 1, 1) - TimeSpan.FromDays(1) : new DateTime(nYear, 12, 31); break; case "Q": timeframe = ETimeFrame.Quarterly; periodStart = new DateTime(nYear, (nPeriod - 1) * 3 + 1, 1); periodEnd = nPeriod < 4 ? new DateTime(nYear, nPeriod * 3 + 1, 1) - TimeSpan.FromDays(1) : new DateTime(nYear, 12, 31); break; case "S": timeframe = ETimeFrame.SemiAnnual; periodStart = new DateTime(nYear, (nPeriod - 1) * 6 + 1, 1); periodEnd = nPeriod < 2 ? new DateTime(nYear, nPeriod * 6 + 1, 1) - TimeSpan.FromDays(1) : new DateTime(nYear, 12, 31); break; case "A": default: timeframe = ETimeFrame.Annual; periodStart = new DateTime(nYear, 1, 1); periodEnd = new DateTime(nYear, 12, 31); break; } }
/// <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)); }
public EErrorCodes GetTimeSeries(string country, string ticker, ETimeFrame timeframe, DateTime periodStart, DateTime periodEnd) { EErrorCodes result = EErrorCodes.GeneralError; try { if (SessionToken != null) { GetTimeSeries reqGetTs = new GetTimeSeries(); reqGetTs.Ticker = ticker; reqGetTs.CountryCode = country; reqGetTs.SessionToken = SessionToken; reqGetTs.PeriodStart = periodStart != DateTime.MinValue ? periodStart : DateTime.Parse("01/01/1970"); reqGetTs.PeriodEnd = periodEnd != DateTime.MinValue ? periodEnd : DateTime.Now; reqGetTs.TimeFrame = timeframe; GetTimeSeriesResponse resGetTs = Post <GetTimeSeries, GetTimeSeriesResponse>("/api/timeseries/GetTimeSeries", reqGetTs); if (resGetTs.Success) { // creating new records if needed IndicatorData indData = null; if (Indicators.TryGetValue(ticker, out indData)) { for (int i = 0; i < resGetTs.Payload.Values.Quotes.Count; ++i) { QuoteRecord rec = resGetTs.Payload.Values.Quotes[i]; for (int v = 0; v < rec.Values.Count; ++v) { String sTsName = indData.SeriesNames[v]; IndicatorSeriesData indTsData = null; if (indData.Series.TryGetValue(sTsName, out indTsData)) { indTsData.Values.Add( rec.Time, rec.Values[v] ); } } } result = EErrorCodes.Success; } else { result = EErrorCodes.TickerNotFound; } } else { _lastError = new Exception(resGetTs.Errors[0].Message); result = resGetTs.Errors[0].Code; } } else { return(EErrorCodes.SessionClosed); } } catch (Exception ex) { _lastError = ex; result = EErrorCodes.GeneralError; } return(result); }
///// <summary>Return the order book for 'pair' to a depth of 'count'</summary> //protected async override Task<MarketDepth> MarketDepthInternal(TradePair pair, int depth) // Worker thread context //{ // var cp = new CurrencyPair(pair.Base, pair.Quote); // var orders = await Api.GetOrderBook(cp, depth, cancel: Shutdown.Token); // // Update the depth of market data // var market_depth = new MarketDepth(pair.Base, pair.Quote); // var buys = orders.BuyOffers.Select(x => new Offer(x.Price._(pair.RateUnits), x.AmountBase._(pair.Base))).ToArray(); // var sells = orders.SellOffers.Select(x => new Offer(x.Price._(pair.RateUnits), x.AmountBase._(pair.Base))).ToArray(); // market_depth.UpdateOrderBooks(buys, sells); // return market_depth; //} /// <summary>Return the chart data for a given pair, over a given time range</summary> protected async override Task <List <Candle> > CandleDataInternal(TradePair pair, ETimeFrame timeframe, UnixSec time_beg, UnixSec time_end, CancellationToken?cancel) // Worker thread context { var cp = new CurrencyPair(pair.Base, pair.Quote); // Get the chart data var data = await Api.GetChartData(cp, ToMarketPeriod(timeframe), time_beg, time_end, cancel); // Convert it to candles (yes, Polo gets the base/quote backwards for 'Volume') var candles = data.Select(x => new Candle(x.Time.Ticks, x.Open, x.High, x.Low, x.Close, x.WeightedAverage, x.VolumeQuote)).ToList(); return(candles); }
/// <summary>Convert 'units' in 'time_frame' units to ticks. e.g. if 'units' is 4.3 hours, then TimeSpan.FromHours(4.3).Ticks is returned</summary> public static long TimeFrameToTicks(double units, ETimeFrame time_frame) { // Use 1 second for all tick time-frames switch (time_frame) { default: throw new Exception("Unknown time frame"); case ETimeFrame.Tick1: return(TimeSpan.FromSeconds(units).Ticks); case ETimeFrame.Min1: return(TimeSpan.FromMinutes(units).Ticks); case ETimeFrame.Min2: return(TimeSpan.FromMinutes(units * 2.0).Ticks); case ETimeFrame.Min3: return(TimeSpan.FromMinutes(units * 3.0).Ticks); case ETimeFrame.Min4: return(TimeSpan.FromMinutes(units * 4.0).Ticks); case ETimeFrame.Min5: return(TimeSpan.FromMinutes(units * 5.0).Ticks); case ETimeFrame.Min6: return(TimeSpan.FromMinutes(units * 6.0).Ticks); case ETimeFrame.Min7: return(TimeSpan.FromMinutes(units * 7.0).Ticks); case ETimeFrame.Min8: return(TimeSpan.FromMinutes(units * 8.0).Ticks); case ETimeFrame.Min9: return(TimeSpan.FromMinutes(units * 9.0).Ticks); case ETimeFrame.Min10: return(TimeSpan.FromMinutes(units * 10.0).Ticks); case ETimeFrame.Min15: return(TimeSpan.FromMinutes(units * 15.0).Ticks); case ETimeFrame.Min20: return(TimeSpan.FromMinutes(units * 20.0).Ticks); case ETimeFrame.Min30: return(TimeSpan.FromMinutes(units * 30.0).Ticks); case ETimeFrame.Min45: return(TimeSpan.FromMinutes(units * 45.0).Ticks); case ETimeFrame.Hour1: return(TimeSpan.FromHours(units).Ticks); case ETimeFrame.Hour2: return(TimeSpan.FromHours(units * 2.0).Ticks); case ETimeFrame.Hour3: return(TimeSpan.FromHours(units * 3.0).Ticks); case ETimeFrame.Hour4: return(TimeSpan.FromHours(units * 4.0).Ticks); case ETimeFrame.Hour6: return(TimeSpan.FromHours(units * 6.0).Ticks); case ETimeFrame.Hour8: return(TimeSpan.FromHours(units * 8.0).Ticks); case ETimeFrame.Hour12: return(TimeSpan.FromHours(units * 12.0).Ticks); case ETimeFrame.Day1: return(TimeSpan.FromDays(units).Ticks); case ETimeFrame.Day2: return(TimeSpan.FromDays(units * 2.0).Ticks); case ETimeFrame.Day3: return(TimeSpan.FromDays(units * 3.0).Ticks); case ETimeFrame.Week1: return(TimeSpan.FromDays(units * 7.0).Ticks); case ETimeFrame.Week2: return(TimeSpan.FromDays(units * 14.0).Ticks); case ETimeFrame.Month1: return(TimeSpan.FromDays(units * 30.0).Ticks); } }
public static TimeSpan TimeFrameToTimeSpan(double units, ETimeFrame time_frame) { return(TimeSpan.FromTicks(TimeFrameToTicks(units, time_frame))); }
public TFTime(TFTime tft, ETimeFrame tf) : this(tft.m_ticks, tf) { }
/// <summary>Return the end time for this candle given 'time_frame'</summary> public DateTimeOffset CloseTime(ETimeFrame time_frame) { return(TimestampUTC + Misc.TimeFrameToTimeSpan(1.0, time_frame)); }
public Instrument(Instrument rhs, ETimeFrame time_frame) : this(rhs.Model, rhs.SymbolCode) { TimeFrame = time_frame; }