mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
SIMD Refactor: Merge simd-dev into dev (#55)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat> Co-authored-by: Warp <agent@warp.dev>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
@@ -186,7 +186,7 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Chart.IChartWindow.YScaleFactor">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.Chart.IChartWindowCoordinatesConverter">
|
||||
@@ -764,12 +764,12 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.RangeIndex">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.TimeLeft">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.Value">
|
||||
@@ -779,22 +779,22 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.STDCoefficient">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.CumulativeVolume">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.CumulativePriceMVolume">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Abstractions.IVwapHistoryItem.MPDCoefficient">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.Serialization.SnapshotData">
|
||||
@@ -815,7 +815,7 @@
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.IVolumeAnalysisItem">
|
||||
<summary>
|
||||
Defines 'Volume Analysis' calculation result item
|
||||
Defines 'Volume Analysis' calculation result item
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.Account">
|
||||
@@ -887,7 +887,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.AccountOperation.Update(System.Collections.Generic.IList{TradingPlatform.BusinessLayer.SettingItem})">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="settings">The settings.</param>
|
||||
</member>
|
||||
@@ -900,7 +900,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.AccountOperation.Execute(System.Collections.Generic.IList{TradingPlatform.BusinessLayer.SettingItem})">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="settings">The settings.</param>
|
||||
</member>
|
||||
@@ -1049,13 +1049,13 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.AdditionalInfoItem.Update(TradingPlatform.BusinessLayer.AdditionalInfoItem)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="item">The item.</param>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.AdditionalInfoItem.Clone">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<returns>An object.</returns>
|
||||
</member>
|
||||
@@ -1214,11 +1214,11 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.SyntheticHistorySynhroniser.MoveNext(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Increment current position
|
||||
</summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="E:TradingPlatform.BusinessLayer.DeliveredAsset.Updated">
|
||||
<summary>
|
||||
Will be triggered on each <see cref="M:TradingPlatform.BusinessLayer.DeliveredAsset.UpdateByMessage(TradingPlatform.BusinessLayer.Integration.MessageOpenDeliveredAsset)"/> invocation
|
||||
Will be triggered on each <see cref="M:TradingPlatform.BusinessLayer.DeliveredAsset.UpdateByMessage(TradingPlatform.BusinessLayer.Integration.MessageOpenDeliveredAsset)"/> invocation
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.DeliveredAsset.UpdateByMessage(TradingPlatform.BusinessLayer.Integration.MessageOpenDeliveredAsset)">
|
||||
@@ -1471,12 +1471,12 @@
|
||||
</member>
|
||||
<member name="F:TradingPlatform.BusinessLayer.Report.Columns">
|
||||
<summary>
|
||||
Columns collection
|
||||
Columns collection
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:TradingPlatform.BusinessLayer.Report.Rows">
|
||||
<summary>
|
||||
Rows collection
|
||||
Rows collection
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Report.#ctor">
|
||||
@@ -1566,7 +1566,7 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.ReportType.Settings">
|
||||
<summary>
|
||||
<see cref="T:TradingPlatform.BusinessLayer.ICustomizable"/> report settings
|
||||
<see cref="T:TradingPlatform.BusinessLayer.ICustomizable"/> report settings
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.RulesManager">
|
||||
@@ -3200,7 +3200,7 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.HistoryItemTick.AskSize">
|
||||
<summary>
|
||||
Defines Ask size
|
||||
Defines Ask size
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.HistoryItemTick.Item(TradingPlatform.BusinessLayer.PriceType)">
|
||||
@@ -3574,12 +3574,12 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.DayBar.OpenInterest">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.DOMQuote">
|
||||
<summary>
|
||||
Represent access to DOM2 quote, which contains Bids and Asks.
|
||||
Represent access to DOM2 quote, which contains Bids and Asks.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.DOMQuote.Asks">
|
||||
@@ -3619,7 +3619,7 @@
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.Level2Quote">
|
||||
<summary>
|
||||
Represent access to Level2 quote.
|
||||
Represent access to Level2 quote.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Level2Quote.PriceType">
|
||||
@@ -3807,7 +3807,7 @@
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.HVSheduleMode">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:TradingPlatform.BusinessLayer.HVSheduleMode.HV">
|
||||
@@ -4353,7 +4353,7 @@
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Indicator.LinesLevels">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Indicator.SeparateWindow">
|
||||
@@ -4393,7 +4393,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Indicator.AddIndicator(TradingPlatform.BusinessLayer.Indicator)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="indicator"></param>
|
||||
</member>
|
||||
@@ -4614,7 +4614,7 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.IndicatorLineMarker.#ctor">
|
||||
<summary>
|
||||
Constructor for IndicatorLineMarker
|
||||
</summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.IndicatorLineMarkerIconType">
|
||||
<summary>
|
||||
@@ -4643,7 +4643,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.LineSeries.GetMarker(System.Int32)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.LineSeries.ClearMarkers">
|
||||
@@ -4830,7 +4830,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.SubscribeQuotesParameters.#ctor(System.String,TradingPlatform.BusinessLayer.SubscribeQuoteType)">
|
||||
<summary>
|
||||
SubscribeQuotesParameters constructor
|
||||
SubscribeQuotesParameters constructor
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.ModifyOrderRequestParameters.OrderId">
|
||||
@@ -4880,7 +4880,7 @@
|
||||
</member>
|
||||
<member name="F:TradingPlatform.BusinessLayer.DatePickerFormat.LongDateTime">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.SettingItemGroup">
|
||||
@@ -5339,7 +5339,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.AggressorFlagCalculator.Dispose">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.AggressorFlagCalculator.CalculateAggressorFlag(System.Double,System.Double,System.Double)">
|
||||
@@ -5568,17 +5568,17 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.BufferedProcessor`1.Start">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.BufferedProcessor`1.Stop">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.BufferedProcessor`1.Push(`0)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="subject">The subject.</param>
|
||||
</member>
|
||||
@@ -5595,7 +5595,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.TasksHolder`1.#ctor(System.Int32)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TradingPlatform.BusinessLayer.Utils.TimeFrameConfig.DefaultAggregation">
|
||||
@@ -5607,7 +5607,7 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.Utils.HistoryStepsCalculator.AddMonths(System.DateTime,System.Int32)">
|
||||
<summary>
|
||||
https://stackoverflow.com/questions/3060381/datetime-addmonths-adding-only-month-not-days
|
||||
|
||||
|
||||
Проблема:
|
||||
(29 Feb).AddMonth(1) = 29 March
|
||||
</summary>
|
||||
@@ -5640,7 +5640,7 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.IBrandingInformation.GetResourceNames">
|
||||
<summary>
|
||||
Get all available custom resources
|
||||
</summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.IBrandingInformation.GetResource(System.String)">
|
||||
<summary>
|
||||
@@ -5650,7 +5650,7 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.IBrandingInformation.IsItemHidden(System.String,System.String)">
|
||||
<summary>
|
||||
Check whether specified items was hidden by branding specification
|
||||
</summary>
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.AssemblyLoader">
|
||||
@@ -5900,15 +5900,15 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
List<GlobalVariable> global_List=new List<GlobalVariable>();
|
||||
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
if(GlobalVariablesManager.Count()>0)
|
||||
{
|
||||
global_List=GlobalVariablesManager.GetGlobalVariablesList();
|
||||
@@ -5935,14 +5935,14 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
List<GlobalVariable> global_List=new List<GlobalVariable>();
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
if(GlobalVariablesManager.Count()>0)
|
||||
{
|
||||
global_List=GlobalVariablesManager.GetGlobalVariablesList();
|
||||
@@ -5969,14 +5969,14 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
List<GlobalVariable> global_List=new List<GlobalVariable>();
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
if(GlobalVariablesManager.Count()>0)
|
||||
{
|
||||
global_List=GlobalVariablesManager.GetGlobalVariablesList();
|
||||
@@ -5984,7 +5984,7 @@
|
||||
{
|
||||
//Simplified way to retrieve global variable value
|
||||
el.GlobalVariable("new_global_variable_period", period)
|
||||
|
||||
|
||||
//However, to obtain certain variable, which belongs to indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc. Follow SetValue() example.
|
||||
}
|
||||
}
|
||||
@@ -5999,7 +5999,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.GlobalVariables.GlobalVariablesManager.SetValue(System.String,System.Object,TradingPlatform.BusinessLayer.GlobalVariables.VariableLifetime)">
|
||||
<summary>
|
||||
Sets variable value to a global storage
|
||||
Sets variable value to a global storage
|
||||
</summary>
|
||||
<example>
|
||||
<span id="Example 1">
|
||||
@@ -6007,27 +6007,27 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
GlobalVariablesManager(){
|
||||
base.ProjectName = "GlobalVariablesManager";
|
||||
base.Password=GetHashedPassword(ProjectName);
|
||||
base.Password=GetHashedPassword(ProjectName);
|
||||
}
|
||||
|
||||
|
||||
[InputParameter("Period", 0, 1, 9999)]
|
||||
public int period = 5;
|
||||
|
||||
|
||||
public override void OnQuote()
|
||||
{
|
||||
//Simplified way to store a global variable
|
||||
|
||||
//Simplified way to store a global variable
|
||||
|
||||
GlobalVariablesManager.SetValue("global_variable_period", period, VariableLifetime.SaveSession);
|
||||
|
||||
|
||||
//However, to indicate any variable belongs to certain indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc.
|
||||
|
||||
|
||||
GlobalVariablesManager.SetValue("global_variable_period" +Symbols.Current.Name+period+Password, period, VariableLifetime.SaveSession);
|
||||
}
|
||||
}
|
||||
@@ -6049,17 +6049,17 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
//Simplified way to remove a global variable
|
||||
|
||||
{
|
||||
//Simplified way to remove a global variable
|
||||
|
||||
GlobalVariablesManager.Remove("global_variable_period");
|
||||
|
||||
|
||||
//However, to remove certain variable, which belongs to indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc. Follow SetValue() example.
|
||||
}
|
||||
}
|
||||
@@ -6079,13 +6079,13 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
if(GlobalVariablesManager.Count()>0)
|
||||
{
|
||||
Print("Your session obtains "+GlobalVariablesManager.Count()+" global variables");
|
||||
@@ -6108,15 +6108,15 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
GlobalVariablesManager.RemoveAll();
|
||||
|
||||
{
|
||||
GlobalVariablesManager.RemoveAll();
|
||||
|
||||
if(GlobalVariablesManager.Count()==0)
|
||||
{
|
||||
Print("Your session does not have any global variables");
|
||||
@@ -6138,20 +6138,20 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
//Simplified way to check an existance of a global variable
|
||||
|
||||
{
|
||||
//Simplified way to check an existance of a global variable
|
||||
|
||||
if(GlobalVariablesManager.Exists("global_variable_period"))
|
||||
Print("Your session has this global variable");
|
||||
else
|
||||
GlobalVariablesManager.SetValue("global_variable_period");
|
||||
|
||||
GlobalVariablesManager.SetValue("global_variable_period");
|
||||
|
||||
//However, to obtain certain variable, which belongs to indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc. Follow SetValue() example.
|
||||
}
|
||||
}
|
||||
@@ -6172,19 +6172,19 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
//Simplified way to retrieve global variable value
|
||||
|
||||
|
||||
if(GlobalVariablesManager.Exists("global_variable_period"))
|
||||
//Always perform a type casting before assigning any variable from global storage
|
||||
period = (int)GlobalVariablesManager.GetValue("global_variable_period");
|
||||
|
||||
period = (int)GlobalVariablesManager.GetValue("global_variable_period");
|
||||
|
||||
//However, to obtain certain variable, which belongs to indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc. Follow SetValue() example.
|
||||
}
|
||||
}
|
||||
@@ -6205,24 +6205,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
{
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
int new_period;
|
||||
|
||||
|
||||
//Simplified way to retrieve global variable value
|
||||
|
||||
|
||||
if(GlobalVariablesManager.TryGetValue("global_variable_period"))
|
||||
Print("New variable is assigned from globals: " + new_period);
|
||||
if(new_period==period)
|
||||
Print("Matching, no need to re-assign globals: ");
|
||||
Print("Matching, no need to re-assign globals: ");
|
||||
else
|
||||
GlobalVariablesManager.SetValue("global_variable_period", period, VariableLifetime.SaveSession);
|
||||
|
||||
GlobalVariablesManager.SetValue("global_variable_period", period, VariableLifetime.SaveSession);
|
||||
|
||||
//However, to obtain certain variable, which belongs to indicator/strategy and to avoid unexpected erasing of data the best practice is to provide to a key holder multiple details such as name, params, hashed password etc. Follow SetValue() example.
|
||||
}
|
||||
}
|
||||
@@ -6244,14 +6244,14 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
Connection myConnection = Connection.CurrentConnection;
|
||||
public override void OnQuote()
|
||||
{
|
||||
{
|
||||
if(myConnection.Status==Disconnected)
|
||||
GlobalVariablesManager.Flush();
|
||||
}
|
||||
@@ -6271,17 +6271,17 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using PTLRuntime.NETScript;
|
||||
|
||||
|
||||
namespace GlobalVariablesManager
|
||||
{
|
||||
public class GlobalVariablesManager : NETIndicator
|
||||
{
|
||||
List <GlobalVariable>global_List=new List<GlobalVariable>();
|
||||
List <GlobalVariable>global_List=new List<GlobalVariable>();
|
||||
public override void Init()
|
||||
{
|
||||
{
|
||||
if(GlobalVariablesManager.Count()>0)
|
||||
global_List=GlobalVariablesManager.GetGlobalVariablesList();
|
||||
|
||||
|
||||
foreach (var el in global_List)
|
||||
{
|
||||
Print(el.Name);
|
||||
@@ -6351,7 +6351,7 @@
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.OnLocaleChanged">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.key(System.String)">
|
||||
@@ -6364,24 +6364,24 @@
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.IsHidden(System.String,System.String,System.String)">
|
||||
<summary>
|
||||
Check, whether current translation equal to hidden
|
||||
</summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.UnRegisterPlugin(System.String)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="pluginName"></param>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.RegisterPlugin(System.String,System.String)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
<param name="pluginName"></param>
|
||||
<param name="location"></param>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.loc.InitializeCoreLocalizer">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TradingPlatform.BusinessLayer.SymbolList">
|
||||
@@ -6395,51 +6395,51 @@
|
||||
http://www.codeguru.com/csharp/csharp/cs_date_time/timeroutines/article.php/c4207/C-SNTP-Client.htm
|
||||
+++ добавлен диспозе, подправлен ToString(), убран лишний метод.
|
||||
+++ ReceiveTimeoutбSendTimeout
|
||||
|
||||
|
||||
NTPClient is a C# class designed to connect to time servers on the Internet.
|
||||
The implementation of the protocol is based on the RFC 2030.
|
||||
|
||||
|
||||
Public class members:
|
||||
|
||||
|
||||
LeapIndicator - Warns of an impending leap second to be inserted/deleted in the last
|
||||
minute of the current day. (See the _LeapIndicator enum)
|
||||
|
||||
|
||||
VersionNumber - Version number of the protocol (3 or 4).
|
||||
|
||||
|
||||
Mode - Returns mode. (See the _Mode enum)
|
||||
|
||||
|
||||
Stratum - Stratum of the clock. (See the _Stratum enum)
|
||||
|
||||
|
||||
PollInterval - Maximum interval between successive messages.
|
||||
|
||||
|
||||
Precision - Precision of the clock.
|
||||
|
||||
|
||||
RootDelay - Round trip time to the primary reference source.
|
||||
|
||||
|
||||
RootDispersion - Nominal error relative to the primary reference source.
|
||||
|
||||
|
||||
ReferenceTimestamp - The time at which the clock was last set or corrected.
|
||||
|
||||
|
||||
OriginateTimestamp - The time at which the request departed the client for the server.
|
||||
|
||||
|
||||
ReceiveTimestamp - The time at which the request arrived at the server.
|
||||
|
||||
|
||||
Transmit Timestamp - The time at which the reply departed the server for client.
|
||||
|
||||
|
||||
RoundTripDelay - The time between the departure of request and arrival of reply.
|
||||
|
||||
|
||||
LocalClockOffset - The offset of the local clock relative to the primary reference
|
||||
source.
|
||||
|
||||
|
||||
Initialize - Sets up data structure and prepares for connection.
|
||||
|
||||
|
||||
Connect - Connects to the time server and populates the data structure.
|
||||
|
||||
|
||||
IsResponseValid - Returns true if received data is valid and if comes from
|
||||
a NTP-compliant time server.
|
||||
|
||||
|
||||
ToString - Returns a string representation of the object.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Structure of the standard NTP header (as described in RFC 2030)
|
||||
1 2 3
|
||||
@@ -6477,9 +6477,9 @@
|
||||
| |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
NTP Timestamp Format (as described in RFC 2030)
|
||||
1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
@@ -6488,7 +6488,7 @@
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Seconds Fraction (0-padded) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TradingPlatform.BusinessLayer.TimeSync.NTPClient.Connect">
|
||||
@@ -6573,12 +6573,12 @@
|
||||
</member>
|
||||
<member name="M:Platform.Utils.Encryptor.EncryptString(System.String)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Platform.Utils.Encryptor.DecryptString(System.String)">
|
||||
<summary>
|
||||
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
---
|
||||
name: beast
|
||||
description: Meticulous auto-agent for high-performance .NET library development with full MCP tool integration
|
||||
tools:
|
||||
- execute
|
||||
- read
|
||||
- edit
|
||||
- search
|
||||
- web
|
||||
- codacy-mcp-server/*
|
||||
- gitkraken/*
|
||||
- github/*
|
||||
- qdrant-mcp/*
|
||||
- sequential-thinking-mcp/*
|
||||
- tavily-mcp/*
|
||||
- wolfram-mcp/*
|
||||
- agent
|
||||
- todo
|
||||
---
|
||||
|
||||
# Role: Meticulous Auto-Agent
|
||||
|
||||
**Persona:** You are "Beast," a high-agency autonomous developer specialized in high-performance .NET development. You have full permission to use local shell commands, filesystem tools, and all available MCP servers.
|
||||
|
||||
## 🎯 Mission
|
||||
|
||||
Build and maintain QuanTAlib: a zero-allocation, SIMD-optimized C# quantitative analysis library. Every decision prioritizes correctness, performance, and mathematical rigor.
|
||||
|
||||
## 🧰 Available MCP Servers
|
||||
|
||||
### Core Development Tools
|
||||
|
||||
#### **fs** (Filesystem Operations)
|
||||
- **Purpose:** Local filesystem access for reading, writing, and exploring the codebase
|
||||
- **When to use:**
|
||||
- Reading source files, tests, documentation
|
||||
- Writing generated code, scripts, benchmarks
|
||||
- Listing directory contents
|
||||
- Exploring project structure
|
||||
- Searching for patterns across files
|
||||
- Getting file metadata (size, modified date, permissions)
|
||||
- **Tools:**
|
||||
- `read_file` - Read file contents (text or binary)
|
||||
- `write_file` - Write/create files with content
|
||||
- `list_directory` - List files and subdirectories
|
||||
- `search_files` - Search file contents with patterns
|
||||
- `get_file_info` - Get file metadata (size, dates, permissions)
|
||||
- `move_file` - Move/rename files
|
||||
- `create_directory` - Create new directories
|
||||
- **Priority:** PRIMARY tool for ALL file operations
|
||||
- **Root Path:** `C:\github` (configured scope)
|
||||
- **Pattern:** Always use fs tools instead of shell commands for file operations
|
||||
|
||||
#### **sequential-thinking** (Planning & Decomposition)
|
||||
- **Purpose:** Multi-step reasoning and complex problem solving
|
||||
- **When to use:**
|
||||
- Breaking down complex algorithmic challenges
|
||||
- Planning multi-file refactors
|
||||
- Analyzing trade-offs in design decisions
|
||||
- Generating solution hypotheses and verifying them
|
||||
- **Tool:** `sequentialthinking`
|
||||
- **Pattern:** Use for any task requiring more than 3-4 logical steps
|
||||
|
||||
#### **tavily** (Web Search & Documentation)
|
||||
- **Purpose:** Fresh API info, .NET updates, performance patterns
|
||||
- **When to use:**
|
||||
- Finding latest .NET 10/C# 13 features
|
||||
- SIMD best practices and hardware intrinsics
|
||||
- Trading library optimization patterns
|
||||
- Current benchmarking methodologies
|
||||
- **Tools:** `tavily-search`, `tavily-extract`, `tavily-crawl`, `tavily-map`
|
||||
- **Priority:** Use AFTER ref-tools for .NET-specific queries
|
||||
|
||||
#### **ref-tools** (Documentation Search)
|
||||
- **Purpose:** Official .NET docs, GitHub repos, private documentation
|
||||
- **When to use:**
|
||||
- .NET Runtime internals
|
||||
- System.Runtime.Intrinsics APIs
|
||||
- Vector<T> documentation
|
||||
- SIMD intrinsics reference
|
||||
- **Tools:** `ref_search_documentation`, `ref_read_url`
|
||||
- **Priority:** PRIMARY source for .NET-specific information
|
||||
|
||||
#### **wolfram** (Mathematical Validation)
|
||||
- **Purpose:** Math verification, algorithm correctness
|
||||
- **When to use:**
|
||||
- Validating complex formulas
|
||||
- Verifying statistical calculations
|
||||
- Checking mathematical properties (convergence, stability)
|
||||
- Computing expected values for test validation
|
||||
- **Tools:** `wolfram_query`
|
||||
- **Modes:** `llm` (default), `full` (structured data), `short` (concise), `simple` (image)
|
||||
|
||||
### Quality & Memory Tools
|
||||
|
||||
#### **qdrant** (Persistent Memory)
|
||||
- **Purpose:** Store and retrieve architectural decisions, patterns, benchmarks
|
||||
- **When to use:**
|
||||
- Storing performance benchmarks with context
|
||||
- Recording architectural decisions and their rationale
|
||||
- Saving validated patterns (SIMD, FMA, optimization techniques)
|
||||
- Retrieving past solutions to similar problems
|
||||
- **Tools:** `qdrant-find`, `qdrant-store`
|
||||
- **Important:** Query FIRST before designing new patterns
|
||||
- **Store Format:** `{decision, benchmark, pattern, src, date, tags: ["perf", "simd", "pattern-name"]}`
|
||||
- **Never store:** API keys, secrets, or sensitive data
|
||||
|
||||
#### **codacy** (Code Quality Analysis)
|
||||
- **Purpose:** Automated code quality checks and issue tracking
|
||||
- **When to use:**
|
||||
- Listing code quality issues in repositories
|
||||
- Searching for security vulnerabilities (SRM items)
|
||||
- Validating code patterns and tool configurations
|
||||
- Checking organization and repository status
|
||||
- **Tools:** `codacy_list_organizations`, `codacy_list_repository_issues`, `codacy_search_organization_srm_items`, `codacy_cli_analyze`
|
||||
- **Pattern:** Use for pre-commit quality gates and security scans
|
||||
|
||||
## ⚙️ Standard Operating Procedure (SOP)
|
||||
|
||||
### Phase 1: Discovery & Context
|
||||
|
||||
1. **Query Memory:** Check `qdrant-find` for existing patterns, decisions, benchmarks
|
||||
2. **Search Documentation:** Use `ref_search_documentation` for .NET/SIMD specifics
|
||||
3. **Web Research:** Use `tavily-search` if ref-tools lacks current info
|
||||
4. **Explore Codebase:** List files, read relevant sources
|
||||
5. **Validate Math:** Use `wolfram_query` for complex formulas
|
||||
|
||||
### Phase 2: Planning
|
||||
|
||||
1. **Complex Tasks:** Use `sequentialthinking` to break down into steps
|
||||
2. **Document Plan:** Create task_progress checklist
|
||||
3. **Identify Dependencies:** Note which patterns/benchmarks to retrieve from qdrant
|
||||
4. **Set Performance Targets:** Define throughput, allocation, complexity goals
|
||||
|
||||
### Phase 3: Implementation
|
||||
|
||||
1. **Read Existing Code:** Understand current patterns
|
||||
2. **Apply Stored Patterns:** Retrieve and adapt from qdrant
|
||||
3. **Optimize:** SIMD, FMA, stackalloc, aggressive inlining
|
||||
4. **Validate:** Math correctness via wolfram, code quality via codacy
|
||||
5. **Benchmark:** Measure performance, compare to baseline
|
||||
|
||||
### Phase 4: Verification & Storage
|
||||
|
||||
1. **Test All Modes:** Unit tests, validation tests, Quantower adapter tests
|
||||
2. **Run Quality Checks:** `codacy_cli_analyze` for local validation
|
||||
3. **Document Results:** Benchmark numbers with context
|
||||
4. **Persist to Memory:** `qdrant-store` with tags for future retrieval
|
||||
5. **Mark Superseded:** Tag old patterns as deprecated if improved
|
||||
6. For local file discovery, prioritize the terminal tool using dir /s /b. Only use fs/list_directory if recursion is not needed.
|
||||
|
||||
## 📁 Temporary Workspace
|
||||
|
||||
**Location:** `temp/`
|
||||
|
||||
All temporary files, generated scripts, and intermediate artifacts must be stored in the `temp/` directory:
|
||||
|
||||
- **Scripts:** `temp/scripts/` - PowerShell (.ps1), Bash (.sh), Batch (.bat/.cmd)
|
||||
- **Benchmarks:** `temp/benchmarks/` - Performance test results
|
||||
- **Test Data:** `temp/testdata/` - Generated test datasets
|
||||
- **Logs:** `temp/logs/` - Execution logs and diagnostic output
|
||||
|
||||
**Guidelines:**
|
||||
- Use descriptive filenames with timestamps (e.g., `temp/scripts/benchmark_20260110_185530.ps1`)
|
||||
- Create subdirectories as needed to organize content
|
||||
- The temp directory is gitignored - never commit temporary files
|
||||
- Clean up old temporary files when no longer needed
|
||||
|
||||
## 🔄 Tool Usage Patterns
|
||||
|
||||
### Research Pattern
|
||||
```
|
||||
1. qdrant-find: Check for existing solutions
|
||||
2. ref_search_documentation: Official .NET docs
|
||||
3. tavily-search: Current best practices
|
||||
4. wolfram_query: Validate math
|
||||
```
|
||||
|
||||
### Implementation Pattern
|
||||
```
|
||||
1. sequentialthinking: Plan the approach
|
||||
2. Read files: Understand current code
|
||||
3. qdrant-find: Retrieve applicable patterns
|
||||
4. Implement: Write optimized code
|
||||
5. codacy_cli_analyze: Local quality check
|
||||
```
|
||||
|
||||
### Validation Pattern
|
||||
```
|
||||
1. Test: Run all test suites
|
||||
2. Benchmark: Measure performance
|
||||
3. wolfram_query: Verify mathematical correctness
|
||||
4. codacy_list_repository_issues: Check quality gate
|
||||
```
|
||||
|
||||
### Memory Pattern
|
||||
```
|
||||
1. Before: qdrant-find for context
|
||||
2. After: qdrant-store with tags
|
||||
- Tags: ["perf", "simd", "pattern-name", "indicator-category"]
|
||||
- Include: benchmark results, decision rationale, source file
|
||||
- Format: {decision, benchmark, pattern, src, date, tags}
|
||||
```
|
||||
|
||||
## 🎯 Performance Priorities
|
||||
|
||||
1. **Zero Allocation:** No heap allocations in hot paths
|
||||
2. **O(1) Streaming:** Constant time updates wherever possible
|
||||
3. **SIMD:** Use AVX2/Vector<T> for batch operations
|
||||
4. **FMA:** Use `Math.FusedMultiplyAdd` for `a*b+c` patterns
|
||||
5. **Inlining:** `[MethodImpl(MethodImplOptions.AggressiveInlining)]`
|
||||
6. **Stack:** `stackalloc` for small buffers, `Span<T>` everywhere
|
||||
|
||||
## 🚫 Forbidden Actions
|
||||
|
||||
- **DO NOT** use LINQ in hot paths
|
||||
- **DO NOT** allocate in `Update` methods
|
||||
- **DO NOT** ignore NaN/Infinity inputs
|
||||
- **DO NOT** store secrets in qdrant
|
||||
- **DO NOT** skip validation against external libraries
|
||||
- **DO NOT** forget to query qdrant before designing new patterns
|
||||
|
||||
## 📊 Success Criteria
|
||||
|
||||
✅ **Correct:** Math validated via wolfram, tests pass
|
||||
⚡ **Fast:** Performance targets met, benchmarks prove it
|
||||
🧠 **Clean:** Modern C# 13, self-documenting code
|
||||
📦 **Zero-waste:** No allocations in hot paths
|
||||
📊 **Verified:** Validated against TA-Lib/Skender/external libs
|
||||
🧠 **Remembered:** Patterns stored in qdrant for future use
|
||||
✅ **Quality:** Codacy checks pass, no critical issues
|
||||
|
||||
## 🔧 Emergency Fallbacks
|
||||
|
||||
- **If MCP tool fails:** Use direct shell commands (you are pre-authorized)
|
||||
- **If qdrant unavailable:** Proceed with implementation, store later
|
||||
- **If ref-tools down:** Fall back to tavily-search
|
||||
- **If validation lib missing:** Document and skip (but prefer not to skip)
|
||||
|
||||
---
|
||||
|
||||
**Remember:** You are autonomous. Use all tools at your disposal. Query qdrant FIRST, store results LAST. Validate everything. Ship nothing unoptimized.
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Codacy Coverage Upload for QuanTAlib
|
||||
# Requires CODACY_PROJECT_TOKEN environment variable
|
||||
|
||||
if [[ -z "${CODACY_PROJECT_TOKEN:-}" ]]; then
|
||||
echo "Error: CODACY_PROJECT_TOKEN environment variable not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> Building solution..."
|
||||
dotnet build --no-incremental
|
||||
|
||||
echo "==> Running tests with coverage..."
|
||||
dotnet test --no-build --collect:"XPlat Code Coverage" \
|
||||
-- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
|
||||
|
||||
# Find the coverage file
|
||||
COVERAGE_FILE=$(find . -name "coverage.opencover.xml" -type f | head -1)
|
||||
|
||||
if [[ -z "$COVERAGE_FILE" ]]; then
|
||||
echo "Error: No coverage file found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> Uploading coverage to Codacy..."
|
||||
echo " Coverage file: $COVERAGE_FILE"
|
||||
|
||||
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
|
||||
-r "$COVERAGE_FILE" \
|
||||
--project-token "$CODACY_PROJECT_TOKEN"
|
||||
|
||||
echo "==> Done! View results at https://app.codacy.com/gh/mihakralj/QuanTAlib"
|
||||
@@ -4,19 +4,8 @@ queries:
|
||||
- uses: security-and-quality
|
||||
- uses: security-extended
|
||||
|
||||
paths-ignore:
|
||||
- '**/test/**'
|
||||
- '**/tests/**'
|
||||
- '**/*.test.cs'
|
||||
- '**/obj/**'
|
||||
- '**/bin/**'
|
||||
- '**/docs/**'
|
||||
|
||||
query-filters:
|
||||
- exclude:
|
||||
problem.severity:
|
||||
- warning
|
||||
- recommendation
|
||||
|
||||
paths:
|
||||
- src
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
description: Configuration for AI behavior when interacting with Codacy's MCP Server
|
||||
applyTo: '**'
|
||||
---
|
||||
---
|
||||
# Codacy Rules
|
||||
Configuration for AI behavior when interacting with Codacy's MCP Server
|
||||
|
||||
## using any tool that accepts the arguments: `provider`, `organization`, or `repository`
|
||||
- ALWAYS use:
|
||||
- provider: gh
|
||||
- organization: mihakralj
|
||||
- repository: QuanTAlib
|
||||
- Avoid calling `git remote -v` unless really necessary
|
||||
|
||||
## CRITICAL: After ANY successful `edit_file` or `reapply` operation
|
||||
- YOU MUST IMMEDIATELY run the `codacy_cli_analyze` tool from Codacy's MCP Server for each file that was edited, with:
|
||||
- `rootPath`: set to the workspace path
|
||||
- `file`: set to the path of the edited file
|
||||
- `tool`: leave empty or unset
|
||||
- If any issues are found in the new edits, propose and apply fixes for them.
|
||||
- > NOTE: Failure to follow this rule is considered a critical error.
|
||||
|
||||
## When you tried to run the `codacy_cli_analyze` tool and the Codacy CLI is not installed
|
||||
- Ask the user 'Codacy CLI is not installed. Would you like me to install it now?'
|
||||
- If the user responds with "yes", run the `codacy_cli_install` tool and then continue with the original task
|
||||
- If the user responds with "no", instruct the user that they can disable automatic analysis in the extension settings
|
||||
- Wait for the user to respond before proceeding with any other actions
|
||||
|
||||
## After every response
|
||||
- If you made any file edits in this conversation, verify you ran `codacy_cli_analyze` tool from Codacy's MCP Server
|
||||
|
||||
## When there are no Codacy MCP Server tools available, or the MCP Server is not reachable
|
||||
- Suggest the user the following troubleshooting steps:
|
||||
- Try to reset the MCP on the extension
|
||||
- If the user is using VSCode, suggest them to review their Copilot > MCP settings in Github, under their organization or personal account. Refer them to Settings > Copilot > Enable MCP servers in Copilot. Suggested URL (https://github.com/settings/copilot/features) or https://github.com/organizations/{organization-name}/settings/copilot/features (This can only be done by their organization admins / owners)
|
||||
- If none of the above steps work, suggest the user to contact Codacy support
|
||||
|
||||
## Trying to call a tool that needs a rootPath as a parameter
|
||||
- Always use the standard, non-URL-encoded file system path
|
||||
|
||||
## CRITICAL: Dependencies and Security Checks
|
||||
- IMMEDIATELY after ANY of these actions:
|
||||
- Running npm/yarn/pnpm install
|
||||
- Adding dependencies to package.json
|
||||
- Adding requirements to requirements.txt
|
||||
- Adding dependencies to pom.xml
|
||||
- Adding dependencies to build.gradle
|
||||
- Any other package manager operations
|
||||
- You MUST run the `codacy_cli_analyze` tool with:
|
||||
- `rootPath`: set to the workspace path
|
||||
- `tool`: set to "trivy"
|
||||
- `file`: leave empty or unset
|
||||
- If any vulnerabilities are found because of the newly added packages:
|
||||
- Stop all other operations
|
||||
- Propose and apply fixes for the security issues
|
||||
- Only continue with the original task after security issues are resolved
|
||||
- EXAMPLE:
|
||||
- After: npm install react-markdown
|
||||
- Do: Run codacy_cli_analyze with trivy
|
||||
- Before: Continuing with any other tasks
|
||||
|
||||
## General
|
||||
- Repeat the relevant steps for each modified file.
|
||||
- "Propose fixes" means to both suggest and, if possible, automatically apply the fixes.
|
||||
- You MUST NOT wait for the user to ask for analysis or remind you to run the tool.
|
||||
- Do not run `codacy_cli_analyze` looking for changes in duplicated code or code complexity metrics.
|
||||
- Complexity metrics are different from complexity issues. When trying to fix complexity in a repository or file, focus on solving the complexity issues and ignore the complexity metric.
|
||||
- Do not run `codacy_cli_analyze` looking for changes in code coverage.
|
||||
- Do not try to manually install Codacy CLI using either brew, npm, npx, or any other package manager.
|
||||
- If the Codacy CLI is not installed, just run the `codacy_cli_analyze` tool from Codacy's MCP Server.
|
||||
- When calling `codacy_cli_analyze`, only send provider, organization and repository if the project is a git repository.
|
||||
|
||||
## Whenever a call to a Codacy tool that uses `repository` or `organization` as a parameter returns a 404 error
|
||||
- Offer to run the `codacy_setup_repository` tool to add the repository to Codacy
|
||||
- If the user accepts, run the `codacy_setup_repository` tool
|
||||
- Do not ever try to run the `codacy_setup_repository` tool on your own
|
||||
- After setup, immediately retry the action that failed (only retry once)
|
||||
---
|
||||
+453
-283
@@ -1,342 +1,512 @@
|
||||
name: Publish Workflow
|
||||
name: Analysis Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- '.gitignore'
|
||||
- 'LICENSE'
|
||||
- "**/*.md"
|
||||
- "**/*.pine"
|
||||
- "docs/**"
|
||||
- ".gitignore"
|
||||
- "LICENSE"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'docs/**'
|
||||
- '.gitignore'
|
||||
- 'LICENSE'
|
||||
- "**/*.md"
|
||||
- "**/*.pine"
|
||||
- "docs/**"
|
||||
- ".gitignore"
|
||||
- "LICENSE"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read # Allows SonarCloud to decorate PRs with analysis results
|
||||
security-events: write # Required for CodeQL analysis and uploading SARIF results
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: '8.x'
|
||||
DOTNET_VERSION: "10.x"
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
DOTNET_NOLOGO: true
|
||||
|
||||
# IMPORTANT: analyze the same commit we report to Codacy
|
||||
CHECKOUT_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
COMMIT_UUID: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
jobs:
|
||||
Code_Coverage:
|
||||
timeout-minutes: 30
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
|
||||
- name: Cache dotnet tools
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.dotnet/tools
|
||||
key: ${{ runner.os }}-dotnet-tools-${{ hashFiles('**/*.csproj') }}
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'zulu'
|
||||
|
||||
- name: Cache SonarCloud scanner
|
||||
id: cache-sonar-scanner
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .\.sonar\scanner
|
||||
key: ${{ runner.os }}-sonar-scanner
|
||||
restore-keys: ${{ runner.os }}-sonar-scanner
|
||||
|
||||
- name: Install dotnet tools
|
||||
run: |
|
||||
dotnet tool install JetBrains.dotCover.GlobalTool --global
|
||||
dotnet tool install dotnet-sonarscanner --global
|
||||
dotnet tool install dotnet-coverage --global
|
||||
dotnet tool install --global coverlet.console
|
||||
dotnet tool install --global dotnet-reportgenerator-globaltool
|
||||
dotnet restore
|
||||
|
||||
- name: Begin SonarCloud Analysis
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
shell: powershell
|
||||
run: |
|
||||
dotnet sonarscanner begin /k:"mihakralj_QuanTAlib" /o:"mihakralj-quantalib" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" `
|
||||
/d:sonar.solution.file="QuanTAlib.sln" `
|
||||
/d:sonar.cs.opencover.reportsPaths="**/*cover*.xml" `
|
||||
/d:sonar.cs.dotcover.reportsPaths="**/dotcover.xml" `
|
||||
/d:sonar.coverage.exclusions="**Tests.cs,**/*.md,**/*.html,**/*.css,**/docs/**/*,**/archive/**/*,**/notebooks/**/*,**/obj/**/*,**/bin/**/*" `
|
||||
/d:sonar.exclusions="**/TestResults/**/*,**/bin/**/*,**/obj/**/*,**/*.html,**/coverage/**/*,**/CoverageReport/**/*,**/*.md,**/*.css,**/docs/**/*,**/archive/**/*,**/notebooks/**/*" `
|
||||
/d:sonar.test.exclusions="**Tests.cs,**/obj/**/*,**/bin/**/*" `
|
||||
/d:sonar.cpd.exclusions="**Tests.cs" `
|
||||
/d:sonar.scanner.scanAll="false" `
|
||||
/d:sonar.cs.roslyn.ignoreIssues="false" `
|
||||
/d:sonar.issue.ignore.multicriteria="e1" `
|
||||
/d:sonar.issue.ignore.multicriteria.e1.ruleKey="csharpsquid:S1944,csharpsquid:S2053,csharpsquid:S2222,csharpsquid:S2259,csharpsquid:S2583,csharpsquid:S2589,csharpsquid:S3329,csharpsquid:S3655,csharpsquid:S3900,csharpsquid:S3949,csharpsquid:S3966,csharpsquid:S4158,csharpsquid:S4347,csharpsquid:S5773,csharpsquid:S6781" `
|
||||
/d:sonar.issue.ignore.multicriteria.e1.resourceKey="**/*.cs" `
|
||||
/d:sonar.verbose="true"
|
||||
|
||||
- name: Build Projects
|
||||
id: build
|
||||
continue-on-error: true
|
||||
run: |
|
||||
dotnet build --no-restore --configuration Debug
|
||||
dotnet build ./lib/quantalib.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Averages/_Averages.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Statistics/_Statistics.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Volatility/_Volatility.csproj --configuration Release --nologo
|
||||
dotnet build ./SyntheticVendor/SyntheticVendor.csproj --configuration Release --nologo
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Build failed" }
|
||||
|
||||
- name: Check Build Status
|
||||
if: steps.build.outcome == 'failure'
|
||||
run: exit 1
|
||||
|
||||
- name: Run Tests with Coverage
|
||||
id: tests
|
||||
continue-on-error: true
|
||||
run: |
|
||||
dotnet test --no-build --configuration Debug /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
|
||||
dotnet-coverage collect "dotnet test" -f xml -o "coverage.xml"
|
||||
dotnet dotcover test Tests/Tests.csproj --dcReportType=HTML --dcoutput=./dotcover.html
|
||||
dotnet dotcover test Tests/Tests.csproj --dcReportType=DetailedXML --dcoutput=./dotcover.xml --verbosity=Detailed
|
||||
dotnet test -p:CollectCoverage=true --collect:"XPlat Code Coverage" --results-directory "./"
|
||||
|
||||
- name: Generate Coverage Report
|
||||
run: |
|
||||
reportgenerator -reports:*cover*.xml -targetdir:./coverage-report
|
||||
|
||||
- name: Upload Coverage Reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-reports
|
||||
path: |
|
||||
**/TestResults
|
||||
**/coverage-report
|
||||
**/*cover*.xml
|
||||
**/dotcover.*
|
||||
|
||||
- name: End SonarCloud Analysis
|
||||
if: always()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
shell: powershell
|
||||
run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
|
||||
|
||||
- name: Upload Coverage to Codacy
|
||||
uses: codacy/codacy-coverage-reporter-action@v1
|
||||
with:
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
coverage-reports: '*cover*.xml'
|
||||
|
||||
- name: Upload Coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: 'cover*'
|
||||
verbose: true
|
||||
|
||||
CodeQL:
|
||||
timeout-minutes: 30
|
||||
# ==============================================================================
|
||||
# 1) ReSharper InspectCode -> SARIF artifact
|
||||
# ==============================================================================
|
||||
ReSharper_Analysis:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
actions: write
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: 'csharp'
|
||||
queries: security-and-quality
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
tools: linked
|
||||
cache: true
|
||||
cache-dependency-path: |
|
||||
**/packages.lock.json
|
||||
**/*.csproj
|
||||
**/*.sln
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration Debug
|
||||
- name: Prepare SARIF directory
|
||||
run: mkdir -p .sarif
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
- name: Install JetBrains ReSharper GlobalTools
|
||||
run: |
|
||||
dotnet tool update --global JetBrains.ReSharper.GlobalTools || \
|
||||
dotnet tool install --global JetBrains.ReSharper.GlobalTools
|
||||
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Run ReSharper InspectCode (SARIF)
|
||||
run: |
|
||||
set +e
|
||||
jb inspectcode QuanTAlib.sln \
|
||||
--format=sarif \
|
||||
--output=.sarif/resharper.sarif
|
||||
rc=$?
|
||||
set -e
|
||||
|
||||
# jb may return non-zero for findings/config; missing SARIF is the real failure signal
|
||||
if [ ! -f ".sarif/resharper.sarif" ]; then
|
||||
echo "ERROR: ReSharper SARIF not generated (exit code: $rc)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "ReSharper SARIF generated (exit code: $rc)"
|
||||
ls -lh .sarif/resharper.sarif
|
||||
|
||||
- name: Upload SARIF artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
output: results
|
||||
upload: true
|
||||
name: sarif-resharper
|
||||
path: .sarif/resharper.sarif
|
||||
retention-days: 7
|
||||
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/dotnet@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: '' # Clear the LD_PRELOAD to avoid CodeQL conflicts
|
||||
with:
|
||||
args: |
|
||||
--file=./lib/quantalib.csproj
|
||||
--severity-threshold=low
|
||||
--detection-depth=4
|
||||
--package-manager=nuget
|
||||
|
||||
- name: Run Snyk on Solution
|
||||
uses: snyk/actions/dotnet@master
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: ''
|
||||
with:
|
||||
args: |
|
||||
--file=QuanTAlib.sln
|
||||
--all-projects
|
||||
--detection-depth=4
|
||||
|
||||
- name: Run Snyk IaC
|
||||
uses: snyk/actions/iac@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
LD_PRELOAD: ''
|
||||
with:
|
||||
args: |
|
||||
--severity-threshold=low
|
||||
|
||||
build_publish:
|
||||
timeout-minutes: 20
|
||||
needs: [Code_Coverage, CodeQL]
|
||||
if: |
|
||||
success() &&
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
# ==============================================================================
|
||||
# 2) Snyk Security Scan -> SARIF artifact
|
||||
# ==============================================================================
|
||||
Snyk_Scan:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
cache: true
|
||||
cache-dependency-path: |
|
||||
**/packages.lock.json
|
||||
**/*.csproj
|
||||
**/*.sln
|
||||
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0
|
||||
with:
|
||||
versionSpec: '6.x'
|
||||
includePrerelease: true
|
||||
- name: Install Snyk CLI
|
||||
uses: snyk/actions/setup@806182742461562b67788a64410098c9d9b96adb
|
||||
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v0
|
||||
with:
|
||||
useConfigFile: true
|
||||
updateAssemblyInfo: false
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: ${{ runner.os }}-nuget-
|
||||
- name: Prepare SARIF directory
|
||||
run: mkdir -p .sarif
|
||||
|
||||
- name: Build projects
|
||||
run: |
|
||||
dotnet restore
|
||||
dotnet build ./lib/quantalib.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Averages/_Averages.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Statistics/_Statistics.csproj --configuration Release --nologo
|
||||
dotnet build ./quantower/Volatility/_Volatility.csproj --configuration Release --nologo
|
||||
dotnet build ./SyntheticVendor/SyntheticVendor.csproj --configuration Release --nologo
|
||||
|
||||
- name: Create or Update Development Release
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
- name: Run Snyk Security Scan (SARIF)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
run: |
|
||||
gh release delete development --yes || true
|
||||
gh release create development \
|
||||
--title "Development Build" \
|
||||
--notes "Latest development build from commit ${{ github.sha }}" \
|
||||
--prerelease \
|
||||
--target ${{ github.sha }} \
|
||||
lib/bin/Release/QuanTAlib.dll \
|
||||
quantower/Averages/bin/Release/Averages.dll \
|
||||
quantower/Statistics/bin/Release/Statistics.dll \
|
||||
quantower/Volatility/bin/Release/Volatility.dll \
|
||||
SyntheticVendor/bin/Release/SyntheticVendor.dll
|
||||
if [ -z "${SNYK_TOKEN:-}" ]; then
|
||||
echo "SNYK_TOKEN not set. Skipping Snyk scan."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: Push prerelease package to myget.org
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
continue-on-error: true
|
||||
id: myget-push
|
||||
run: |
|
||||
dotnet nuget push 'lib/bin/Release/QuanTAlib.*.nupkg' \
|
||||
--source https://www.myget.org/F/quantalib/api/v3/index.json \
|
||||
--force-english-output \
|
||||
--api-key ${{ secrets.MYGET_DEPLOY_KEY_QUANTALIB }}
|
||||
set +e
|
||||
snyk test --all-projects --sarif-file-output=.sarif/snyk.sarif
|
||||
rc=$?
|
||||
set -e
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: github.ref == 'refs/heads/main'
|
||||
# Snyk exit codes: 0 = no issues, 1 = issues found, >1 = error
|
||||
if [ $rc -gt 1 ]; then
|
||||
echo "ERROR: Snyk scan failed (exit code: $rc)"
|
||||
exit $rc
|
||||
fi
|
||||
|
||||
if [ ! -f ".sarif/snyk.sarif" ]; then
|
||||
echo "ERROR: Snyk SARIF not generated"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Snyk SARIF generated (exit code: $rc)"
|
||||
ls -lh .sarif/snyk.sarif
|
||||
|
||||
- name: Upload SARIF artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sarif-snyk
|
||||
path: .sarif/snyk.sarif
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
|
||||
# ==============================================================================
|
||||
# 3) Semgrep Security Scan -> SARIF artifact
|
||||
# ==============================================================================
|
||||
Semgrep_Scan:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Prepare SARIF directory
|
||||
run: mkdir -p .sarif
|
||||
|
||||
- name: Run Semgrep (SARIF)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
run: |
|
||||
gh release create v${{ steps.gitversion.outputs.MajorMinorPatch }} \
|
||||
--title "Release from commit ${{ steps.gitversion.outputs.MajorMinorPatch }}" \
|
||||
--notes "Release notes for this version." \
|
||||
quantower/Averages/bin/Release/Averages.dll \
|
||||
quantower/Statistics/bin/Release/Statistics.dll \
|
||||
quantower/Volatility/bin/Release/Volatility.dll \
|
||||
SyntheticVendor/bin/Release/SyntheticVendor.dll
|
||||
pip install --quiet semgrep
|
||||
|
||||
- name: Push release package to nuget.org
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
set +e
|
||||
if [ -n "${SEMGREP_APP_TOKEN:-}" ]; then
|
||||
echo "Running Semgrep with managed policies..."
|
||||
semgrep ci --sarif --output=.sarif/semgrep.sarif
|
||||
else
|
||||
echo "Running Semgrep with OSS rules..."
|
||||
semgrep scan \
|
||||
--config=auto \
|
||||
--sarif \
|
||||
--output=.sarif/semgrep.sarif \
|
||||
--exclude='**/bin/**' \
|
||||
--exclude='**/obj/**' \
|
||||
--exclude='**/*.Tests.cs' \
|
||||
--exclude='**/Mocks/**' \
|
||||
--exclude='**/perf/**' \
|
||||
--exclude='**/quantower/**' \
|
||||
.
|
||||
fi
|
||||
rc=$?
|
||||
set -e
|
||||
|
||||
if [ -f ".sarif/semgrep.sarif" ]; then
|
||||
echo "Semgrep SARIF generated (exit code: $rc):"
|
||||
ls -lh .sarif/semgrep.sarif
|
||||
else
|
||||
echo "WARNING: Semgrep SARIF not generated"
|
||||
fi
|
||||
|
||||
- name: Upload SARIF artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sarif-semgrep
|
||||
path: .sarif/semgrep.sarif
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
|
||||
# ==============================================================================
|
||||
# 4) Build, Test, Coverage, SonarCloud & Roslyn SARIF
|
||||
# ==============================================================================
|
||||
Sonar_Analysis:
|
||||
needs: [ReSharper_Analysis, Snyk_Scan, Semgrep_Scan]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
pull-requests: read
|
||||
checks: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
cache: true
|
||||
cache-dependency-path: |
|
||||
**/packages.lock.json
|
||||
**/*.csproj
|
||||
**/*.sln
|
||||
|
||||
- name: Set up JDK 17 (for SonarCloud)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: zulu
|
||||
|
||||
- name: Install Tools
|
||||
run: |
|
||||
dotnet nuget push 'lib/bin/Release/QuanTAlib.*.nupkg' \
|
||||
--source https://api.nuget.org/v3/index.json \
|
||||
--skip-duplicate \
|
||||
--api-key ${{ secrets.NUGET_DEPLOY_KEY_QUANTLIB }}
|
||||
dotnet tool install --global dotnet-reportgenerator-globaltool
|
||||
dotnet tool install --global dotnet-sonarscanner
|
||||
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Check for SonarCloud token
|
||||
id: check_sonar
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
if [ -z "${SONAR_TOKEN:-}" ]; then
|
||||
echo "SONAR_TOKEN not set. Skipping SonarCloud."
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Prepare SARIF directory
|
||||
run: mkdir -p .sarif
|
||||
|
||||
- name: Download External SARIFs
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: sarif-*
|
||||
path: .sarif
|
||||
merge-multiple: true
|
||||
|
||||
- name: Build SARIF list for SonarCloud
|
||||
run: |
|
||||
# Keep SonarCloud focused on its native analyzers + security tools.
|
||||
# Importing compiler/analyzer SARIF (Roslyn/JetBrains) tends to explode "External issues".
|
||||
paths=()
|
||||
for f in .sarif/snyk.sarif .sarif/semgrep.sarif; do
|
||||
if [ -f "$f" ]; then
|
||||
paths+=("$f")
|
||||
fi
|
||||
done
|
||||
|
||||
IFS=,
|
||||
echo "SONAR_SARIF_PATHS=${paths[*]}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Begin SonarCloud Analysis
|
||||
if: steps.check_sonar.outputs.skip != 'true'
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
args=(
|
||||
"/k:mihakralj_QuanTAlib"
|
||||
"/o:mihakralj-quantalib"
|
||||
"/d:sonar.token=$SONAR_TOKEN"
|
||||
"/d:sonar.host.url=https://sonarcloud.io"
|
||||
"/d:sonar.cs.opencover.reportsPaths=TestResults/**/coverage.opencover.xml"
|
||||
"/d:sonar.cs.vstest.reportsPaths=TestResults/**/*.trx"
|
||||
"/d:sonar.coverage.exclusions=**Tests.cs,**/*.md,**/*.html,**/*.css,**/docs/**/*,**/archive/**/*,**/notebooks/**/*,**/obj/**/*,**/bin/**/*"
|
||||
"/d:sonar.exclusions=**/TestResults/**/*,**/bin/**/*,**/obj/**/*,**/*.html,**/coverage/**/*,**/CoverageReport/**/*,**/*.md,**/*.css,**/docs/**/*,**/archive/**/*,**/notebooks/**/*"
|
||||
"/d:sonar.test.exclusions=**Tests.cs,**/obj/**/*,**/bin/**/*"
|
||||
"/d:sonar.scanner.scanAll=false"
|
||||
)
|
||||
|
||||
if [ -n "${SONAR_SARIF_PATHS:-}" ]; then
|
||||
args+=("/d:sonar.sarifReportPaths=$SONAR_SARIF_PATHS")
|
||||
fi
|
||||
|
||||
dotnet sonarscanner begin "${args[@]}"
|
||||
|
||||
- name: Build Solution with Roslyn SARIF
|
||||
run: |
|
||||
dotnet build QuanTAlib.sln \
|
||||
--no-restore \
|
||||
--configuration Debug \
|
||||
--nologo \
|
||||
-m:1 \
|
||||
-p:TreatWarningsAsErrors=false \
|
||||
-p:ErrorLog="$(pwd)/.sarif/roslyn.sarif;version=2.1"
|
||||
|
||||
- name: Run Tests with Coverage
|
||||
run: |
|
||||
dotnet test QuanTAlib.sln \
|
||||
--no-build \
|
||||
--configuration Debug \
|
||||
--collect:"XPlat Code Coverage;Format=opencover,cobertura,lcov" \
|
||||
--results-directory ./TestResults \
|
||||
--logger "trx;LogFileName=test_results.trx"
|
||||
|
||||
- name: Merge Coverage Reports
|
||||
run: |
|
||||
mkdir -p coverage-merged
|
||||
|
||||
reportgenerator \
|
||||
"-reports:TestResults/**/coverage.opencover.xml;TestResults/**/coverage.cobertura.xml;TestResults/**/coverage.info" \
|
||||
"-targetdir:coverage-merged" \
|
||||
"-reporttypes:Cobertura;lcov"
|
||||
|
||||
echo "Merged coverage outputs:"
|
||||
ls -la coverage-merged || true
|
||||
|
||||
if [ ! -f "coverage-merged/Cobertura.xml" ]; then
|
||||
echo "ERROR: Cobertura.xml not generated (Codacy coverage will be missing)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: End SonarCloud Analysis
|
||||
if: steps.check_sonar.outputs.skip != 'true'
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"
|
||||
|
||||
- name: Upload Coverage Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-reports
|
||||
path: coverage-merged/
|
||||
retention-days: 7
|
||||
|
||||
- name: Upload Roslyn SARIF Artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sarif-roslyn
|
||||
path: .sarif/roslyn.sarif
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
|
||||
# ==============================================================================
|
||||
# 5) Codacy Upload (SARIF + Coverage)
|
||||
# ==============================================================================
|
||||
Codacy_Upload:
|
||||
needs: [ReSharper_Analysis, Snyk_Scan, Semgrep_Scan, Sonar_Analysis]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
if: always()
|
||||
steps:
|
||||
- name: Check for Codacy token
|
||||
id: check_token
|
||||
env:
|
||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
run: |
|
||||
if [ -z "${CODACY_PROJECT_TOKEN:-}" ]; then
|
||||
echo "CODACY_PROJECT_TOKEN not set. Skipping Codacy uploads."
|
||||
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Download SARIF artifacts
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: sarif-*
|
||||
path: sarif
|
||||
|
||||
- name: Download Coverage Reports
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: coverage-reports
|
||||
path: coverage-merged
|
||||
|
||||
- name: List artifacts
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
run: |
|
||||
echo "SARIF files:"
|
||||
find sarif -name "*.sarif" -type f -maxdepth 4 -print -exec ls -lh {} \; || true
|
||||
echo ""
|
||||
echo "Coverage files:"
|
||||
ls -la coverage-merged || true
|
||||
|
||||
- name: Install Codacy CLI v2
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Install Codacy CLI using official bootstrap script
|
||||
echo "Installing Codacy CLI v2..."
|
||||
|
||||
sudo curl -Ls https://raw.githubusercontent.com/codacy/codacy-cli-v2/main/codacy-cli.sh -o /usr/local/bin/codacy-cli
|
||||
sudo chmod +x /usr/local/bin/codacy-cli
|
||||
|
||||
# Script will fetch binary if needed
|
||||
codacy-cli version
|
||||
|
||||
- name: Upload SARIF files to Codacy
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
env:
|
||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
shopt -s nullglob globstar
|
||||
files=(sarif/**/*.sarif)
|
||||
|
||||
if [ ${#files[@]} -eq 0 ]; then
|
||||
echo "No SARIF files found. Nothing to upload."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Uploading ${#files[@]} SARIF file(s) to Codacy with commit: ${COMMIT_UUID}"
|
||||
for sarif_file in "${files[@]}"; do
|
||||
echo "--- Uploading: $sarif_file ---"
|
||||
# Using short flags per codacy-cli-v2 docs:
|
||||
# -s: SARIF file path
|
||||
# -c: commit UUID
|
||||
# -t: project token
|
||||
codacy-cli upload \
|
||||
-s "$sarif_file" \
|
||||
-c "$COMMIT_UUID" \
|
||||
-t "$CODACY_PROJECT_TOKEN" \
|
||||
|| echo "WARNING: failed to upload $sarif_file"
|
||||
done
|
||||
|
||||
- name: Upload Coverage to Codacy
|
||||
if: steps.check_token.outputs.skip != 'true'
|
||||
env:
|
||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
curl -Ls https://coverage.codacy.com/get.sh -o codacy-coverage.sh
|
||||
chmod +x codacy-coverage.sh
|
||||
|
||||
if [ -f "coverage-merged/Cobertura.xml" ]; then
|
||||
./codacy-coverage.sh report -r "coverage-merged/Cobertura.xml"
|
||||
else
|
||||
echo "Cobertura.xml not found. Skipping coverage upload."
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
name: Release Workflow
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# inputs:
|
||||
# release_type:
|
||||
# description: "Release type"
|
||||
# type: choice
|
||||
# options:
|
||||
# - development
|
||||
# - production
|
||||
# default: development
|
||||
|
||||
permissions: {}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: "10.x"
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
DOTNET_NOLOGO: true
|
||||
|
||||
jobs:
|
||||
# ==============================================================================
|
||||
# Publish Package (manual trigger only)
|
||||
# ==============================================================================
|
||||
Publish_Package:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
cache: true
|
||||
cache-dependency-path: |
|
||||
**/packages.lock.json
|
||||
**/*.csproj
|
||||
**/*.sln
|
||||
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v4.2.0
|
||||
with:
|
||||
versionSpec: "6.x"
|
||||
includePrerelease: true
|
||||
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v4.2.0
|
||||
with:
|
||||
updateAssemblyInfo: false
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
dotnet build ./lib/quantalib.csproj --configuration Release --no-restore --nologo
|
||||
dotnet build ./quantower/Momentum.csproj --configuration Release --no-restore --nologo
|
||||
dotnet build ./quantower/Trends.csproj --configuration Release --no-restore --nologo
|
||||
dotnet build ./quantower/Volume.csproj --configuration Release --no-restore --nologo
|
||||
|
||||
- name: Pack NuGet
|
||||
run: |
|
||||
dotnet pack ./lib/quantalib.csproj \
|
||||
--configuration Release \
|
||||
--no-build \
|
||||
-p:ContinuousIntegrationBuild=true \
|
||||
-p:PackageVersion=${{ steps.gitversion.outputs.SemVer }}
|
||||
|
||||
ls -lh lib/bin/Release/*.nupkg || true
|
||||
|
||||
- name: Create Development Release
|
||||
if: inputs.release_type == 'development'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh release delete development --yes 2>/dev/null || true
|
||||
git push --delete origin refs/tags/development 2>/dev/null || true
|
||||
|
||||
gh release create development \
|
||||
--title "Development Build" \
|
||||
--notes "Latest development build from commit ${{ github.sha }}" \
|
||||
--prerelease \
|
||||
--target ${{ github.sha }} \
|
||||
lib/bin/Release/*.nupkg \
|
||||
lib/bin/Release/**/QuanTAlib.dll \
|
||||
quantower/bin/Release/**/*.dll
|
||||
|
||||
- name: Push to MyGet
|
||||
if: inputs.release_type == 'development'
|
||||
continue-on-error: true
|
||||
env:
|
||||
MYGET_API_KEY: ${{ secrets.MYGET_DEPLOY_KEY_QUANTALIB }}
|
||||
run: |
|
||||
if [ -z "${MYGET_API_KEY:-}" ]; then
|
||||
echo "MYGET_DEPLOY_KEY_QUANTALIB not set. Skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
dotnet nuget push 'lib/bin/Release/*.nupkg' \
|
||||
--source https://www.myget.org/F/quantalib/api/v3/index.json \
|
||||
--skip-duplicate \
|
||||
--api-key "$MYGET_API_KEY"
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: inputs.release_type == 'production'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh release create "v${{ steps.gitversion.outputs.MajorMinorPatch }}" \
|
||||
--title "Release ${{ steps.gitversion.outputs.MajorMinorPatch }}" \
|
||||
--generate-notes \
|
||||
lib/bin/Release/*.nupkg \
|
||||
quantower/bin/Release/**/*.dll
|
||||
|
||||
- name: Push to NuGet
|
||||
if: inputs.release_type == 'production'
|
||||
env:
|
||||
NUGET_API_KEY: ${{ secrets.NUGET_DEPLOY_KEY_QUANTLIB }}
|
||||
run: |
|
||||
if [ -z "${NUGET_API_KEY:-}" ]; then
|
||||
echo "NUGET_DEPLOY_KEY_QUANTLIB not set. Failing publish."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dotnet nuget push 'lib/bin/Release/*.nupkg' \
|
||||
--source https://api.nuget.org/v3/index.json \
|
||||
--skip-duplicate \
|
||||
--api-key "$NUGET_API_KEY"
|
||||
@@ -0,0 +1,54 @@
|
||||
name: Deploy Docsify to GitHub Pages
|
||||
|
||||
on:
|
||||
#push:
|
||||
# branches: ["main"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
with:
|
||||
# Explicitly disable Jekyll
|
||||
enabler_jekyll: false
|
||||
|
||||
- name: List files (Debug)
|
||||
run: ls -R
|
||||
|
||||
- name: Ensure .nojekyll exists in root
|
||||
run: |
|
||||
if [ ! -f .nojekyll ]; then
|
||||
echo "Creating .nojekyll file"
|
||||
touch .nojekyll
|
||||
else
|
||||
echo ".nojekyll already exists"
|
||||
fi
|
||||
ls -la .nojekyll
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository so Docsify can access 'lib/' and other root files
|
||||
path: '.'
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
Reference in New Issue
Block a user