コード例 #1
0
        public void ストアに登録済みのデータが存在する場合に終了時刻のみを指定してフェッチするとプロバイダーからデータを取得しない()
        {
            var symbol  = new TradingSymbol("USD_JPY");
            var range   = ChartRange.Daily;
            var chart   = new CandleChart(symbol, range);
            var from    = new DateTime(2017, 12, 1, 0, 0, 0, DateTimeKind.Utc);
            var to      = from.AddDays(10);
            var candles = Seeds.CreateRomdomCandles(from, to, range);

            // プロバイダーのセットアップ
            var provider = new MockCandleProvider();

            provider.SetCandle(range, candles);

            // ストアは空
            using (var store = new CandleChartStore(new DbContextOptionsBuilder()
                                                    .UseInMemoryDatabase("CandleChartUpdaterTestDb4")
                                                    .Options))
            {
                // ストアに保存
                var entry = store.FindOrCreateEntry(symbol, range);
                store.AddCandles(entry, from, to, candles.ToArray());
                var chartUpdater = new CandleChartUpdater(chart, store, provider);
                chartUpdater.Update(from, 1);
                chartUpdater.Update(to);

                Assert.AreEqual(11, store.Candles.Count());
                Assert.IsFalse(provider.ProvidedCandles.Any());
            }
        }
コード例 #2
0
        public void キャンドルマネージャーに2件のキャンドルを設定して更新した場合にキャンドルが正しく更新される()
        {
            var sut = new CandleChartManager(current, (s, r) => mockProvider, store);

            var symbol1 = new TradingSymbol("USD_JPY");
            var range1  = ChartRange.Daily;
            var chart1  = sut.GetChart(symbol1, range1);

            chart1.AddIndicator("SMA5", new SmaIndicator(5));
            chart1.AddIndicator("SMA10", new SmaIndicator(10));
            chart1.AddIndicator("SMA20", new SmaIndicator(20));
            chart1.AddIndicator("SMA60", new SmaIndicator(60));
            chart1.AddIndicator("SMA120", new SmaIndicator(120));

            var symbol2 = new TradingSymbol("EUR_USD");
            var range2  = ChartRange.Daily;
            var chart2  = sut.GetChart(symbol2, range2);

            chart2.AddIndicator("SMA5", new SmaIndicator(5));
            chart2.AddIndicator("SMA10", new SmaIndicator(10));
            chart2.AddIndicator("SMA20", new SmaIndicator(20));
            chart2.AddIndicator("SMA60", new SmaIndicator(60));
            chart2.AddIndicator("SMA120", new SmaIndicator(120));

            var snapshotBeforeUpdate1 = chart1.Snapshot;
            var snapshotBeforeUpdate2 = chart2.Snapshot;

            sut.Update(to);
            var snapshotAfterUpdate1 = chart1.Snapshot;
            var snapshotAfterUpdate2 = chart2.Snapshot;

            Assert.IsTrue(snapshotBeforeUpdate1.Candles.Last().Time < snapshotAfterUpdate1.Candles.Last().Time);
            Assert.IsTrue(snapshotBeforeUpdate2.Candles.Last().Time < snapshotAfterUpdate2.Candles.Last().Time);
        }
コード例 #3
0
        public Candle[] GetCandles(TradingSymbol symbol, ChartRange range, DateTime to, int count)
        {
            var granularity = ConvertGranurality(range);
            var task        = apiEndpoint.GetBidAskCandles(symbol.Symbol, granularity: granularity, count: count, end: to, includeFirst: true);

            return(task.Result.Select(oandaCandle => new Candle(oandaCandle.Time, oandaCandle.OpenAsk, oandaCandle.HighAsk, oandaCandle.LowAsk, oandaCandle.CloseAsk, oandaCandle.Volume)).ToArray());
        }
コード例 #4
0
        public PriceSet GetPrices(TradingSymbol symbol, int year, int month)
        {
            int    price_set_index     = GetPriceSetIndex(year, month);
            string price_set_file_path = GetPriceSetFilePath(symbol, year, month);

            if (!data_loaded.ContainsKey(symbol))
            {
                data_loaded[symbol] = new Dictionary <int, PriceSet>();
            }

            if (data_loaded[symbol].ContainsKey(price_set_index))
            {
                return(data_loaded[symbol][price_set_index]);
            }
            else
            {
                if (File.Exists(price_set_file_path))
                {
                    data_loaded[symbol][price_set_index] = PriceSet.Read(new BinaryReader(File.Open(price_set_file_path, FileMode.Open)));
                }
                else
                {
                    data_loaded[symbol][price_set_index] = new PriceSet(symbol, new DateTimeUTC(year, month, 1), new DateTimeUTC(year, month + 1, 1));
                }


                return(data_loaded[symbol][price_set_index]);
            }
        }
