Compare commits

...

7 Commits
16632 ... 13565

Author SHA1 Message Date
Martin-Molinero
54fa1ad7a4 Address self review 2022-01-31 21:31:07 -03:00
Marinovsky
d2e0cf4721 Nit changes 2022-01-24 13:54:41 -05:00
Marinovsky
eb2a00ad13 Restore SaveString() 2022-01-24 13:53:26 -05:00
Marinovsky
489f3ecd54 Requested changes 2022-01-24 12:28:40 -05:00
Marinovsky
c2eaf199cf Requested changes 2022-01-21 13:46:38 -05:00
Marinovsky
255b4550f0 Nit changes 2022-01-21 13:08:59 -05:00
Marinovsky
bd25cba92c Refactor GetFilePath()
Add also useful methods to use with this one
2022-01-21 12:58:12 -05:00
3 changed files with 113 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -124,7 +124,8 @@ namespace QuantConnect.Storage
{
encoding = encoding ?? Encoding.UTF8;
return encoding.GetString(_store.ReadBytes(key));
var data = _store.ReadBytes(key);
return data != null ? encoding.GetString(data) : null;
}
/// <summary>
@@ -172,17 +173,35 @@ namespace QuantConnect.Storage
}
}
/// <summary>
/// Saves the data from a local file path associated with the specified key
/// </summary>
/// <remarks>If the file does not exist it will throw an exception</remarks>
/// <param name="key">The object key</param>
/// <returns>True if the object was saved successfully</returns>
public bool Save(string key)
{
// Check the file exists
var filePath = GetFilePath(key);
if (!File.Exists(filePath))
{
throw new ArgumentException($"There is no file associated with key {key} in '{filePath}'");
}
var bytes = File.ReadAllBytes(filePath);
return _store.SaveBytes(key, bytes);
}
/// <summary>
/// Saves the object data in text format for the specified key
/// </summary>
/// <param name="key">The object key</param>
/// <param name="text">The string object to be saved</param>
/// <param name="encoding">The string encoding used</param>
/// <param name="encoding">The string encoding used, <see cref="Encoding.UTF8"/> by default</param>
/// <returns>True if the object was saved successfully</returns>
public bool Save(string key, string text, Encoding encoding = null)
{
encoding = encoding ?? Encoding.UTF8;
encoding ??= Encoding.UTF8;
return _store.SaveBytes(key, encoding.GetBytes(text));
}

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -203,7 +203,7 @@ namespace QuantConnect.Lean.Engine.Storage
// Before saving confirm we are abiding by the control rules
// Start by counting our file and its length
var fileCount = 1;
var expectedStorageSizeBytes = contents.Length;
var expectedStorageSizeBytes = contents?.Length ?? 0;
foreach (var kvp in _storage)
{
if (key.Equals(kvp.Key))
@@ -214,7 +214,10 @@ namespace QuantConnect.Lean.Engine.Storage
else
{
fileCount++;
expectedStorageSizeBytes += kvp.Value.Length;
if(kvp.Value != null)
{
expectedStorageSizeBytes += kvp.Value.Length;
}
}
}
@@ -277,6 +280,8 @@ namespace QuantConnect.Lean.Engine.Storage
/// <summary>
/// Returns the file path for the specified key
/// </summary>
/// <remarks>If the key is not already inserted it will just return a path associated with it
/// and add the key with null value</remarks>
/// <param name="key">The object key</param>
/// <returns>The path for the file</returns>
public virtual string GetFilePath(string key)
@@ -284,13 +289,15 @@ namespace QuantConnect.Lean.Engine.Storage
// Ensure we have an object for that key
if (!ContainsKey(key))
{
throw new KeyNotFoundException($"Object with key '{key}' was not found in the current project. " +
"Please use ObjectStore.ContainsKey(key) to check if an object exists before attempting to read."
);
// Add a key with null value to tell Persist() not to delete the file created in the path associated
// with this key and not update it with the value associated with the key(null)
SaveBytes(key, null);
}
else
{
// Persist to ensure pur files are up to date
Persist();
}
// Persist to ensure pur files are up to date
Persist();
// Fetch the path to file and return it
return PathForKey(key);
@@ -414,9 +421,13 @@ namespace QuantConnect.Lean.Engine.Storage
// Write all our store data to disk
foreach (var kvp in data)
{
// Get a path for this key and write to it
var path = PathForKey(kvp.Key);
File.WriteAllBytes(path, kvp.Value);
// Skip the key associated with null values. They are not linked to a file yet
if (kvp.Value != null)
{
// Get a path for this key and write to it
var path = PathForKey(kvp.Key);
File.WriteAllBytes(path, kvp.Value);
}
}
return true;

