| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- using MuchInfo.Chart.Data.EnumTypes;
- using MuchInfo.Chart.Data.Interfaces;
- using MuchInfo.Chart.Data.Models;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- namespace MuchInfo.Chart.DataAccess
- {
- /// <summary>
- /// 文件JSON存储
- /// </summary>
- public class FileDataAccess : IDataAccess
- {
- #region Methods
- #region Public Methods
- /// <summary>
- /// 获取数据
- /// </summary>
- /// <param name="symbol">商品代码</param>
- /// <param name="cycleType">周期类型</param>
- /// <param name="startTime">起始时间</param>
- /// <param name="endTime">结束时间</param>
- /// <param name="totalCount">记录条数</param>
- public IEnumerable<IBarDataPoint> GetDataPoints(string symbol, CycleType cycleType, DateTime startTime, DateTime endTime, int totalCount)
- {
- if (string.IsNullOrWhiteSpace(symbol)) return null;
- //周期为Nono,默认为Day
- var filePath = CombineFilePath(symbol, (cycleType == CycleType.None ? CycleType.Day : cycleType));
- if (!File.Exists(filePath)) return null;
- return GetDataPoints(filePath, startTime, endTime, totalCount);
- }
- /// <summary>
- /// 获取数据
- /// </summary>
- /// <param name="filePath">The file path.</param>
- /// <param name="startTime">起始时间</param>
- /// <param name="endTime">结束时间</param>
- /// <param name="totalCount">记录条数</param>
- /// <returns>IEnumerable{IBarDataPoint}.</returns>
- private IEnumerable<IBarDataPoint> GetDataPoints(string filePath, DateTime startTime, DateTime endTime, int totalCount)
- {
- try
- {
- IList<BarDataPoint> dataSoure;
- //获取数据
- using (StreamReader file = File.OpenText(filePath))
- {
- var serializer = new JsonSerializer();
- try
- {
- dataSoure = (IList<BarDataPoint>)serializer.Deserialize(file, typeof(IList<BarDataPoint>));
- }
- catch
- {
- return null;
- }
- }
- if (dataSoure == null || !dataSoure.Any()) return null;
- //记录条数小于零,默认取100条
- //返回数据按日间顺排序
- var count = totalCount <= 0 ? 100 : totalCount;
- if (startTime > endTime)
- {
- return dataSoure.Where(z => z.Date <= endTime)
- .OrderByDescending(z => z.Date)
- .Take(count).OrderBy(z => z.Date);
- }
- else
- {
- return dataSoure.Where(z => z.Date >= startTime && z.Date <= endTime)
- .OrderByDescending(z => z.Date)
- .Take(count).OrderBy(z => z.Date);
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 保存数据
- /// </summary>
- /// <param name="symbol">商品代码</param>
- /// <param name="cycleType">周期类型</param>
- /// <param name="dataPoints">保存的数据</param>
- /// <exception cref="System.NotImplementedException"></exception>
- public void SaveDataPoints(string symbol, CycleType cycleType, IList<IBarDataPoint> dataPoints)
- {
- if (string.IsNullOrWhiteSpace(symbol) ||
- cycleType == CycleType.None ||
- dataPoints == null) return;
- var filePath = CombineFilePath(symbol, cycleType);
- SaveDataPoints(filePath, dataPoints);
- }
- /// <summary>
- /// Saves the data points.
- /// </summary>
- /// <param name="filePath">The file path.</param>
- /// <param name="dataPoints">The data points.</param>
- private void SaveDataPoints(string filePath, IList<IBarDataPoint> dataPoints)
- {
- try
- {
- IList<IBarDataPoint> totalDataPoints;
- if (File.Exists(filePath))
- {
- //获取源数据
- IList<BarDataPoint> source;
- try
- {
- using (StreamReader file = File.OpenText(filePath))
- {
- var serializer = new JsonSerializer();
- source = (IList<BarDataPoint>)serializer.Deserialize(file, typeof(IList<BarDataPoint>));
- }
- }
- catch
- {
- //反序列化出错,删除源文件,重新写入目标数据
- source = new List<BarDataPoint>();
- File.Delete(filePath);
- }
- //合并数据
- totalDataPoints = CombineDataPoints(source == null ? null : source.ToList<IBarDataPoint>(), dataPoints).ToList();
- }
- else
- {
- totalDataPoints = dataPoints;
- var fileInfo = new FileInfo(filePath);
- //创建目录
- if (fileInfo.Directory != null && !Directory.Exists(fileInfo.Directory.FullName))
- {
- Directory.CreateDirectory(fileInfo.Directory.FullName);
- }
- }
- //写JSON数据
- using (var file = File.CreateText(filePath))
- {
- var serializer = new JsonSerializer();
- serializer.Serialize(file, totalDataPoints);
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion Public Methods
- #region Private Methods
- /// <summary>
- /// 合并数据
- /// </summary>
- /// <param name="source">源数据</param>
- /// <param name="destination">目标数据</param>
- private IEnumerable<IBarDataPoint> CombineDataPoints(IList<IBarDataPoint> source, IList<IBarDataPoint> destination)
- {
- if (source == null && destination == null) return new List<IBarDataPoint>();
- if (source == null || !source.Any()) return destination;
- if (destination == null || !destination.Any()) return source;
- //找出源中存的数据
- var interesct = destination.Intersect(source, new DataPointComparer<IBarDataPoint>()).ToList();
- //找出源数据中不存在的数据
- var except = destination.Except(source, new DataPointComparer<IBarDataPoint>()).ToList();
- //从源中移除要更新的数据
- //合并不存在的数据
- //合并更新的数据
- var result = source.Except(interesct, new DataPointComparer<IBarDataPoint>())
- .Union(except)
- .Union(interesct);
- return result;
- }
- /// <summary>
- /// 生成数据文件路径
- /// </summary>
- /// <param name="symbol">商品代码</param>
- /// <param name="cycleType">Type of the cycle.</param>
- /// <returns>System.String.</returns>
- private string CombineFilePath(string symbol, CycleType cycleType)
- {
- return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", symbol + "_" + cycleType.ToString() + ".txt");
- }
- private string CombineFilePath(string symbol, TimeSpan timeSpan)
- {
- var timeSpanString = timeSpan.ToString().Replace(".", "_").Replace(":", "_");
- return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", symbol + "_" + timeSpanString + ".txt");
- }
- /// <summary>
- /// 依据周期和记录条生成EndTime
- /// </summary>
- /// <param name="time">时间</param>
- /// <param name="type">周期</param>
- /// <param name="count">记录条数</param>
- private DateTime CreateDateTime(DateTime time, CycleType type, int count)
- {
- switch (type)
- {
- case CycleType.Minute:
- return time.AddMinutes(count);
- case CycleType.Minute5:
- return time.AddMinutes(count * 5);
- case CycleType.Minute30:
- return time.AddMinutes(count * 30);
- case CycleType.Minute240:
- return time.AddMinutes(count * 240);
- case CycleType.Week:
- return time.AddDays(count * 7);
- case CycleType.Month:
- return time.AddMonths(count);
- case CycleType.Quarter:
- return time.AddMonths(count * 4);
- case CycleType.Year:
- return time.AddYears(count);
- default:
- return time.AddDays(count);
- }
- }
- #endregion Private Methods
- #endregion Methods
- public IEnumerable<IBarDataPoint> GetDataPoints(string symbol, TimeSpan timeSpan, DateTime startTime, DateTime endTime, int totalCount)
- {
- if (string.IsNullOrWhiteSpace(symbol)) return null;
- var filePath = CombineFilePath(symbol, timeSpan);
- if (!File.Exists(filePath)) return null;
- return GetDataPoints(filePath, startTime, endTime, totalCount);
- }
- /// <summary>
- /// 保存数据
- /// </summary>
- /// <param name="symbol">商品代码</param>
- /// <param name="timeSpan">The time span.</param>
- /// <param name="dataPoints">保存的数据</param>
- public void SaveDataPoints(string symbol, TimeSpan timeSpan, IList<IBarDataPoint> dataPoints)
- {
- if (string.IsNullOrWhiteSpace(symbol) || dataPoints == null) return;
- var filePath = CombineFilePath(symbol, timeSpan);
- SaveDataPoints(filePath, dataPoints);
- }
- }
- }
|