コード例 #5
0
ファイル: ToolsPrice.cs プロジェクト: kozzion/KozzionTrading
        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);
            }
        }
コード例 #6
0
        public void SavePrices(TradingSymbol symbol, int year, int month)
        {
            int    price_set_index     = GetPriceSetIndex(year, month);
            string price_set_file_path = GetPriceSetFilePath(symbol, year, month);

            if (!data_loaded.ContainsKey(symbol))
            {
                throw new Exception("Cant save this data");
            }

            if (!data_loaded[symbol].ContainsKey(price_set_index))
            {
                throw new Exception("Cant save unloaded data");
            }

            if (!Directory.GetParent(price_set_file_path).Exists)
            {
                Directory.CreateDirectory(Directory.GetParent(price_set_file_path).ToString());
            }

            using (BinaryWriter writer = new BinaryWriter(File.Open(price_set_file_path, FileMode.OpenOrCreate)))
            {
                data_loaded[symbol][price_set_index].Write(writer);
            }
        }
コード例 #7
0
        public static ICandleProvider GetInstance(TradingSymbol symbol)
        {
            if (factories.TryGetValue(symbol, out var factory))
            {
                return(factory.Invoke());
            }

            throw new ArgumentException($"provider for {symbol.Symbol} is not registered.");
        }
コード例 #8
0
 public Candle[] GetCandles(TradingSymbol symbol, ChartRange range, DateTime from, DateTime to)
 {
     if (candles.TryGetValue(range, out var value))
     {
         var providingCandles = value.Where(c => c.Time >= from && c.Time <= to).ToArray();
         ProvidedCandles.AddRange(providingCandles);
         return(providingCandles);
     }
     return(Array.Empty <Candle>());
 }
コード例 #9
0
 public CandleChart(TradingSymbol symbol, ChartRange range, Candle[] candles)
 {
     foreach (var candle in candles)
     {
         latestCandle = candle;
         store.Enqueue(candle);
     }
     this.symbol = symbol;
     this.range  = range;
     updateSnapshot();
 }
コード例 #10
0
 public SymbolDataServiceEventArgs(string symbol)
 {
     if (!Market.Instance.Symbols.TryGetValue(symbol, out TradingSymbol found))
     {
         throw new KeyNotFoundException($"The market does not contain the trading symbol {symbol}.");
     }
     else
     {
         Symbol = found;
     }
 }
コード例 #11
0
 public SymbolChangedEventArgs(string symbol, string oldSymbol) : base(symbol)
 {
     if (!Market.Instance.Symbols.TryGetValue(oldSymbol, out TradingSymbol found))
     {
         throw new KeyNotFoundException($"The market does not contain the trading symbol {symbol}.");
     }
     else
     {
         OldSymbol = found;
     }
 }
コード例 #12
0
        public PriceSet GetPrices(TradingSymbol symbol, DateTimeUTC lower_inclusive, DateTimeUTC upper_exclusive)
        {
            List <PriceSet> month_price_set_list = new List <PriceSet>();
            //Move through months
            DateTimeUTC initial_month = new DateTimeUTC(lower_inclusive.Year, lower_inclusive.Month, 1);
            int         year          = 0;
            int         month         = 0;
            PriceSet    price_set     = GetPrices(symbol, year, month);

            return(new PriceSet(month_price_set_list));// new PriceSet(List<PriceSet> month_price_set_list)
        }
コード例 #13
0
        public void 事前に登録したキャンドルプロバイダーをシンボルを指定して取得できる()
        {
            var symbol = new TradingSymbol("USD_JPY");

            CandleProviderFactory.Register(symbol, () => new MockCandleProvider());

            var sut = CandleProviderFactory.GetInstance(symbol);

            Assert.IsNotNull(sut);
            Assert.AreEqual("MockCandleProvider", sut.GetType().Name);
        }
コード例 #14
0
        public void チャートにキャンドルを読み込むとストアに登録される()
        {
            var date   = DateTime.Now;
            var symbol = new TradingSymbol("USD_JPY");
            var chart  = new CandleChart(symbol, ChartRange.Hourly);

            chart.AddCandle(new Candle(date, 0, 48.70m, 47.79m, 48.16m, 0));

            var snapshot = chart.Snapshot;

            Assert.AreEqual(date, snapshot.Candles.First().Time);
        }