View File

@@ -1,4 +1,4 @@
/*
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
@@ -68,7 +68,7 @@ namespace QuantConnect.Tests.Common.Storage
Log.LogHandler = _logHandler;
}
[TestCase(FileAccess.Read, false)]
[TestCase(FileAccess.Read, true)]
[TestCase(FileAccess.ReadWrite, false)]
[TestCase(0, true)]
[TestCase(FileAccess.Write, true)]
@@ -83,7 +83,7 @@ namespace QuantConnect.Tests.Common.Storage
}
else
{
Assert.Throws<KeyNotFoundException>(() => store.GetFilePath("Jose"));
Assert.DoesNotThrow(() => store.GetFilePath("Jose"));
}
}
@@ -250,7 +250,6 @@ namespace QuantConnect.Tests.Common.Storage
public void GetFilePathReturnsFileName(string key, string expectedRelativePath)
{
var expectedPath = Path.GetFullPath(expectedRelativePath).Replace("\\", "/");
_store.SaveString(key, "data");
Assert.AreEqual(expectedPath, _store.GetFilePath(key).Replace("\\", "/"));
}
@@ -412,6 +411,55 @@ namespace QuantConnect.Tests.Common.Storage
Assert.IsFalse(_store.SaveString("breaker", "gotem"));
}
[Test]
public void WriteFromExternalMethodAndSaveFromSource()
{
using (var store = new ObjectStore(new LocalObjectStore()))
{
store.Initialize("test", 0, 0, "", new Controls() { PersistenceIntervalSeconds = -1 });
Assert.IsTrue(Directory.Exists("./LocalObjectStoreTests/test"));
var key = "Test";
var content = "Example text";
var path = store.GetFilePath(key);
DummyMachineLearning(path, content);
store.Save(key);
var storeContent = store.Read(key);
Assert.AreEqual(content, storeContent);
}
}
[Test]
public void GetFilePathMethodWorksProperly()
{
using (var store = new ObjectStore(new LocalObjectStore()))
{
store.Initialize("test", 0, 0, "", new Controls() { PersistenceIntervalSeconds = -1 });
Assert.IsTrue(Directory.Exists("./LocalObjectStoreTests/test"));
var key = "test";
var path = store.GetFilePath(key);
Assert.IsFalse(File.Exists(path));
Assert.IsNull(store.Read(key));
}
}
[Test]
public void TrySaveKeyWithNotFileAssociated()
{
using (var store = new ObjectStore(new LocalObjectStore()))
{
store.Initialize("test", 0, 0, "", new Controls() { PersistenceIntervalSeconds = -1 });
Assert.IsTrue(Directory.Exists("./LocalObjectStoreTests/test"));
var key = "test";
Assert.Throws<Exception>(() => store.Save(key));
}
}
[Test]
public void DeletedObjectIsNotReloaded()
{
@@ -448,6 +496,20 @@ namespace QuantConnect.Tests.Common.Storage
}
}
private static void DummyMachineLearning(string outputFile, string content)
{
try
{
var sw = new StreamWriter(outputFile);
sw.Write(content);
sw.Close();
}
catch(Exception e)
{
throw e;
}
}
public class TestSettings
{
public int EmaFastPeriod { get; set; }