コード例 #15
0
        public void OANDAサーバーよりキャンドルが取得できる()
        {
            var symbol = new TradingSymbol("USD_JPY");
            var from   = new DateTime(2017, 1, 1, 1, 0, 0, DateTimeKind.Utc);
            var to     = new DateTime(2017, 1, 1, 10, 0, 0, DateTimeKind.Utc);
            var range  = ChartRange.Hourly;

            var oandaApi = new OandaApi(_server.BaseUri, _server.DefaultAccessToken);
            var sut      = new OandaCandleProvider(oandaApi);
            var candles  = sut.GetCandles(symbol, range, from, to);

            Assert.AreEqual(10, candles.Length);
        }
コード例 #16
0
 public Candle[] GetCandles(TradingSymbol symbol, ChartRange range, DateTime to, int count)
 {
     if (candles.TryGetValue(range, out var value))
     {
         var providingCandles = value.Where(c => c.Time <= to)
                                .OrderByDescending(c => c.Time)
                                .Take(count)
                                .OrderBy(c => c.Time)
                                .ToArray();
         ProvidedCandles.AddRange(providingCandles);
         return(providingCandles);
     }
     return(Array.Empty <Candle>());
 }
コード例 #17
0
        public ChartEntryEntity FindOrCreateEntry(TradingSymbol symbol, ChartRange range)
        {
            var entry = ChartEntries.Where(ce => ce.Symbol == symbol.Symbol && ce.Range == range).FirstOrDefault();

            if (entry == null)
            {
                entry = new ChartEntryEntity()
                {
                    Symbol = symbol.Symbol,
                    Range  = range,
                };
                ChartEntries.AddAsync(entry);
                SaveChangesAsync();
            }
            return(entry);
        }
コード例 #18
0
ファイル: ToolsPrice.cs プロジェクト: kozzion/KozzionTrading
        public static List <PriceCandle> GetPriceCandles(TradingSymbol trading_symbol, TimeScale time_scale, DateTime start_inclusive, DateTime end_exclusive)
        {
            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);
            }

            return(ToolsIOSerialization.SerializeFromFile <List <PriceCandle> >(files[0]));
        }
コード例 #19
0
        public void データ登録済みのストアを指定してチャートを生成しインジケータを追加しインジケータが計算済みであること()
        {
            var date   = DateTime.Now;
            var symbol = new TradingSymbol("USD_JPY");

            var chart = new CandleChart(symbol, ChartRange.Hourly, Seeds.ATR14_CANDLES.Item1);

            chart.AddIndicator("ATR14", new AtrIndicator(14));

            var snapshot = chart.Snapshot;

            CollectionAssert.AreEqual(
                Seeds.ATR14_CANDLES.Item2.Where(sv => sv != null).Select(sv => sv.Value).ToArray(),
                snapshot.Plot <SingleValue>("ATR14").Select(sv => Math.Round(sv.Value, 4)).ToArray()
                );
        }
コード例 #20
0
        public void OANDAよりデータを取得してチャートが更新されることを確認する()
        {
            // 前提条件:
            // トレードをするクラスはチャートが常に勝手に最新に更新されていること
            // を想定して同期的にアクセス可能
            // データを取得する単位はシンボル・チャートの足単位とする
            // (TODO: 最適化できれば複数のシンボル・チャート足を同時に取得したいけど、
            // OANDA的に難しそうなのでとりあえず...分足から日足を生成するとか
            // -> ちなみに↑の最適化したい理由はリクエストが発生すると遅いから)
            //
            // 1. 更新スケジュールを作り、タイミングでトリガーを発生
            // 2. トリガーでプロバイダよりデータを取得する
            // 3. プロバイダがデータを取得出来たらデータストアを更新
            // 4. データストアはチャートマネージャに通知を送信
            // 5. チャートマネージャは送られてきたデータによってチャートを更新する
            // 6. スレッドセーフになるように頑張る

            var symbol = new TradingSymbol("USD_JPY");
            var range  = ChartRange.Daily;

            var from = new DateTime(2017, 12, 1, 0, 0, 0, DateTimeKind.Utc);
            var to   = new DateTime(2017, 12, 1, 0, 2, 0, DateTimeKind.Utc);

            var apiEndpoint = new OandaApi(_server.BaseUri, _server.DefaultAccessToken);
            var provider    = new OandaCandleProvider(apiEndpoint) as ICandleProvider;

            var chartManager = new CandleChartManager(from, (s, r) => provider);

            var chart = chartManager.GetChart(symbol, range);

            // この時点で100件分のチャートが取得済み
            chart.AddIndicator("SMA10", new SmaIndicator(10));
            var snapshot1 = chart.Snapshot;

            Assert.AreEqual(100, snapshot1.Candles.Length);
            Assert.AreEqual(100, snapshot1.Plot <SingleValue>("SMA10").Length);

            // これでチャートが更新される
            chartManager.Update(to);
            var snapshot2 = chart.Snapshot;

            Assert.AreEqual(100, snapshot2.Candles.Length);
            Assert.AreEqual(100, snapshot2.Plot <SingleValue>("SMA10").Length);

            // SNAPSHOT1とSNAPSHOT2のインスタンスが異なることを確認
            Assert.AreNotSame(snapshot1, snapshot2);
        }
コード例 #21
0
        private PriceSet ImportSecondData(string file_path)
        {
            string        symbol         = Path.GetFileName(file_path).Substring(0, 6);
            TradingSymbol trading_symbol = new TradingSymbol("TradersWay", "MT4.VAR.DEMO", symbol, "The one we mine on the VM");
            List <Price>  price_list     = new List <Price>();

            string[,] table = ToolsIOCSV.ReadCSVFile(file_path);
            for (int index_0 = 0; index_0 < table.GetLength(0); index_0++)
            {
                //TODO duplicate date_times can exist both on the server and on the client
                DateTimeUTC date_time = ToolsTime.UnixTimeStampToDateTimeUTC(int.Parse(table[index_0, 0]));
                double      bid       = double.Parse(table[index_0, 2], CultureInfo.InvariantCulture);
                double      ask       = double.Parse(table[index_0, 3], CultureInfo.InvariantCulture);
                price_list.Add(new Price(date_time, bid, ask));
            }

            return(new PriceSet(trading_symbol, price_list));
        }
コード例 #22
0
ファイル: ToolsPrice.cs プロジェクト: kozzion/KozzionTrading
        public static PriceSet GetPriceSet(TradingSymbol trading_symbol)
        {
            string data_path = Path.Combine(binary_data_root_path, trading_symbol.Broker, trading_symbol.Account, trading_symbol.Symbol);

            if (!Directory.Exists(data_path))
            {
                throw new Exception("No data for trading symbol: " + trading_symbol);
            }
            string[] files = Directory.GetFiles(data_path);
            if (files.Length != 1)
            {
                throw new Exception("No unique data for trading symbol: " + trading_symbol);
            }

            using (BinaryReader reader = new BinaryReader(new FileStream(files[0], FileMode.Open)))
            {
                return(PriceSet.Read(reader));
            }
        }
コード例 #23
0
ファイル: ToolsPrice.cs プロジェクト: kozzion/KozzionTrading
        public static IReadOnlyList <Price> GetPriceList(TradingSymbol trading_symbol)
        {
            string file_path = Path.Combine(binary_data_root_path, trading_symbol.Broker, trading_symbol.Account, trading_symbol.Symbol, "Prices.bin");

            if (!File.Exists(file_path))
            {
                throw new Exception("No data for trading symbol: " + trading_symbol);
            }
            using (BinaryReader reader = new BinaryReader(new FileStream(file_path, FileMode.Open)))
            {
                int          count      = reader.ReadInt32();
                List <Price> price_list = new List <Price>(count);
                for (int candle_index = 0; candle_index < count; candle_index++)
                {
                    price_list.Add(Price.Read(reader));
                }
                return(price_list);
            }
        }
コード例 #24
0
        public CandleChart GetChart(TradingSymbol symbol, ChartRange range)
        {
            var chartKey = Tuple.Create(symbol, range);

            if (charts.TryGetValue(chartKey, out var chartAndUpdater))
            {
                return(chartAndUpdater.Item1);
            }

            var provider = candleProviderFactory(symbol, range);
            var chart    = new CandleChart(symbol, range);
            var updater  = new CandleChartUpdater(chart, store, provider);

            charts.Add(chartKey, Tuple.Create(chart, updater));
            var now = currentTime;

            updater.Update(now, 100);
            return(chart);
        }
コード例 #25
0
ファイル: ToolsPrice.cs プロジェクト: kozzion/KozzionTrading
        public static void ComposeBinary(TradingSymbol trading_symbol)
        {
            string source_data_path = Path.Combine(source_data_root_path, trading_symbol.Broker, trading_symbol.Account, trading_symbol.Symbol);
            string target_data_path = Path.Combine(binary_data_root_path, trading_symbol.Broker, trading_symbol.Account, trading_symbol.Symbol);

            if (!Directory.Exists(source_data_path))
            {
                throw new Exception("No data for trading symbol: " + trading_symbol);
            }
            string[] files = Directory.GetFiles(source_data_path);
            if (files.Length == 0)
            {
                throw new Exception("No data for trading symbol: " + trading_symbol);
            }
            Array.Sort(files);

            List <Price> price_list = new List <Price>();

            foreach (string file in files)
            {
                AddFileToPriceList(price_list, file);
            }
            PriceSet    price_set       = new PriceSet(ToolsPrice.DefaultSymbolGBPUSD, price_list);
            DateTimeUTC date_time_first = price_set.OpenDateTime;
            DateTimeUTC date_time_last  = price_set.CloseDateTime;

            target_data_path = Path.Combine(target_data_path, date_time_first.ToString("yyyyMMddHHmmss") + "_" + date_time_last.ToString("yyyyMMddHHmmss") + ".blb");

            string target_data_path_dir = Path.GetDirectoryName(target_data_path);

            if (!Directory.Exists(target_data_path_dir))
            {
                Directory.CreateDirectory(target_data_path_dir);
            }

            using (BinaryWriter writer = new BinaryWriter(new FileStream(target_data_path, FileMode.Create)))
            {
                price_set.Write(writer);
            }
        }
コード例 #26
0
        public void チャートにATRを設定しキャンドルを読み込むと自動的にATRが計算される()
        {
            var symbol = new TradingSymbol("USD_JPY");
            var chart  = new CandleChart(symbol, ChartRange.Hourly);

            chart.AddIndicator("ATR14", new AtrIndicator(14));
            chart.AddCandles(Seeds.ATR14_CANDLES.Item1);

            var snapshot = chart.Snapshot;
            var values   = snapshot.Plot <SingleValue>("ATR14");
            var i        = 0;

            foreach (var val in Seeds.ATR14_CANDLES.Item2)
            {
                if (val != null)
                {
                    var plot = values[i++];
                    Assert.AreEqual(val.Time, plot.Time);
                    Assert.AreEqual(val.Value, Math.Round(plot.Value, 4));
                }
            }
        }
コード例 #27
0
        public void チャートに保持するインジケータの計算結果が最大100件までとなる()
        {
            var date   = DateTime.Now;
            var symbol = new TradingSymbol("USD_JPY");

            var chart = new CandleChart(symbol, ChartRange.Hourly);

            chart.AddIndicator("SMA5", new SmaIndicator(5));

            Enumerable.Range(1, 100).ToList()
            .ForEach(i =>
            {
                chart.AddCandle(new Candle(date.AddDays(i), i, i, i, i, i));
                var snapshot1 = chart.Snapshot;
                Assert.AreEqual(i, snapshot1.Plot <SingleValue>("SMA5").Length);
            });

            chart.AddCandle(new Candle(date.AddDays(101), 101, 101, 101, 101, 101));
            var snapshot2 = chart.Snapshot;

            Assert.AreEqual(100, snapshot2.Candles.Length);
            Assert.AreEqual(100, snapshot2.Plot <SingleValue>("SMA5").Length);
        }
コード例 #28
0
        public void ストアにデータが存在しない場合に取得数を指定してフェッチするとプロバイダーからデータを取得する()
        {
            var symbol  = new TradingSymbol("USD_JPY");
            var range   = ChartRange.Daily;
            var chart   = new CandleChart(symbol, range);
            var to      = new DateTime(2017, 12, 10, 0, 0, 0, DateTimeKind.Utc);
            var candles = Seeds.CreateRomdomCandles(to.AddDays(-20), to, range);

            // プロバイダーのセットアップ
            var provider = new MockCandleProvider();

            provider.SetCandle(range, candles);

            // ストアは空
            using (var store = new CandleChartStore(new DbContextOptionsBuilder()
                                                    .UseInMemoryDatabase("CandleChartUpdaterTestDb1")
                                                    .Options))
            {
                var chartUpdater = new CandleChartUpdater(chart, store, provider);
                chartUpdater.Update(to, 10);

                Assert.AreEqual(10, store.Candles.Count());
            }
        }
コード例 #29
0
 private string GetPriceSetFilePath(TradingSymbol symbol, int year, int month)
 {
     return(Path.Combine(database_path, symbol.ToString(), year + month.ToString("00") + ".dat"));
 }
コード例 #30
0
 public SymbolChangedEventArgs(TradingSymbol symbol, TradingSymbol oldSymbol) : base(symbol)
 {
     OldSymbol = OldSymbol;
 }