├── README.md ├── Quantum.Framework.GenericProperties.dll ├── CryptoShark ├── Custom-Icon-Design-Flatastic-11-Cash.ico ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Enum │ ├── OrderSide.cs │ └── OrderType.cs ├── Utility │ ├── Enum │ │ └── SettingName.cs │ ├── Events │ │ └── FileLoggedEventArgs.cs │ ├── MathExtensions.cs │ ├── Constants.cs │ ├── EnhancedForm.cs │ ├── ServiceHelper.cs │ ├── FileLogger.cs │ ├── SettingsManager │ │ ├── Data │ │ │ └── SettingsItem.cs │ │ └── Manager │ │ │ └── SettingsManager.cs │ ├── SettingsHelper.cs │ ├── JObjectHelper.cs │ ├── EncryptionHelper.cs │ └── BinanceApiHelper.cs ├── Data │ ├── StatisticData.cs │ ├── MarketOrderResult.cs │ └── OrderItem.cs ├── Model │ ├── CryptoSharkModel.cs │ ├── CryptoSharkModel.Designer.cs │ ├── CryptoSharkModel.edmx.diagram │ ├── CryptoSharkModel.Context.cs │ ├── SellOrder.cs │ ├── Symbol.cs │ ├── CryptoSharkModel.edmx │ ├── CryptoSharkModel.Context.tt │ └── CryptoSharkModel.tt ├── Program.cs ├── Hunting │ ├── Data │ │ ├── HuntingType.cs │ │ ├── HuntingTypeManager.cs │ │ └── Hunting.cs │ └── VolumeHunting │ │ └── VolumeHuntingType.cs ├── packages.config ├── Forms │ ├── FormSettings.cs │ ├── FormSettings.Designer.cs │ ├── FormMain.cs │ └── FormMain.Designer.cs ├── App.config └── CryptoShark.csproj ├── LICENSE ├── CryptoShark.sln └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # Binance-CryptoShark 2 | Hunting for pumping coins with Binance API and buy&sell them instantly like a trading-bot 3 | -------------------------------------------------------------------------------- /Quantum.Framework.GenericProperties.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcadeindy/Binance-CryptoShark/HEAD/Quantum.Framework.GenericProperties.dll -------------------------------------------------------------------------------- /CryptoShark/Custom-Icon-Design-Flatastic-11-Cash.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcadeindy/Binance-CryptoShark/HEAD/CryptoShark/Custom-Icon-Design-Flatastic-11-Cash.ico -------------------------------------------------------------------------------- /CryptoShark/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CryptoShark/Enum/OrderSide.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CryptoShark.Enum 8 | { 9 | public enum OrderSide 10 | { 11 | Buy, 12 | Sell 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /CryptoShark/Utility/Enum/SettingName.cs: -------------------------------------------------------------------------------- 1 | namespace CryptoShark.Utility.Enum 2 | { 3 | public class SettingName 4 | { 5 | public static string API_KEY => "apiKey"; 6 | public static string SECRET_KEY => "secretKey"; 7 | public static string TRADING_ENABLED => "tradingEnabled"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CryptoShark/Enum/OrderType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CryptoShark.Enum 8 | { 9 | public enum OrderType 10 | { 11 | Limit, 12 | StopLimit, 13 | Market 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CryptoShark/Utility/Events/FileLoggedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CryptoShark.Utility.Events 8 | { 9 | public class FileLoggedEventArgs : EventArgs 10 | { 11 | public string Text { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CryptoShark/Data/StatisticData.cs: -------------------------------------------------------------------------------- 1 | using Binance; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CryptoShark.Data 9 | { 10 | public class StatisticData 11 | { 12 | public Dictionary Statistics { get; set; } 13 | public DateTime DateTime { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CryptoShark/Data/MarketOrderResult.cs: -------------------------------------------------------------------------------- 1 | using Binance; 2 | using System; 3 | 4 | namespace CryptoShark.Data 5 | { 6 | public class MarketOrderResult 7 | { 8 | public Symbol Symbol { get; set; } 9 | public decimal Quantity { get; set; } 10 | public decimal AveragePrice { get; set; } 11 | public decimal Total => (Quantity * AveragePrice).RoundTo(7); 12 | public OrderSide Side { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | -------------------------------------------------------------------------------- /CryptoShark/Program.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Forms; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace CryptoShark 9 | { 10 | static class Program 11 | { 12 | /// 13 | /// The main entry point for the application. 14 | /// 15 | [STAThread] 16 | static void Main() 17 | { 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | Application.Run(new FormMain()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /CryptoShark/Data/OrderItem.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Enum; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CryptoShark.Data 9 | { 10 | public class OrderItem 11 | { 12 | public OrderSide Side { get; set; } 13 | public string Symbol { get; set; } 14 | //public OrderType OrderType { get; set; } 15 | public decimal Quantity { get; set; } 16 | public decimal Price { get; set; } 17 | public decimal ExecutedQuantity { get; set; } 18 | public decimal StopPrice { get; set; } 19 | public decimal Total => (Quantity * Price).RoundTo(6); 20 | public DateTime Date { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CryptoShark/Hunting/Data/HuntingType.cs: -------------------------------------------------------------------------------- 1 | using Quantum.Framework.GenericProperties.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CryptoShark.Hunting.Data 9 | { 10 | public class HuntingType 11 | { 12 | public virtual string TypeName { get; } 13 | public virtual string DisplayName { get; } 14 | 15 | public virtual Hunting CreateInstance() 16 | { 17 | return null; 18 | } 19 | 20 | public virtual GenericPropertyCollection GetProperties() 21 | { 22 | return new GenericPropertyCollection(); 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return DisplayName; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.Designer.cs: -------------------------------------------------------------------------------- 1 | // T4 code generation is enabled for model 'C:\Projects\CryptoShark\source\CryptoShark\CryptoShark\Model\CryptoSharkModel.edmx'. 2 | // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer 3 | // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model 4 | // is open in the designer. 5 | 6 | // If no context and entity classes have been generated, it may be because you created an empty model but 7 | // have not yet chosen which version of Entity Framework to use. To generate a context class and entity 8 | // classes for your model, open the model in the designer, right-click on the designer surface, and 9 | // select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation 10 | // Item...'. -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.edmx.diagram: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CryptoShark/Utility/MathExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace System 8 | { 9 | public static class MathExtensions 10 | { 11 | 12 | public static decimal RoundTo(this decimal value, int decimals) 13 | { 14 | //var multiplier = (decimal)Math.Pow(10, decimals); 15 | //return Math.Truncate(value * multiplier) / multiplier; 16 | return Math.Round(value, decimals); 17 | } 18 | 19 | public static int DecimalPlaces(this decimal value) 20 | { 21 | var decimalPlaces = 0; 22 | var temp = value; 23 | 24 | while (temp < 1) 25 | { 26 | temp = temp * 10; 27 | decimalPlaces++; 28 | } 29 | 30 | return decimalPlaces; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CryptoShark/Utility/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CryptoShark.Utility 9 | { 10 | public class Constants 11 | { 12 | public static string SETTINGS_FILENAME => "settings.json"; 13 | 14 | public const string ENCRYPTION_SALT = "#kc!!__-!!oguz123@@!"; 15 | 16 | public static string HUNTING_PROPERTIES_POSTFIX = ".settings"; 17 | public static string GENERAL_PROPERTIES = "general"; 18 | 19 | public static string STATUS_WORKING => "WORKING"; 20 | public static string STATUS_FILLED => "FILLED"; 21 | public static string STATUS_STOPLOSS_EXECUTED => "STOPLOSS_EXECUTED"; 22 | public static string STATUS_CANCELLED => "CANCELLED"; 23 | 24 | public static Color Green => Color.FromArgb(115, 201, 33); 25 | public static Color Red => Color.FromArgb(202, 44, 120); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CryptoShark/Hunting/Data/HuntingTypeManager.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Hunting.VolumeHunting; 2 | using Quantum.Framework.GenericProperties.Utilities; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace CryptoShark.Hunting.Data 10 | { 11 | class HuntingTypeManager : Singleton 12 | { 13 | public List HuntingTypes { get; set; } 14 | 15 | public HuntingTypeManager() 16 | { 17 | HuntingTypes = new List() 18 | { 19 | new VolumeHuntingType() 20 | }; 21 | } 22 | 23 | public HuntingType GetHuntingType(string typeName) 24 | { 25 | foreach (var huntingServiceType in HuntingTypes) 26 | { 27 | if (huntingServiceType.TypeName == typeName) 28 | return huntingServiceType; 29 | } 30 | 31 | return null; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Oguz Kucukcanbaz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.Context.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace CryptoShark.Model 11 | { 12 | using System; 13 | using System.Data.Entity; 14 | using System.Data.Entity.Infrastructure; 15 | 16 | public partial class CryptoSharkEntities : DbContext 17 | { 18 | public CryptoSharkEntities() 19 | : base("name=CryptoSharkEntities") 20 | { 21 | } 22 | 23 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 24 | { 25 | throw new UnintentionalCodeFirstException(); 26 | } 27 | 28 | public virtual DbSet SellOrders { get; set; } 29 | public virtual DbSet Symbols { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CryptoShark.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CryptoShark", "CryptoShark\CryptoShark.csproj", "{310151A0-2089-42B6-A26D-88F8A72A3131}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {310151A0-2089-42B6-A26D-88F8A72A3131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {310151A0-2089-42B6-A26D-88F8A72A3131}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {310151A0-2089-42B6-A26D-88F8A72A3131}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {310151A0-2089-42B6-A26D-88F8A72A3131}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {53369DDC-00FD-4F92-870E-18B8AECC35D3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /CryptoShark/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CryptoShark.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CryptoShark/Utility/EnhancedForm.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace CryptoShark.Utility 4 | { 5 | public class EnhancedForm : Form 6 | { 7 | public void ShowWarning(string message) 8 | { 9 | MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); 10 | } 11 | public void ShowError(string message) 12 | { 13 | MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 14 | } 15 | 16 | public void ShowInfo(string message) 17 | { 18 | MessageBox.Show(this, message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); 19 | } 20 | 21 | public DialogResult ShowQuestion(string message, bool showCancel = false) 22 | { 23 | if (showCancel) 24 | return MessageBox.Show(this, message, "Question", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); 25 | else 26 | return MessageBox.Show(this, message, "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question); 27 | } 28 | 29 | public EnhancedForm() : base() 30 | { 31 | 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CryptoShark/Model/SellOrder.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace CryptoShark.Model 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class SellOrder 16 | { 17 | public int Id { get; set; } 18 | public int SymbolId { get; set; } 19 | public long OrderId { get; set; } 20 | public decimal Quantity { get; set; } 21 | public decimal Price { get; set; } 22 | public decimal StopLossPrice { get; set; } 23 | public Nullable StopLossAt { get; set; } 24 | public Nullable StopLossExecutedPrice { get; set; } 25 | public string Status { get; set; } 26 | public System.DateTime Date { get; set; } 27 | 28 | public virtual Symbol Symbol { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CryptoShark/Utility/ServiceHelper.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Text; 8 | 9 | namespace CryptoShark.Utility 10 | { 11 | public class ServiceHelper 12 | { 13 | private const string CURRENCY_USD_TO_TRY_URL = "https://www.doviz.com/api/v1/currencies/USD/latest"; 14 | 15 | public static double USDtoTRY() 16 | { 17 | try 18 | { 19 | var request = (HttpWebRequest)WebRequest.Create(CURRENCY_USD_TO_TRY_URL); 20 | request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; 21 | 22 | using (var response = (HttpWebResponse)request.GetResponse()) 23 | using (var stream = response.GetResponseStream()) 24 | using (var reader = new StreamReader(stream)) 25 | { 26 | var jObjectTRY = JObject.Parse(reader.ReadToEnd()); 27 | return Convert.ToDouble(jObjectTRY["buying"]); 28 | } 29 | } 30 | catch (Exception) 31 | { 32 | return 0; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CryptoShark/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CryptoShark")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CryptoShark")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("310151a0-2089-42b6-a26d-88f8a72a3131")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CryptoShark/Model/Symbol.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace CryptoShark.Model 11 | { 12 | using System; 13 | using System.Collections.Generic; 14 | 15 | public partial class Symbol 16 | { 17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 18 | public Symbol() 19 | { 20 | this.SellOrders = new HashSet(); 21 | } 22 | 23 | public int Id { get; set; } 24 | public string BaseAsset { get; set; } 25 | public string QuoteAsset { get; set; } 26 | public decimal QuantityIncrement { get; set; } 27 | public decimal PriceIncrement { get; set; } 28 | public decimal NotionalMinimumValue { get; set; } 29 | 30 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 31 | public virtual ICollection SellOrders { get; set; } 32 | 33 | public override string ToString() 34 | { 35 | return BaseAsset + QuoteAsset; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CryptoShark/Utility/FileLogger.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Utility.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace CryptoShark.Utility 10 | { 11 | public class FileLogger 12 | { 13 | public const string DEFAULT_LOG_FILENAME_PREFIX = "CryptoSharkLog_"; 14 | public const string DEFAULT_LOG_FILEPATH = "CryptoSharkLogs"; 15 | 16 | public event EventHandler OnFileLogged; 17 | 18 | private static string fileName; 19 | 20 | #region Singleton Members 21 | private static FileLogger instance; 22 | public static FileLogger Instance 23 | { 24 | get 25 | { 26 | if (instance == null) 27 | { 28 | instance = new FileLogger(); 29 | fileName = Path.Combine(DEFAULT_LOG_FILEPATH, DEFAULT_LOG_FILENAME_PREFIX + DateTime.Now.ToString("dd.MM.yyyy_HH.mm") + ".txt"); 30 | 31 | if (!Directory.Exists(DEFAULT_LOG_FILEPATH)) 32 | Directory.CreateDirectory(DEFAULT_LOG_FILEPATH); 33 | } 34 | return instance; 35 | } 36 | } 37 | #endregion 38 | 39 | public void WriteLog(string text, bool withTimeStamp = true, bool invokeEvent = true) 40 | { 41 | if (!File.Exists(fileName)) 42 | { 43 | var stream = File.CreateText(fileName); 44 | stream.Close(); 45 | } 46 | 47 | if (withTimeStamp) 48 | text += " [" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss") + "]"; 49 | 50 | if (invokeEvent) 51 | OnFileLogged?.Invoke(this, new FileLoggedEventArgs() 52 | { 53 | Text = text 54 | }); 55 | 56 | File.AppendAllText(fileName, text + Environment.NewLine); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /CryptoShark/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /CryptoShark/Utility/SettingsManager/Data/SettingsItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CryptoShark.Utility.SettingsManager.Data 9 | { 10 | public class SettingsItem 11 | { 12 | public event EventHandler OnChange; 13 | 14 | public string Name { get; set; } 15 | 16 | private object value_; 17 | 18 | public object Value 19 | { 20 | get { return value_; } 21 | set 22 | { 23 | value_ = value; 24 | 25 | OnChange?.Invoke(this, EventArgs.Empty); 26 | } 27 | } 28 | 29 | public SettingsItem() 30 | : this(string.Empty) 31 | { 32 | 33 | } 34 | 35 | public SettingsItem(string name) 36 | { 37 | Name = name; 38 | } 39 | 40 | public int ToInt32() 41 | { 42 | return ToInteger(0); 43 | } 44 | 45 | public int ToInteger(int defaultValue) 46 | { 47 | return Value != null ? Convert.ToInt32(Value, CultureInfo.InvariantCulture) : defaultValue; 48 | } 49 | 50 | public override string ToString() 51 | { 52 | return ToString(string.Empty); 53 | } 54 | 55 | public string ToString(string defaultValue) 56 | { 57 | return Value != null ? Convert.ToString(Value, CultureInfo.InvariantCulture) : defaultValue; 58 | } 59 | 60 | public bool ToBoolean() 61 | { 62 | return ToBoolean(false); 63 | } 64 | 65 | public bool ToBoolean(bool defaultValue) 66 | { 67 | return Value != null ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : defaultValue; 68 | } 69 | 70 | public double ToDouble() 71 | { 72 | return ToDouble(0); 73 | } 74 | 75 | public double ToDouble(double defaultValue) 76 | { 77 | return Value != null ? Convert.ToDouble(Value, CultureInfo.InvariantCulture) : defaultValue; 78 | } 79 | 80 | public object ToObject() 81 | { 82 | return ToObject(null); 83 | } 84 | 85 | public object ToObject(object defaultValue) 86 | { 87 | return Value != null ? Value : defaultValue; 88 | } 89 | 90 | public Guid ToGuid() 91 | { 92 | return ToGuid(Guid.Empty); 93 | } 94 | 95 | public Guid ToGuid(Guid defaultValue) 96 | { 97 | return Value != null ? new Guid(Convert.ToString(Value)) : defaultValue; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /CryptoShark/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CryptoShark.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CryptoShark.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /CryptoShark/Forms/FormSettings.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Hunting.Data; 2 | using CryptoShark.Hunting.VolumeHunting; 3 | using CryptoShark.Utility; 4 | using Newtonsoft.Json.Linq; 5 | using Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl; 6 | using Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.Enum; 7 | using Quantum.Framework.GenericProperties.Data; 8 | using System; 9 | using System.IO; 10 | using System.Windows.Forms; 11 | 12 | namespace CryptoShark.Forms 13 | { 14 | public partial class FormSettings : Form 15 | { 16 | public FormSettings() 17 | { 18 | InitializeComponent(); 19 | } 20 | 21 | private void FormSettings_Load(object sender, EventArgs e) 22 | { 23 | // general properties 24 | genericPropertyListControl.Properties = SettingsHelper.GetGeneralProperties(); 25 | genericPropertyListControl.RefreshItems(); 26 | 27 | // hunting properties 28 | var huntingTypes = HuntingTypeManager.Instance.HuntingTypes; 29 | foreach (var huntingType in huntingTypes) 30 | { 31 | var properties = huntingType.GetProperties(); 32 | var jArrayProperties = SettingsHelper.GetJArrayHuntingProperties(huntingType.TypeName); 33 | if (jArrayProperties != null) 34 | GenericPropertySerializer.DeserializePropertiesFromArray(properties, jArrayProperties); 35 | 36 | var tabPage = new TabPage() 37 | { 38 | Text = huntingType.DisplayName, 39 | Tag = huntingType 40 | }; 41 | 42 | var propertyControl = new GenericPropertyListControl 43 | { 44 | Dock = DockStyle.Fill, 45 | Properties = properties 46 | }; 47 | propertyControl.Options.ViewMode = ViewMode.CategoryList; 48 | 49 | tabPage.Controls.Add(propertyControl); 50 | tabControl.TabPages.Add(tabPage); 51 | 52 | propertyControl.RefreshItems(); 53 | } 54 | } 55 | 56 | private void buttonSave_Click(object sender, EventArgs e) 57 | { 58 | var jObjectSettings = new JObject(); 59 | 60 | foreach (TabPage tabPage in tabControl.TabPages) 61 | { 62 | if (tabPage.Tag is HuntingType huntingType) 63 | { 64 | GenericPropertyCollection properties = null; 65 | foreach (Control control in tabPage.Controls) 66 | { 67 | if (control is GenericPropertyListControl propertyControl) 68 | properties = propertyControl.Properties; 69 | } 70 | 71 | if (properties != null) 72 | jObjectSettings[huntingType.TypeName + Constants.HUNTING_PROPERTIES_POSTFIX] = GenericPropertySerializer.SerializePropertiesToArray(properties); 73 | } 74 | } 75 | 76 | jObjectSettings[Constants.GENERAL_PROPERTIES] = GenericPropertySerializer.SerializePropertiesToArray(genericPropertyListControl.Properties); 77 | 78 | SettingsHelper.SaveSettings(jObjectSettings); 79 | 80 | DialogResult = DialogResult.OK; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /CryptoShark/Utility/SettingsHelper.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Utility.Enum; 2 | using Newtonsoft.Json.Linq; 3 | using Quantum.Framework.GenericProperties.Data; 4 | using Quantum.Framework.GenericProperties.Enum; 5 | using System.IO; 6 | 7 | namespace CryptoShark.Utility 8 | { 9 | public class SettingsHelper 10 | { 11 | #region Singleton Members 12 | 13 | private static SettingsHelper instance; 14 | public static SettingsHelper Instance 15 | { 16 | get 17 | { 18 | if (instance == null) 19 | { 20 | instance = new SettingsHelper(); 21 | instance.genericProperties = GetGeneralProperties(); 22 | } 23 | return instance; 24 | } 25 | } 26 | 27 | private GenericPropertyCollection genericProperties; 28 | 29 | #endregion 30 | 31 | private static JObject LoadSettings() 32 | { 33 | if (File.Exists(Constants.SETTINGS_FILENAME)) 34 | { 35 | var contents = File.ReadAllText(Constants.SETTINGS_FILENAME); 36 | return JObject.Parse(contents); 37 | } 38 | else 39 | return null; 40 | } 41 | 42 | public static void SaveSettings(JObject jObjectSettings) 43 | { 44 | File.WriteAllText(Constants.SETTINGS_FILENAME, jObjectSettings.ToString()); 45 | } 46 | 47 | public static JArray GetJArrayHuntingProperties(string typeName) 48 | { 49 | var jObjectSettings = LoadSettings(); 50 | if (jObjectSettings != null && jObjectSettings[typeName + Constants.HUNTING_PROPERTIES_POSTFIX] != null) 51 | return (JArray)jObjectSettings[typeName + Constants.HUNTING_PROPERTIES_POSTFIX]; 52 | else 53 | return null; 54 | } 55 | 56 | private static JArray GetJArrayGeneralProperties() 57 | { 58 | var jObjectSettings = LoadSettings(); 59 | if (jObjectSettings != null && jObjectSettings[Constants.GENERAL_PROPERTIES] != null) 60 | return (JArray)jObjectSettings[Constants.GENERAL_PROPERTIES]; 61 | else 62 | return null; 63 | } 64 | 65 | public static GenericPropertyCollection GetGeneralProperties() 66 | { 67 | var properties = new GenericPropertyCollection() 68 | { 69 | new GenericProperty() 70 | { 71 | Browsable = true, 72 | Name = SettingName.API_KEY, 73 | DisplayName = "Api Key", 74 | DefaultValue = string.Empty, 75 | Type = GenericPropertyType.String 76 | }, 77 | new GenericProperty() 78 | { 79 | Browsable = true, 80 | Name = SettingName.SECRET_KEY, 81 | DisplayName = "Secret Key", 82 | DefaultValue = string.Empty, 83 | Type = GenericPropertyType.String 84 | }, 85 | new GenericProperty() 86 | { 87 | Browsable = true, 88 | Name = SettingName.TRADING_ENABLED, 89 | DisplayName = "Trading Enable", 90 | DefaultValue = false, 91 | Type = GenericPropertyType.Boolean 92 | } 93 | }; 94 | 95 | var jArrayProperties = GetJArrayGeneralProperties(); 96 | if (jArrayProperties != null) 97 | GenericPropertySerializer.DeserializePropertiesFromArray(properties, jArrayProperties); 98 | 99 | return properties; 100 | } 101 | 102 | public T GetSetting(string name, T defaultValue) 103 | { 104 | var properties = GetGeneralProperties(); 105 | if (properties.Contains(name)) 106 | return properties.Get(name, defaultValue); 107 | else 108 | return defaultValue; 109 | } 110 | 111 | public void Invalidate() 112 | { 113 | genericProperties = GetGeneralProperties(); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /CryptoShark/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /CryptoShark/Utility/JObjectHelper.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Globalization; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace CryptoShark.Utility 10 | { 11 | public static class JObjectHelper 12 | { 13 | public static string GetString(JObject jObject, string propertyName) 14 | { 15 | return GetString(jObject, propertyName, string.Empty); 16 | } 17 | 18 | public static string GetString(JObject jObject, string propertyName, string defaultValue) 19 | { 20 | if (jObject == null) 21 | return defaultValue; 22 | 23 | return jObject[propertyName] != null ? Convert.ToString(jObject[propertyName]) : defaultValue; 24 | } 25 | 26 | public static int GetInt32(JObject jObject, string propertyName) 27 | { 28 | return GetInt32(jObject, propertyName, default(int)); 29 | } 30 | 31 | public static int GetInt32(JObject jObject, string propertyName, int defaultValue) 32 | { 33 | if (jObject == null) 34 | return defaultValue; 35 | 36 | int value = defaultValue; 37 | 38 | if (jObject[propertyName] != null) 39 | int.TryParse(Convert.ToString(jObject[propertyName]), out value); 40 | 41 | return value; 42 | } 43 | 44 | public static double GetDouble(JObject jObject, string propertyName) 45 | { 46 | return GetDouble(jObject, propertyName, default(double)); 47 | } 48 | 49 | public static double GetDouble(JObject jObject, string propertyName, double defaultValue) 50 | { 51 | if (jObject == null) 52 | return defaultValue; 53 | 54 | if (jObject[propertyName] != null) 55 | { 56 | try 57 | { 58 | string text = Convert.ToString(jObject[propertyName]); 59 | text = text.Replace(",", "."); 60 | return jObject[propertyName] != null ? double.Parse(text, NumberStyles.Any, CultureInfo.InvariantCulture) : defaultValue; 61 | } 62 | catch (FormatException) 63 | { 64 | return defaultValue; 65 | } 66 | } 67 | else 68 | return defaultValue; 69 | } 70 | 71 | public static decimal GetDecimal(JObject jObject, string propertyName) 72 | { 73 | return GetDecimal(jObject, propertyName, default(decimal)); 74 | } 75 | 76 | public static decimal GetDecimal(JObject jObject, string propertyName, decimal defaultValue) 77 | { 78 | if (jObject == null) 79 | return defaultValue; 80 | 81 | if (jObject[propertyName] != null) 82 | { 83 | try 84 | { 85 | string text = Convert.ToString(jObject[propertyName]); 86 | text = text.Replace(",", "."); 87 | return jObject[propertyName] != null ? decimal.Parse(text, NumberStyles.Any, CultureInfo.InvariantCulture) : defaultValue; 88 | } 89 | catch (FormatException ex) 90 | { 91 | return defaultValue; 92 | } 93 | } 94 | else 95 | return defaultValue; 96 | } 97 | 98 | public static bool GetBoolean(JObject jObject, string propertyName) 99 | { 100 | return GetBoolean(jObject, propertyName, default(bool)); 101 | } 102 | 103 | public static bool GetBoolean(JObject jObject, string propertyName, bool defaultValue) 104 | { 105 | if (jObject == null) 106 | return defaultValue; 107 | 108 | return jObject[propertyName] != null ? Convert.ToBoolean(jObject[propertyName]) : defaultValue; 109 | } 110 | 111 | public static Guid GetGuid(JObject jObject, string propertyName) 112 | { 113 | return GetGuid(jObject, propertyName, default(Guid)); 114 | } 115 | 116 | public static Guid GetGuid(JObject jObject, string propertyName, Guid defaultValue) 117 | { 118 | if (jObject == null) 119 | return defaultValue; 120 | 121 | return jObject[propertyName] != null ? new Guid(Convert.ToString(jObject[propertyName])) : defaultValue; 122 | } 123 | 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /CryptoShark/Utility/EncryptionHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace CryptoShark.Utility 10 | { 11 | public class EncryptionHelper 12 | { 13 | public static string HashMD5(string pass) 14 | { 15 | MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); 16 | byte[] btr = Encoding.UTF8.GetBytes(pass); 17 | btr = md5.ComputeHash(btr); 18 | StringBuilder sb = new StringBuilder(); 19 | foreach (byte ba in btr) 20 | { 21 | sb.Append(ba.ToString("x2").ToLower()); 22 | } 23 | return sb.ToString(); 24 | } 25 | 26 | public static string EncryptText(string input, string password = Constants.ENCRYPTION_SALT) 27 | { 28 | // Get the bytes of the string 29 | byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input); 30 | byte[] passwordBytes = Encoding.UTF8.GetBytes(password); 31 | 32 | // Hash the password with SHA256 33 | passwordBytes = SHA256.Create().ComputeHash(passwordBytes); 34 | 35 | byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes); 36 | 37 | string result = Convert.ToBase64String(bytesEncrypted); 38 | 39 | return result; 40 | } 41 | 42 | public static string DecryptText(string input, string password = Constants.ENCRYPTION_SALT) 43 | { 44 | // Get the bytes of the string 45 | byte[] bytesToBeDecrypted = Convert.FromBase64String(input); 46 | byte[] passwordBytes = Encoding.UTF8.GetBytes(password); 47 | passwordBytes = SHA256.Create().ComputeHash(passwordBytes); 48 | 49 | byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes); 50 | 51 | string result = Encoding.UTF8.GetString(bytesDecrypted); 52 | 53 | return result; 54 | } 55 | 56 | private static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) 57 | { 58 | byte[] encryptedBytes = null; 59 | 60 | // Set your salt here, change it to meet your flavor: 61 | // The salt bytes must be at least 8 bytes. 62 | byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 63 | 64 | using (MemoryStream ms = new MemoryStream()) 65 | { 66 | using (RijndaelManaged AES = new RijndaelManaged()) 67 | { 68 | AES.KeySize = 256; 69 | AES.BlockSize = 128; 70 | 71 | var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 72 | AES.Key = key.GetBytes(AES.KeySize / 8); 73 | AES.IV = key.GetBytes(AES.BlockSize / 8); 74 | 75 | AES.Mode = CipherMode.CBC; 76 | 77 | using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) 78 | { 79 | cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length); 80 | cs.Close(); 81 | } 82 | encryptedBytes = ms.ToArray(); 83 | } 84 | } 85 | 86 | return encryptedBytes; 87 | } 88 | 89 | private static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes) 90 | { 91 | byte[] decryptedBytes = null; 92 | 93 | // Set your salt here, change it to meet your flavor: 94 | // The salt bytes must be at least 8 bytes. 95 | byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 96 | 97 | using (MemoryStream ms = new MemoryStream()) 98 | { 99 | using (RijndaelManaged AES = new RijndaelManaged()) 100 | { 101 | AES.KeySize = 256; 102 | AES.BlockSize = 128; 103 | 104 | var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 105 | AES.Key = key.GetBytes(AES.KeySize / 8); 106 | AES.IV = key.GetBytes(AES.BlockSize / 8); 107 | 108 | AES.Mode = CipherMode.CBC; 109 | 110 | using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)) 111 | { 112 | cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length); 113 | cs.Close(); 114 | } 115 | decryptedBytes = ms.ToArray(); 116 | } 117 | } 118 | 119 | return decryptedBytes; 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /CryptoShark/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /CryptoShark/Hunting/Data/Hunting.cs: -------------------------------------------------------------------------------- 1 | using Binance; 2 | using CryptoShark.Data; 3 | using CryptoShark.Utility; 4 | using CryptoShark.Utility.Enum; 5 | using Quantum.Framework.GenericProperties.Data; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | 11 | namespace CryptoShark.Hunting.Data 12 | { 13 | public class Hunting 14 | { 15 | public virtual string TypeName { get; } 16 | public GenericPropertyCollection Properties { get; set; } 17 | 18 | public BinanceApi Api { get; private set; } 19 | public BinanceApiUser User { get; private set; } 20 | 21 | public bool TradeEnabled => genericProperties.Get(SettingName.TRADING_ENABLED, false); 22 | 23 | private GenericPropertyCollection genericProperties; 24 | 25 | public Hunting() 26 | { 27 | genericProperties = SettingsHelper.GetGeneralProperties(); 28 | } 29 | 30 | public virtual void Initialize() 31 | { 32 | Api = new BinanceApi(); 33 | 34 | var apiKey = genericProperties.Get(SettingName.API_KEY, string.Empty); 35 | var secretKey = genericProperties.Get(SettingName.SECRET_KEY, string.Empty); 36 | 37 | if (!string.IsNullOrEmpty(apiKey) && !string.IsNullOrEmpty(secretKey)) 38 | User = new BinanceApiUser(apiKey, secretKey); 39 | 40 | var jArrayProperties = SettingsHelper.GetJArrayHuntingProperties(TypeName); 41 | if (jArrayProperties != null) 42 | GenericPropertySerializer.DeserializePropertiesFromArray(Properties, jArrayProperties); 43 | } 44 | 45 | public virtual void StartHunting() 46 | { 47 | 48 | } 49 | 50 | public virtual void StopHunting() 51 | { 52 | 53 | } 54 | 55 | public virtual Hunting Clone() 56 | { 57 | return null; 58 | } 59 | 60 | public async Task GetBTCBalance() 61 | { 62 | var account = await Api.GetAccountInfoAsync(User); 63 | foreach (var balance in account.Balances) 64 | { 65 | if (balance.Free > 0 || balance.Locked > 0) 66 | { 67 | if (balance.Asset == Asset.BTC.Symbol) 68 | return balance.Free; 69 | } 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | public async Task GetUSDTBalance() 76 | { 77 | var account = await Api.GetAccountInfoAsync(User); 78 | foreach (var balance in account.Balances) 79 | { 80 | if (balance.Free > 0 || balance.Locked > 0) 81 | { 82 | if (balance.Asset == Asset.USDT.Symbol) 83 | return balance.Free; 84 | } 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | public async Task GetSymbolBalance(string symbol) 91 | { 92 | var account = await Api.GetAccountInfoAsync(User); 93 | foreach (var balance in account.Balances) 94 | { 95 | if (balance.Free > 0 || balance.Locked > 0) 96 | { 97 | if (balance.Asset == symbol) 98 | return balance.Free; 99 | } 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | public async Task BuyFromMarket(decimal mainFundQuantity, string symbol) 106 | { 107 | var success = false; 108 | var boughtAll = true; 109 | var symbolObj = await BinanceApiHelper.Instance.GetSymbol(symbol); 110 | 111 | var orders = new List(); 112 | var quantityDecimalPlaces = symbolObj.Quantity.Increment.DecimalPlaces(); 113 | var priceDecimalPlaces = symbolObj.Price.Increment.DecimalPlaces(); 114 | 115 | while (!success || !boughtAll) 116 | { 117 | var orderBookTop = await Api.GetOrderBookTopAsync(symbol); 118 | var amountToBuy = mainFundQuantity / orderBookTop.Bid.Price; 119 | amountToBuy = amountToBuy.RoundTo(quantityDecimalPlaces); 120 | 121 | if (amountToBuy > orderBookTop.Bid.Quantity) 122 | { 123 | amountToBuy = orderBookTop.Bid.Quantity; 124 | boughtAll = false; 125 | } 126 | 127 | if (amountToBuy == 0) 128 | break; 129 | 130 | try 131 | { 132 | var order = await Api.PlaceAsync(new MarketOrder(User) 133 | { 134 | Quantity = amountToBuy, 135 | Side = OrderSide.Buy, 136 | Symbol = symbol 137 | }); 138 | orders.Add(order); 139 | 140 | var averagePriceOrder = BinanceApiHelper.Instance.GetAveragePrice(order, symbolObj); 141 | mainFundQuantity -= amountToBuy * averagePriceOrder; 142 | 143 | success = true; 144 | } 145 | catch (Exception ex) 146 | { 147 | success = false; 148 | } 149 | 150 | /* 151 | if (!success || !boughtAll) 152 | await Task.Delay(50); 153 | */ 154 | } 155 | 156 | 157 | var totalOrderPrice = 0m; 158 | var totalOrderQuantity = 0m; 159 | foreach (var order in orders) 160 | { 161 | var totalPrice = 0m; 162 | var fills = order.Fills.ToList(); 163 | foreach (var fill in fills) 164 | totalPrice += fill.Price * fill.Quantity; 165 | 166 | var averageOrderPrice = totalPrice / order.ExecutedQuantity; 167 | 168 | totalOrderPrice += averageOrderPrice * order.ExecutedQuantity; 169 | totalOrderQuantity += order.ExecutedQuantity; 170 | } 171 | 172 | if (totalOrderQuantity == 0) 173 | throw new Exception($"Total order quantitiy is 0"); 174 | 175 | var averagePrice = (totalOrderPrice / totalOrderQuantity).RoundTo(priceDecimalPlaces); 176 | 177 | return new MarketOrderResult() 178 | { 179 | Symbol = symbolObj, 180 | AveragePrice = averagePrice, 181 | Quantity = totalOrderQuantity.RoundTo(quantityDecimalPlaces) 182 | }; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ -------------------------------------------------------------------------------- /CryptoShark/Utility/BinanceApiHelper.cs: -------------------------------------------------------------------------------- 1 | using Binance; 2 | using CryptoShark.Data; 3 | using CryptoShark.Utility.Enum; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace CryptoShark.Utility 11 | { 12 | public class BinanceApiHelper 13 | { 14 | #region Singleton Members 15 | 16 | private static BinanceApiHelper instance; 17 | public static BinanceApiHelper Instance 18 | { 19 | get 20 | { 21 | if (instance == null) 22 | { 23 | instance = new BinanceApiHelper(); 24 | instance.Api = new BinanceApi(); 25 | var apiKey = SettingsHelper.Instance.GetSetting(SettingName.API_KEY, string.Empty); 26 | var secretKey = SettingsHelper.Instance.GetSetting(SettingName.SECRET_KEY, string.Empty); 27 | 28 | if (!string.IsNullOrEmpty(apiKey) && !string.IsNullOrEmpty(secretKey)) 29 | instance.User = new BinanceApiUser(apiKey, secretKey); 30 | } 31 | return instance; 32 | } 33 | } 34 | 35 | #endregion 36 | 37 | public BinanceApi Api { get; set; } 38 | public BinanceApiUser User { get; set; } 39 | public List Symbols { get; set; } 40 | 41 | public async Task> GetAllOrders(string quoteAsset = "BTC", int limitPerSymbol = 5) 42 | { 43 | try 44 | { 45 | var orders = new List(); 46 | //var stopwatch = Stopwatch.StartNew(); 47 | 48 | var symbols = (await Api.GetSymbolsAsync()).Where(x => x.QuoteAsset.Symbol == quoteAsset).ToList(); 49 | foreach (var symbol in symbols) 50 | { 51 | var symbolOrders = await Api.GetOrdersAsync(User, symbol.ToString(), -1, limitPerSymbol); 52 | foreach (var symbolOrder in symbolOrders) 53 | { 54 | if (symbolOrder.Status == OrderStatus.Filled) 55 | { 56 | var orderItem = new OrderItem() 57 | { 58 | Price = symbolOrder.Price, 59 | StopPrice = symbolOrder.StopPrice, 60 | Quantity = symbolOrder.OriginalQuantity.RoundTo(symbol.BaseAsset.Precision), 61 | ExecutedQuantity = symbolOrder.ExecutedQuantity.RoundTo(symbol.BaseAsset.Precision), 62 | Side = symbolOrder.Side == OrderSide.Buy ? CryptoShark.Enum.OrderSide.Buy : CryptoShark.Enum.OrderSide.Sell, 63 | Symbol = symbolOrder.Symbol, 64 | Date = symbolOrder.Time 65 | }; 66 | 67 | if (symbolOrder.Type == OrderType.Market) 68 | { 69 | var price = 0m; 70 | var trades = await Api.GetAccountTradesAsync(User, symbolOrder.Symbol, 200); 71 | foreach (var trade in trades) 72 | { 73 | if (trade.OrderId == symbolOrder.Id) 74 | price += trade.Price * trade.Quantity; 75 | } 76 | price = price / symbolOrder.ExecutedQuantity; 77 | price = price.RoundTo(6); 78 | orderItem.Price = price; 79 | } 80 | 81 | orders.Add(orderItem); 82 | } 83 | } 84 | } 85 | 86 | orders = orders.OrderByDescending(x => x.Date).ToList(); 87 | 88 | //stopwatch.Stop(); 89 | //Console.WriteLine("Elapsed: " + stopwatch.Elapsed.Seconds); 90 | 91 | return orders; 92 | } 93 | catch (Exception ex) 94 | { 95 | return null; 96 | } 97 | } 98 | 99 | public async Task> GetOpenOrders() 100 | { 101 | try 102 | { 103 | var orders = new List(); 104 | 105 | var openOrders = await Api.GetOpenOrdersAsync(User); 106 | foreach (var openOrder in openOrders) 107 | { 108 | var symbol = await GetSymbol(openOrder.Symbol); 109 | var orderItem = new OrderItem() 110 | { 111 | Price = openOrder.Price, 112 | StopPrice = openOrder.StopPrice, 113 | Quantity = openOrder.OriginalQuantity.RoundTo(symbol.BaseAsset.Precision), 114 | ExecutedQuantity = openOrder.ExecutedQuantity, 115 | Side = openOrder.Side == OrderSide.Buy ? CryptoShark.Enum.OrderSide.Buy : CryptoShark.Enum.OrderSide.Sell, 116 | Symbol = openOrder.Symbol, 117 | Date = openOrder.Time 118 | }; 119 | 120 | //if (openOrder.Type == OrderType.Limit) 121 | // orderItem.OrderType = CryptoShark.Enum.OrderType.Limit; 122 | //else if (openOrder.Type == OrderType.StopLossLimit) 123 | // orderItem.OrderType = CryptoShark.Enum.OrderType.StopLimit; 124 | //else if (openOrder.Type == OrderType.Market) 125 | // orderItem.OrderType = CryptoShark.Enum.OrderType.Market; 126 | 127 | orders.Add(orderItem); 128 | } 129 | 130 | return orders; 131 | } 132 | catch (Exception ex) 133 | { 134 | return null; 135 | } 136 | } 137 | 138 | public async Task GetSymbol(string symbol) 139 | { 140 | if (Symbols == null) 141 | Symbols = (await Api.GetSymbolsAsync()).ToList(); 142 | 143 | foreach (var symbol_ in Symbols) 144 | { 145 | if (symbol_.ToString() == symbol) 146 | return symbol_; 147 | } 148 | 149 | return null; 150 | } 151 | 152 | public decimal GetAveragePrice(Order order, Symbol symbol) 153 | { 154 | var totalPrice = 0m; 155 | var totalQuantity = 0m; 156 | 157 | var fills = order.Fills.ToList(); 158 | foreach (var fill in fills) 159 | { 160 | totalPrice += fill.Price * fill.Quantity; 161 | totalQuantity += fill.Quantity; 162 | } 163 | 164 | var decimalPlaces = symbol.Price.Increment.DecimalPlaces(); 165 | 166 | return (totalPrice / totalQuantity).RoundTo(decimalPlaces); 167 | } 168 | 169 | public async Task GetAveragePrice(Order order, string symbol) 170 | { 171 | var symbolObj = await GetSymbol(symbol); 172 | return GetAveragePrice(order, symbolObj); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /CryptoShark/Forms/FormSettings.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CryptoShark.Forms 2 | { 3 | partial class FormSettings 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.Data.GenericPropertyListOptions genericPropertyListOptions1 = new Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.Data.GenericPropertyListOptions(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormSettings)); 33 | this.buttonCancel = new System.Windows.Forms.Button(); 34 | this.buttonSave = new System.Windows.Forms.Button(); 35 | this.tabControl = new System.Windows.Forms.TabControl(); 36 | this.tabPageGeneral = new System.Windows.Forms.TabPage(); 37 | this.genericPropertyListControl = new Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.GenericPropertyListControl(); 38 | this.tabControl.SuspendLayout(); 39 | this.tabPageGeneral.SuspendLayout(); 40 | this.SuspendLayout(); 41 | // 42 | // buttonCancel 43 | // 44 | this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 45 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 46 | this.buttonCancel.Location = new System.Drawing.Point(356, 408); 47 | this.buttonCancel.Name = "buttonCancel"; 48 | this.buttonCancel.Size = new System.Drawing.Size(75, 23); 49 | this.buttonCancel.TabIndex = 0; 50 | this.buttonCancel.Text = "Cancel"; 51 | this.buttonCancel.UseVisualStyleBackColor = true; 52 | // 53 | // buttonSave 54 | // 55 | this.buttonSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 56 | this.buttonSave.Location = new System.Drawing.Point(275, 408); 57 | this.buttonSave.Name = "buttonSave"; 58 | this.buttonSave.Size = new System.Drawing.Size(75, 23); 59 | this.buttonSave.TabIndex = 1; 60 | this.buttonSave.Text = "Save"; 61 | this.buttonSave.UseVisualStyleBackColor = true; 62 | this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click); 63 | // 64 | // tabControl 65 | // 66 | this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 67 | | System.Windows.Forms.AnchorStyles.Left) 68 | | System.Windows.Forms.AnchorStyles.Right))); 69 | this.tabControl.Controls.Add(this.tabPageGeneral); 70 | this.tabControl.Location = new System.Drawing.Point(12, 12); 71 | this.tabControl.Name = "tabControl"; 72 | this.tabControl.SelectedIndex = 0; 73 | this.tabControl.Size = new System.Drawing.Size(419, 390); 74 | this.tabControl.TabIndex = 2; 75 | // 76 | // tabPageGeneral 77 | // 78 | this.tabPageGeneral.Controls.Add(this.genericPropertyListControl); 79 | this.tabPageGeneral.Location = new System.Drawing.Point(4, 22); 80 | this.tabPageGeneral.Name = "tabPageGeneral"; 81 | this.tabPageGeneral.Padding = new System.Windows.Forms.Padding(3); 82 | this.tabPageGeneral.Size = new System.Drawing.Size(411, 364); 83 | this.tabPageGeneral.TabIndex = 0; 84 | this.tabPageGeneral.Text = "General"; 85 | this.tabPageGeneral.UseVisualStyleBackColor = true; 86 | // 87 | // genericPropertyListControl 88 | // 89 | this.genericPropertyListControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 90 | | System.Windows.Forms.AnchorStyles.Left) 91 | | System.Windows.Forms.AnchorStyles.Right))); 92 | this.genericPropertyListControl.AutoScroll = true; 93 | this.genericPropertyListControl.Location = new System.Drawing.Point(3, 3); 94 | this.genericPropertyListControl.Margin = new System.Windows.Forms.Padding(0); 95 | this.genericPropertyListControl.Name = "genericPropertyListControl"; 96 | genericPropertyListOptions1.AutoSize = false; 97 | genericPropertyListOptions1.CategoryBottomMargin = 7; 98 | genericPropertyListOptions1.CategoryLeftMargin = 5; 99 | genericPropertyListOptions1.CategoryRightMargin = 5; 100 | genericPropertyListOptions1.CategorySeperatorColor = System.Drawing.Color.Silver; 101 | genericPropertyListOptions1.CategorySeperatorHeight = 1; 102 | genericPropertyListOptions1.CategoryTitleFont = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold); 103 | genericPropertyListOptions1.CategoryTitleForeColor = System.Drawing.Color.Silver; 104 | genericPropertyListOptions1.CategoryTitleHeight = 21; 105 | genericPropertyListOptions1.CategoryTopMargin = 5; 106 | genericPropertyListOptions1.ItemGap = 3; 107 | genericPropertyListOptions1.ItemHeight = 22; 108 | genericPropertyListOptions1.ItemLabelForeColor = System.Drawing.Color.Empty; 109 | genericPropertyListOptions1.ItemLeftMargin = 5; 110 | genericPropertyListOptions1.ItemRightMargin = 5; 111 | genericPropertyListOptions1.ScrollBarPadding = 3; 112 | genericPropertyListOptions1.SeperatorOffset = 40; 113 | genericPropertyListOptions1.SeperatorOffsetType = Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.Enum.SeperatorOffsetType.Percent; 114 | genericPropertyListOptions1.SeperatorPadding = 5; 115 | genericPropertyListOptions1.ViewMode = Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.Enum.ViewMode.List; 116 | this.genericPropertyListControl.Options = genericPropertyListOptions1; 117 | this.genericPropertyListControl.Properties = null; 118 | this.genericPropertyListControl.Size = new System.Drawing.Size(405, 358); 119 | this.genericPropertyListControl.TabIndex = 0; 120 | this.genericPropertyListControl.Values = null; 121 | // 122 | // FormSettings 123 | // 124 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 125 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 126 | this.CancelButton = this.buttonCancel; 127 | this.ClientSize = new System.Drawing.Size(443, 443); 128 | this.Controls.Add(this.tabControl); 129 | this.Controls.Add(this.buttonSave); 130 | this.Controls.Add(this.buttonCancel); 131 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 132 | this.MaximizeBox = false; 133 | this.MinimizeBox = false; 134 | this.Name = "FormSettings"; 135 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 136 | this.Text = "Settings"; 137 | this.Load += new System.EventHandler(this.FormSettings_Load); 138 | this.tabControl.ResumeLayout(false); 139 | this.tabPageGeneral.ResumeLayout(false); 140 | this.ResumeLayout(false); 141 | 142 | } 143 | 144 | #endregion 145 | 146 | private System.Windows.Forms.Button buttonCancel; 147 | private System.Windows.Forms.Button buttonSave; 148 | private System.Windows.Forms.TabControl tabControl; 149 | private System.Windows.Forms.TabPage tabPageGeneral; 150 | private Quantum.Framework.GenericProperties.Controls.GenericPropertyListControl.GenericPropertyListControl genericPropertyListControl; 151 | } 152 | } -------------------------------------------------------------------------------- /CryptoShark/Forms/FormMain.cs: -------------------------------------------------------------------------------- 1 | using Binance; 2 | using CryptoShark.Hunting.Data; 3 | using CryptoShark.Utility; 4 | using CryptoShark.Utility.Enum; 5 | using System; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | 9 | namespace CryptoShark.Forms 10 | { 11 | public partial class FormMain : EnhancedForm 12 | { 13 | #region Constants 14 | 15 | private const string WALLET_FORMAT = "{0} BTC / ${1} / {2} TL"; 16 | private const int WALLET_REFRESH_INTERVAL = 5 * 60 * 1000; // in ms 17 | private const int ORDERS_REFRESH_INTERVAL = 10 * 60 * 1000; // in ms 18 | 19 | #endregion 20 | 21 | private Hunting.Data.Hunting currentHunting; 22 | private Timer timerWallet; 23 | private Timer timerOrders; 24 | 25 | private bool TradeEnabled => SettingsHelper.Instance.GetSetting(SettingName.TRADING_ENABLED, false); 26 | 27 | public FormMain() 28 | { 29 | InitializeComponent(); 30 | } 31 | 32 | private void FormMain_Load(object sender, EventArgs e) 33 | { 34 | comboBoxHuntingTypes.DataSource = HuntingTypeManager.Instance.HuntingTypes; 35 | 36 | FileLogger.Instance.OnFileLogged += Instance_OnFileLogged; 37 | 38 | InitializeVariables(); 39 | 40 | timerWallet = new Timer(); 41 | timerWallet.Interval = WALLET_REFRESH_INTERVAL; 42 | timerWallet.Tick += TimerWallet_Tick; 43 | timerWallet.Start(); 44 | 45 | timerOrders = new Timer(); 46 | timerOrders.Interval = ORDERS_REFRESH_INTERVAL; 47 | timerOrders.Tick += TimerOrders_Tick; 48 | timerOrders.Start(); 49 | } 50 | 51 | 52 | private void Instance_OnFileLogged(object sender, Utility.Events.FileLoggedEventArgs e) 53 | { 54 | if (checkBoxLogActive.Checked) 55 | { 56 | richTextBox.Text += e.Text + "\n"; 57 | 58 | richTextBox.SelectionStart = richTextBox.Text.Length; 59 | richTextBox.ScrollToCaret(); 60 | } 61 | } 62 | 63 | #region UI Events 64 | 65 | private void buttonStartStop_Click(object sender, EventArgs e) 66 | { 67 | if (currentHunting != null) 68 | { 69 | currentHunting.StopHunting(); 70 | currentHunting = null; 71 | 72 | buttonStartStop.Text = "Start Hunting"; 73 | } 74 | else 75 | { 76 | if (comboBoxHuntingTypes.SelectedIndex != -1) 77 | { 78 | var huntingType = (HuntingType)comboBoxHuntingTypes.SelectedItem; 79 | currentHunting = huntingType.CreateInstance(); 80 | currentHunting.Initialize(); 81 | currentHunting.StartHunting(); 82 | 83 | RefreshWallet(); 84 | //RefreshOrders(); 85 | 86 | buttonStartStop.Text = "Stop Hunting"; 87 | } 88 | else 89 | MessageBox.Show("Hunting type is not selected!"); 90 | } 91 | } 92 | 93 | private void buttonClear_Click(object sender, EventArgs e) 94 | { 95 | richTextBox.Text = string.Empty; 96 | } 97 | 98 | private void settingsToolStripMenuItem_Click(object sender, EventArgs e) 99 | { 100 | var formSettings = new FormSettings(); 101 | if (formSettings.ShowDialog(this) == DialogResult.OK) 102 | { 103 | SettingsHelper.Instance.Invalidate(); 104 | 105 | if (currentHunting != null) 106 | { 107 | if (ShowQuestion("Do you want to stop current hunting process?") == DialogResult.Yes) 108 | { 109 | currentHunting.StopHunting(); 110 | currentHunting = null; 111 | 112 | buttonStartStop.Text = "Start Hunting"; 113 | } 114 | } 115 | } 116 | } 117 | 118 | private void dataGridViewOrders_DataSourceChanged(object sender, EventArgs e) 119 | { 120 | if (dataGridViewOpenOrders.Columns.Count > 0) 121 | { 122 | dataGridViewOpenOrders.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; 123 | dataGridViewOpenOrders.Columns[0].Width = 48; 124 | } 125 | 126 | foreach (DataGridViewRow row in dataGridViewOpenOrders.Rows) 127 | { 128 | if (Convert.ToString(row.Cells[0].Value) == "Buy") 129 | row.DefaultCellStyle.BackColor = Constants.Green; 130 | else 131 | row.DefaultCellStyle.BackColor = Constants.Red; 132 | } 133 | } 134 | 135 | private void dataGridViewAllOrders_DataSourceChanged(object sender, EventArgs e) 136 | { 137 | if (dataGridViewAllOrders.Columns.Count > 0) 138 | { 139 | dataGridViewAllOrders.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; 140 | dataGridViewAllOrders.Columns[0].Width = 48; 141 | } 142 | 143 | foreach (DataGridViewRow row in dataGridViewAllOrders.Rows) 144 | { 145 | if (Convert.ToString(row.Cells[0].Value) == "Buy") 146 | row.DefaultCellStyle.BackColor = Constants.Green; 147 | else 148 | row.DefaultCellStyle.BackColor = Constants.Red; 149 | } 150 | } 151 | 152 | #endregion 153 | 154 | #region Timer Events 155 | 156 | private void TimerOrders_Tick(object sender, EventArgs e) 157 | { 158 | if (TradeEnabled) 159 | RefreshOrders(); 160 | } 161 | 162 | private void TimerWallet_Tick(object sender, EventArgs e) 163 | { 164 | if (TradeEnabled) 165 | RefreshWallet(); 166 | } 167 | 168 | #endregion 169 | 170 | #region UI Operations 171 | 172 | private async void RefreshWallet() 173 | { 174 | if (currentHunting?.User != null) 175 | { 176 | try 177 | { 178 | var account = await currentHunting.Api.GetAccountInfoAsync(currentHunting.User); 179 | var prices = await currentHunting.Api.GetPricesAsync(); 180 | decimal totalBTC = 0; 181 | foreach (var balance in account.Balances) 182 | { 183 | if (balance.Free > 0 || balance.Locked > 0) 184 | { 185 | if (balance.Asset == Asset.BTC.Symbol) 186 | totalBTC += (balance.Free + balance.Locked); 187 | else 188 | { 189 | if (balance.Asset == "USDT") 190 | { 191 | var priceBTC = prices.Where(x => x.Symbol == "BTCUSDT").FirstOrDefault().Value; 192 | totalBTC += (balance.Free + balance.Locked) / priceBTC; 193 | } 194 | else 195 | { 196 | var price = prices.Where(x => x.Symbol == balance.Asset + "BTC").FirstOrDefault(); 197 | if (price != null) 198 | totalBTC += price.Value * (balance.Free + balance.Locked); 199 | } 200 | } 201 | } 202 | } 203 | 204 | var btcUsdPrice = await currentHunting.Api.GetPriceAsync(Symbol.BTC_USDT); 205 | 206 | var btcStringFormat = string.Format("{0:0.########}", totalBTC); 207 | var usdStringFormat = string.Format("{0:0}", totalBTC * btcUsdPrice.Value); 208 | var tlStringFormat = string.Format("{0:0}", totalBTC * btcUsdPrice.Value * (decimal)ServiceHelper.USDtoTRY()); 209 | 210 | toolStripStatusLabelWallet.Text = string.Format(WALLET_FORMAT, btcStringFormat, usdStringFormat, tlStringFormat); 211 | } 212 | catch (Exception ex) 213 | { 214 | 215 | } 216 | } 217 | } 218 | 219 | private async void RefreshOrders() 220 | { 221 | var symbols = await currentHunting.Api.GetSymbolsAsync(); 222 | try 223 | { 224 | var openOrders = await BinanceApiHelper.Instance.GetOpenOrders(); 225 | dataGridViewOpenOrders.DataSource = openOrders; 226 | if (openOrders != null) 227 | dataGridViewOpenOrders.Columns["Date"].DefaultCellStyle.Format = "MM.dd.yyyy HH:mm:ss"; 228 | 229 | /* 230 | var allOrders = await BinanceApiHelper.Instance.GetAllOrders(); 231 | dataGridViewAllOrders.DataSource = allOrders; 232 | if (allOrders != null) 233 | dataGridViewAllOrders.Columns["Date"].DefaultCellStyle.Format = "MM.dd.yyyy HH:mm:ss"; 234 | */ 235 | } 236 | catch (Exception ex) 237 | { 238 | 239 | } 240 | } 241 | 242 | #endregion 243 | 244 | #region Utility Functions 245 | 246 | private void InitializeVariables() 247 | { 248 | 249 | } 250 | 251 | #endregion 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /CryptoShark/Hunting/VolumeHunting/VolumeHuntingType.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Hunting.Data; 2 | using Quantum.Framework.GenericProperties.Data; 3 | using Quantum.Framework.GenericProperties.Enum; 4 | using System.Collections.Generic; 5 | 6 | namespace CryptoShark.Hunting.VolumeHunting 7 | { 8 | public class VolumeHuntingType : HuntingType 9 | { 10 | public override string TypeName => "volumeHunting"; 11 | public override string DisplayName => "Volume Hunting"; 12 | 13 | public override Data.Hunting CreateInstance() 14 | { 15 | return new VolumeHunting() 16 | { 17 | Properties = GetProperties() 18 | }; 19 | } 20 | 21 | public override GenericPropertyCollection GetProperties() 22 | { 23 | var customPropertiesDecimalPlaces = new Dictionary() 24 | { 25 | ["decimalPlaces"] = 3 26 | }; 27 | 28 | return new GenericPropertyCollection() 29 | { 30 | // hunting properties 31 | new GenericProperty() 32 | { 33 | Browsable = true, 34 | CategoryName = "hunting", 35 | CategoryDisplayName = "Hunting", 36 | Name = "volumeIncreaseThreshold", 37 | DisplayName = "Volume Increase Threshold", 38 | MaximumValue = decimal.MaxValue, 39 | MinimumValue = 0m, 40 | DefaultValue = 0m, 41 | CustomProperties = customPropertiesDecimalPlaces, 42 | Type = GenericPropertyType.Decimal 43 | }, 44 | new GenericProperty() 45 | { 46 | Browsable = true, 47 | CategoryName = "hunting", 48 | CategoryDisplayName = "Hunting", 49 | Name = "minimumVolume", 50 | DisplayName = "Minimum Volume", 51 | MaximumValue = decimal.MaxValue, 52 | MinimumValue = 0m, 53 | DefaultValue = 0m, 54 | CustomProperties = customPropertiesDecimalPlaces, 55 | Type = GenericPropertyType.Decimal 56 | }, 57 | new GenericProperty() 58 | { 59 | Browsable = true, 60 | CategoryName = "hunting", 61 | CategoryDisplayName = "Hunting", 62 | Name = "minimumPrice", 63 | DisplayName = "Minimum Price", 64 | MaximumValue = decimal.MaxValue, 65 | MinimumValue = 0m, 66 | DefaultValue = 0m, 67 | CustomProperties = new Dictionary() 68 | { 69 | ["decimalPlaces"] = 8 70 | }, 71 | Type = GenericPropertyType.Decimal 72 | }, 73 | new GenericProperty() 74 | { 75 | Browsable = true, 76 | CategoryName = "hunting", 77 | CategoryDisplayName = "Hunting", 78 | Name = "minimumBidAskDifferencePercent", 79 | DisplayName = "Minimum Bid-Ask Difference Percent", 80 | MaximumValue = decimal.MaxValue, 81 | MinimumValue = 0m, 82 | DefaultValue = 0m, 83 | CustomProperties = customPropertiesDecimalPlaces, 84 | Type = GenericPropertyType.Decimal 85 | }, 86 | new GenericProperty() 87 | { 88 | Browsable = true, 89 | CategoryName = "hunting", 90 | CategoryDisplayName = "Hunting", 91 | Name = "checkIntervalMinutes", 92 | DisplayName = "Check Interval Minutes", 93 | MaximumValue = 2880, 94 | MinimumValue = 1, 95 | DefaultValue = 10, 96 | Type = GenericPropertyType.Integer 97 | }, 98 | new GenericProperty() 99 | { 100 | Browsable = true, 101 | CategoryName = "hunting", 102 | CategoryDisplayName = "Hunting", 103 | Name = "getVolumeIntervalMinutes", 104 | DisplayName = "Get Volume Interval Minutes", 105 | MaximumValue = 2880, 106 | MinimumValue = 1, 107 | DefaultValue = 1, 108 | Type = GenericPropertyType.Integer 109 | }, 110 | new GenericProperty() 111 | { 112 | Browsable = true, 113 | CategoryName = "hunting", 114 | CategoryDisplayName = "Hunting", 115 | Name = "priceChangeThreshold", 116 | DisplayName = "Price Change Threshold", 117 | MaximumValue = decimal.MaxValue, 118 | MinimumValue = 0m, 119 | DefaultValue = 0m, 120 | Value = 0m, 121 | CustomProperties = customPropertiesDecimalPlaces, 122 | Type = GenericPropertyType.Decimal 123 | }, 124 | new GenericProperty() 125 | { 126 | Browsable = true, 127 | CategoryName = "hunting", 128 | CategoryDisplayName = "Hunting", 129 | Name = "priceDecreaseTriggerThreshold", 130 | DisplayName = "Price Decrease Trigger Threshold", 131 | MaximumValue = decimal.MaxValue, 132 | MinimumValue = 0m, 133 | DefaultValue = 0m, 134 | Value = 0m, 135 | CustomProperties = customPropertiesDecimalPlaces, 136 | Type = GenericPropertyType.Decimal 137 | }, 138 | new GenericProperty() 139 | { 140 | Browsable = true, 141 | CategoryName = "hunting", 142 | CategoryDisplayName = "Hunting", 143 | Name = "priceDifferenceType", 144 | DisplayName = "Price Difference Type", 145 | DefaultValue = "lower", 146 | EnumItems = new List() 147 | { 148 | new GenericPropertyEnumItem("Higher", "higher"), 149 | new GenericPropertyEnumItem("Lower", "lower"), 150 | }, 151 | Type = GenericPropertyType.Enumeration 152 | }, 153 | // trading properties 154 | new GenericProperty() 155 | { 156 | Browsable = true, 157 | CategoryName = "trading", 158 | CategoryDisplayName = "Trading", 159 | Name = "mainFund", 160 | DisplayName = "Main Fund", 161 | DefaultValue = "BTC", 162 | EnumItems = new List() 163 | { 164 | new GenericPropertyEnumItem("BTC", "BTC"), 165 | new GenericPropertyEnumItem("ETH", "ETH"), 166 | new GenericPropertyEnumItem("BNB", "BNB"), 167 | new GenericPropertyEnumItem("USDT", "USDT"), 168 | }, 169 | Type = GenericPropertyType.Enumeration 170 | }, 171 | new GenericProperty() 172 | { 173 | Browsable = true, 174 | CategoryName = "trading", 175 | CategoryDisplayName = "Trading", 176 | Name = "mainFundParts", 177 | DisplayName = "Main Fund Parts", 178 | MaximumValue = 20, 179 | MinimumValue = 1, 180 | DefaultValue = 1, 181 | Type = GenericPropertyType.Integer 182 | }, 183 | new GenericProperty() 184 | { 185 | Browsable = true, 186 | CategoryName = "trading", 187 | CategoryDisplayName = "Trading", 188 | Name = "profitPercentage", 189 | DisplayName = "Profit Percentage", 190 | MaximumValue = decimal.MaxValue, 191 | MinimumValue = 0m, 192 | DefaultValue = 0.05m, 193 | Value = 0m, 194 | CustomProperties = customPropertiesDecimalPlaces, 195 | Type = GenericPropertyType.Decimal 196 | }, 197 | new GenericProperty() 198 | { 199 | Browsable = true, 200 | CategoryName = "trading", 201 | CategoryDisplayName = "Trading", 202 | Name = "stopLossPercentage", 203 | DisplayName = "Stop Loss Percentage", 204 | MaximumValue = decimal.MaxValue, 205 | MinimumValue = 0m, 206 | DefaultValue = 2m, 207 | Value = 0m, 208 | CustomProperties = customPropertiesDecimalPlaces, 209 | Type = GenericPropertyType.Decimal 210 | }, 211 | new GenericProperty() 212 | { 213 | Browsable = true, 214 | CategoryName = "trading", 215 | CategoryDisplayName = "Trading", 216 | Name = "stopLossWaitMinutes", 217 | DisplayName = "Stop Loss Wait Minutes", 218 | MaximumValue = int.MaxValue, 219 | MinimumValue = 0, 220 | DefaultValue = 10, 221 | Value = 0, 222 | Type = GenericPropertyType.Integer 223 | }, 224 | }; 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.edmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /CryptoShark/Utility/SettingsManager/Manager/SettingsManager.cs: -------------------------------------------------------------------------------- 1 | using CryptoShark.Utility.SettingsManager.Data; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace CryptoShark.Utility.SettingsManager.Manager 12 | { 13 | public class SettingsManager 14 | { 15 | #region Singleton Members 16 | private static SettingsManager instance; 17 | public static SettingsManager Instance 18 | { 19 | get 20 | { 21 | if (instance == null) 22 | instance = new SettingsManager(); 23 | return instance; 24 | } 25 | } 26 | #endregion 27 | 28 | public List Items { get; set; } 29 | 30 | public bool AutoSave { get; set; } 31 | public string FileName { get; set; } 32 | 33 | public bool IsAutoSaveSuspended { get; set; } 34 | 35 | public void SuspendAutoSave() 36 | { 37 | IsAutoSaveSuspended = true; 38 | } 39 | 40 | public void ResumeAutoSave() 41 | { 42 | IsAutoSaveSuspended = false; 43 | } 44 | 45 | public SettingsManager() 46 | { 47 | Items = new List(); 48 | 49 | FileName = string.Empty; 50 | } 51 | 52 | public void Save() 53 | { 54 | Save(FileName); 55 | } 56 | 57 | public void Save(string fileName) 58 | { 59 | FileName = fileName; 60 | 61 | var jArraySettings = new JArray(); 62 | 63 | foreach (var item in Items) 64 | { 65 | if (item.Value != null) 66 | { 67 | var jObjectSettingsItem = new JObject(); 68 | jObjectSettingsItem["name"] = item.Name; 69 | 70 | if (item.Value is string) 71 | { 72 | jObjectSettingsItem["type"] = "string"; 73 | jObjectSettingsItem["value"] = Convert.ToString(item.Value); 74 | } 75 | else if (item.Value is int) 76 | { 77 | jObjectSettingsItem["type"] = "integer"; 78 | jObjectSettingsItem["value"] = Convert.ToInt32(item.Value); 79 | } 80 | else if (item.Value is decimal) 81 | { 82 | jObjectSettingsItem["type"] = "double"; 83 | jObjectSettingsItem["value"] = Convert.ToDouble(item.Value); 84 | } 85 | else if (item.Value is bool) 86 | { 87 | jObjectSettingsItem["type"] = "boolean"; 88 | jObjectSettingsItem["value"] = Convert.ToBoolean(item.Value); 89 | } 90 | else if (item.Value is Guid) 91 | { 92 | jObjectSettingsItem["type"] = "guid"; 93 | jObjectSettingsItem["value"] = ((Guid)item.Value).ToString(); 94 | } 95 | else if (item.Value is Point point) 96 | { 97 | jObjectSettingsItem["type"] = "point"; 98 | jObjectSettingsItem["value"] = new JObject() 99 | { 100 | ["x"] = point.X, 101 | ["y"] = point.Y 102 | }; 103 | } 104 | else if (item.Value is Size size) 105 | { 106 | jObjectSettingsItem["type"] = "size"; 107 | jObjectSettingsItem["value"] = new JObject() 108 | { 109 | ["width"] = size.Width, 110 | ["height"] = size.Height 111 | }; 112 | } 113 | else if (item.Value is DateTime dateTime) 114 | { 115 | jObjectSettingsItem["type"] = "datetime"; 116 | var dateTimeUtc = dateTime.ToUniversalTime(); 117 | jObjectSettingsItem["value"] = dateTimeUtc.ToString("o"); 118 | } 119 | else if (item.Value is Version version) 120 | { 121 | jObjectSettingsItem["type"] = "version"; 122 | jObjectSettingsItem["value"] = version.ToString(3); 123 | } 124 | else if (item.Value is List stringList) 125 | { 126 | jObjectSettingsItem["type"] = "list:String"; 127 | 128 | var jArrayStringList = new JArray(); 129 | foreach (var str in stringList) 130 | jArrayStringList.Add(str); 131 | 132 | jObjectSettingsItem["value"] = jArrayStringList; 133 | } 134 | 135 | jArraySettings.Add(jObjectSettingsItem); 136 | } 137 | } 138 | 139 | File.WriteAllText(fileName, jArraySettings.ToString(), Encoding.UTF8); 140 | } 141 | 142 | public void Load() 143 | { 144 | Load(FileName); 145 | } 146 | 147 | public void Load(string fileName) 148 | { 149 | FileName = fileName; 150 | 151 | if (File.Exists(fileName)) 152 | { 153 | var contents = File.ReadAllText(fileName, Encoding.UTF8); 154 | var jObjectSettings = JArray.Parse(contents); 155 | 156 | 157 | Items.Clear(); 158 | 159 | SuspendAutoSave(); 160 | 161 | foreach (JObject jObjectSettingsItem in jObjectSettings) 162 | { 163 | try 164 | { 165 | var name = JObjectHelper.GetString(jObjectSettingsItem, "name", string.Empty); 166 | var type = JObjectHelper.GetString(jObjectSettingsItem, "type", string.Empty); 167 | 168 | object value = null; 169 | 170 | if (type == "string") 171 | value = JObjectHelper.GetString(jObjectSettingsItem, "value", string.Empty); 172 | else if (type == "integer") 173 | value = JObjectHelper.GetInt32(jObjectSettingsItem, "value", 0); 174 | else if (type == "double") 175 | value = JObjectHelper.GetDecimal(jObjectSettingsItem, "value", 0); 176 | else if (type == "boolean") 177 | value = JObjectHelper.GetBoolean(jObjectSettingsItem, "value", false); 178 | else if (type == "guid") 179 | value = JObjectHelper.GetGuid(jObjectSettingsItem, "value", Guid.Empty); 180 | else if (type == "point") 181 | { 182 | var x = JObjectHelper.GetInt32(jObjectSettingsItem, "x", 0); 183 | var y = JObjectHelper.GetInt32(jObjectSettingsItem, "y", 0); 184 | value = new Point(x, y); 185 | } 186 | else if (type == "size") 187 | { 188 | var width = JObjectHelper.GetInt32(jObjectSettingsItem, "width", 0); 189 | var height = JObjectHelper.GetInt32(jObjectSettingsItem, "height", 0); 190 | value = new Size(width, height); 191 | } 192 | else if (type == "datetime") 193 | { 194 | var valueStr = JObjectHelper.GetString(jObjectSettingsItem, "value", DateTime.UtcNow.ToString("o")); 195 | value = DateTime.Parse(valueStr); 196 | } 197 | else if (type == "version") 198 | { 199 | value = new Version(JObjectHelper.GetString(jObjectSettingsItem, "value")); 200 | } 201 | else if (type == "list:String") 202 | { 203 | value = new List(); 204 | var jArrayStrings = (JArray)jObjectSettingsItem["value"]; 205 | foreach (string str in jArrayStrings) 206 | { 207 | ((List)value).Add(str); 208 | } 209 | } 210 | 211 | var settingsItem = new SettingsItem(name); 212 | settingsItem.OnChange += settingsItem_OnChange; 213 | settingsItem.Value = value; 214 | Items.Add(settingsItem); 215 | } 216 | catch (Exception ex) 217 | { 218 | } 219 | } 220 | 221 | ResumeAutoSave(); 222 | } 223 | } 224 | 225 | public void ClearItems() 226 | { 227 | Items.Clear(); 228 | } 229 | 230 | public SettingsItem GetItem(string name) 231 | { 232 | foreach (var item in Items) 233 | { 234 | if (item.Name == name) 235 | return item; 236 | } 237 | 238 | return null; 239 | } 240 | 241 | public void AddItem(string name, object value) 242 | { 243 | var settingsItem = new SettingsItem(name) 244 | { 245 | Value = value 246 | }; 247 | 248 | settingsItem.OnChange += settingsItem_OnChange; 249 | 250 | Items.Add(settingsItem); 251 | } 252 | 253 | void settingsItem_OnChange(object sender, EventArgs e) 254 | { 255 | if (AutoSave && !IsAutoSaveSuspended) 256 | { 257 | var settingsManagerDirectoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"VFabrika"); 258 | if (!Directory.Exists(settingsManagerDirectoryPath)) 259 | Directory.CreateDirectory(settingsManagerDirectoryPath); 260 | 261 | Save(); 262 | } 263 | } 264 | 265 | public bool RemoveItem(string name) 266 | { 267 | for (int i = 0; i < Items.Count; i++) 268 | { 269 | var item = Items[i]; 270 | 271 | if (item.Name == name) 272 | { 273 | item.OnChange -= settingsItem_OnChange; 274 | Items.RemoveAt(i); 275 | 276 | return true; 277 | } 278 | } 279 | 280 | return false; 281 | } 282 | 283 | public bool ContainsItem(string name) 284 | { 285 | foreach (var item in Items) 286 | { 287 | if (item.Name.Equals(name)) 288 | { 289 | if (item.Value != null) 290 | return true; 291 | } 292 | } 293 | return false; 294 | } 295 | 296 | public T Get(string name) 297 | { 298 | return Get(name, default(T)); 299 | } 300 | 301 | public T Get(string name, T defaultValue) 302 | { 303 | foreach (var item in Items) 304 | if (item.Name == name) 305 | return item.Value != null ? (T)item.Value : defaultValue; 306 | 307 | return defaultValue; 308 | } 309 | 310 | public void Set(string name, object value) 311 | { 312 | var item = GetItem(name); 313 | if (item == null) 314 | { 315 | item = new SettingsItem(); 316 | item.OnChange += settingsItem_OnChange; 317 | Items.Add(item); 318 | item.Name = name; 319 | item.Value = value; 320 | } 321 | else 322 | item.Value = value; 323 | } 324 | } 325 | 326 | } 327 | -------------------------------------------------------------------------------- /CryptoShark/Forms/FormMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CryptoShark.Forms 2 | { 3 | partial class FormMain 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain)); 32 | this.menuStrip1 = new System.Windows.Forms.MenuStrip(); 33 | this.applicationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 34 | this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 35 | this.tabControl = new System.Windows.Forms.TabControl(); 36 | this.tabPageHunting = new System.Windows.Forms.TabPage(); 37 | this.buttonClear = new System.Windows.Forms.Button(); 38 | this.checkBoxLogActive = new System.Windows.Forms.CheckBox(); 39 | this.comboBoxHuntingTypes = new System.Windows.Forms.ComboBox(); 40 | this.buttonStartStop = new System.Windows.Forms.Button(); 41 | this.richTextBox = new System.Windows.Forms.RichTextBox(); 42 | this.tabPageOpenOrders = new System.Windows.Forms.TabPage(); 43 | this.dataGridViewOpenOrders = new System.Windows.Forms.DataGridView(); 44 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 45 | this.toolStripStatusLabelWallet = new System.Windows.Forms.ToolStripStatusLabel(); 46 | this.tabPageAllOrders = new System.Windows.Forms.TabPage(); 47 | this.dataGridViewAllOrders = new System.Windows.Forms.DataGridView(); 48 | this.menuStrip1.SuspendLayout(); 49 | this.tabControl.SuspendLayout(); 50 | this.tabPageHunting.SuspendLayout(); 51 | this.tabPageOpenOrders.SuspendLayout(); 52 | ((System.ComponentModel.ISupportInitialize)(this.dataGridViewOpenOrders)).BeginInit(); 53 | this.statusStrip1.SuspendLayout(); 54 | this.tabPageAllOrders.SuspendLayout(); 55 | ((System.ComponentModel.ISupportInitialize)(this.dataGridViewAllOrders)).BeginInit(); 56 | this.SuspendLayout(); 57 | // 58 | // menuStrip1 59 | // 60 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 61 | this.applicationToolStripMenuItem}); 62 | this.menuStrip1.Location = new System.Drawing.Point(0, 0); 63 | this.menuStrip1.Name = "menuStrip1"; 64 | this.menuStrip1.Size = new System.Drawing.Size(504, 24); 65 | this.menuStrip1.TabIndex = 5; 66 | this.menuStrip1.Text = "menuStrip1"; 67 | // 68 | // applicationToolStripMenuItem 69 | // 70 | this.applicationToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 71 | this.settingsToolStripMenuItem}); 72 | this.applicationToolStripMenuItem.Name = "applicationToolStripMenuItem"; 73 | this.applicationToolStripMenuItem.Size = new System.Drawing.Size(80, 20); 74 | this.applicationToolStripMenuItem.Text = "Application"; 75 | // 76 | // settingsToolStripMenuItem 77 | // 78 | this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; 79 | this.settingsToolStripMenuItem.Size = new System.Drawing.Size(116, 22); 80 | this.settingsToolStripMenuItem.Text = "Settings"; 81 | this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); 82 | // 83 | // tabControl 84 | // 85 | this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 86 | | System.Windows.Forms.AnchorStyles.Left) 87 | | System.Windows.Forms.AnchorStyles.Right))); 88 | this.tabControl.Controls.Add(this.tabPageHunting); 89 | this.tabControl.Controls.Add(this.tabPageOpenOrders); 90 | this.tabControl.Controls.Add(this.tabPageAllOrders); 91 | this.tabControl.Location = new System.Drawing.Point(0, 24); 92 | this.tabControl.Name = "tabControl"; 93 | this.tabControl.SelectedIndex = 0; 94 | this.tabControl.Size = new System.Drawing.Size(504, 498); 95 | this.tabControl.TabIndex = 6; 96 | // 97 | // tabPageHunting 98 | // 99 | this.tabPageHunting.Controls.Add(this.buttonClear); 100 | this.tabPageHunting.Controls.Add(this.checkBoxLogActive); 101 | this.tabPageHunting.Controls.Add(this.comboBoxHuntingTypes); 102 | this.tabPageHunting.Controls.Add(this.buttonStartStop); 103 | this.tabPageHunting.Controls.Add(this.richTextBox); 104 | this.tabPageHunting.Location = new System.Drawing.Point(4, 22); 105 | this.tabPageHunting.Name = "tabPageHunting"; 106 | this.tabPageHunting.Padding = new System.Windows.Forms.Padding(3); 107 | this.tabPageHunting.Size = new System.Drawing.Size(496, 472); 108 | this.tabPageHunting.TabIndex = 0; 109 | this.tabPageHunting.Text = "Hunting"; 110 | this.tabPageHunting.UseVisualStyleBackColor = true; 111 | // 112 | // buttonClear 113 | // 114 | this.buttonClear.Location = new System.Drawing.Point(8, 12); 115 | this.buttonClear.Name = "buttonClear"; 116 | this.buttonClear.Size = new System.Drawing.Size(69, 23); 117 | this.buttonClear.TabIndex = 9; 118 | this.buttonClear.Text = "Clear"; 119 | this.buttonClear.UseVisualStyleBackColor = true; 120 | this.buttonClear.Click += new System.EventHandler(this.buttonClear_Click); 121 | // 122 | // checkBoxLogActive 123 | // 124 | this.checkBoxLogActive.AutoSize = true; 125 | this.checkBoxLogActive.Checked = true; 126 | this.checkBoxLogActive.CheckState = System.Windows.Forms.CheckState.Checked; 127 | this.checkBoxLogActive.Location = new System.Drawing.Point(83, 16); 128 | this.checkBoxLogActive.Name = "checkBoxLogActive"; 129 | this.checkBoxLogActive.Size = new System.Drawing.Size(56, 17); 130 | this.checkBoxLogActive.TabIndex = 8; 131 | this.checkBoxLogActive.Text = "Active"; 132 | this.checkBoxLogActive.UseVisualStyleBackColor = true; 133 | // 134 | // comboBoxHuntingTypes 135 | // 136 | this.comboBoxHuntingTypes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 137 | this.comboBoxHuntingTypes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 138 | this.comboBoxHuntingTypes.FormattingEnabled = true; 139 | this.comboBoxHuntingTypes.Location = new System.Drawing.Point(260, 12); 140 | this.comboBoxHuntingTypes.Name = "comboBoxHuntingTypes"; 141 | this.comboBoxHuntingTypes.Size = new System.Drawing.Size(121, 21); 142 | this.comboBoxHuntingTypes.TabIndex = 7; 143 | // 144 | // buttonStartStop 145 | // 146 | this.buttonStartStop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 147 | this.buttonStartStop.Location = new System.Drawing.Point(387, 12); 148 | this.buttonStartStop.Name = "buttonStartStop"; 149 | this.buttonStartStop.Size = new System.Drawing.Size(101, 23); 150 | this.buttonStartStop.TabIndex = 6; 151 | this.buttonStartStop.Text = "Start Hunting"; 152 | this.buttonStartStop.UseVisualStyleBackColor = true; 153 | this.buttonStartStop.Click += new System.EventHandler(this.buttonStartStop_Click); 154 | // 155 | // richTextBox 156 | // 157 | this.richTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 158 | | System.Windows.Forms.AnchorStyles.Left) 159 | | System.Windows.Forms.AnchorStyles.Right))); 160 | this.richTextBox.Location = new System.Drawing.Point(8, 41); 161 | this.richTextBox.Name = "richTextBox"; 162 | this.richTextBox.ReadOnly = true; 163 | this.richTextBox.Size = new System.Drawing.Size(480, 429); 164 | this.richTextBox.TabIndex = 5; 165 | this.richTextBox.Text = ""; 166 | // 167 | // tabPageOpenOrders 168 | // 169 | this.tabPageOpenOrders.Controls.Add(this.dataGridViewOpenOrders); 170 | this.tabPageOpenOrders.Location = new System.Drawing.Point(4, 22); 171 | this.tabPageOpenOrders.Name = "tabPageOpenOrders"; 172 | this.tabPageOpenOrders.Padding = new System.Windows.Forms.Padding(3); 173 | this.tabPageOpenOrders.Size = new System.Drawing.Size(496, 472); 174 | this.tabPageOpenOrders.TabIndex = 1; 175 | this.tabPageOpenOrders.Text = "Open Orders"; 176 | this.tabPageOpenOrders.UseVisualStyleBackColor = true; 177 | // 178 | // dataGridViewOpenOrders 179 | // 180 | this.dataGridViewOpenOrders.AllowUserToAddRows = false; 181 | this.dataGridViewOpenOrders.AllowUserToDeleteRows = false; 182 | this.dataGridViewOpenOrders.AllowUserToResizeRows = false; 183 | this.dataGridViewOpenOrders.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 184 | this.dataGridViewOpenOrders.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 185 | this.dataGridViewOpenOrders.Dock = System.Windows.Forms.DockStyle.Fill; 186 | this.dataGridViewOpenOrders.Location = new System.Drawing.Point(3, 3); 187 | this.dataGridViewOpenOrders.Name = "dataGridViewOpenOrders"; 188 | this.dataGridViewOpenOrders.ReadOnly = true; 189 | this.dataGridViewOpenOrders.RowHeadersVisible = false; 190 | this.dataGridViewOpenOrders.Size = new System.Drawing.Size(490, 466); 191 | this.dataGridViewOpenOrders.TabIndex = 0; 192 | this.dataGridViewOpenOrders.DataSourceChanged += new System.EventHandler(this.dataGridViewOrders_DataSourceChanged); 193 | // 194 | // statusStrip1 195 | // 196 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 197 | this.toolStripStatusLabelWallet}); 198 | this.statusStrip1.Location = new System.Drawing.Point(0, 525); 199 | this.statusStrip1.Name = "statusStrip1"; 200 | this.statusStrip1.Size = new System.Drawing.Size(504, 22); 201 | this.statusStrip1.TabIndex = 7; 202 | this.statusStrip1.Text = "statusStrip1"; 203 | // 204 | // toolStripStatusLabelWallet 205 | // 206 | this.toolStripStatusLabelWallet.Name = "toolStripStatusLabelWallet"; 207 | this.toolStripStatusLabelWallet.Size = new System.Drawing.Size(489, 17); 208 | this.toolStripStatusLabelWallet.Spring = true; 209 | this.toolStripStatusLabelWallet.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 210 | // 211 | // tabPageAllOrders 212 | // 213 | this.tabPageAllOrders.Controls.Add(this.dataGridViewAllOrders); 214 | this.tabPageAllOrders.Location = new System.Drawing.Point(4, 22); 215 | this.tabPageAllOrders.Name = "tabPageAllOrders"; 216 | this.tabPageAllOrders.Padding = new System.Windows.Forms.Padding(3); 217 | this.tabPageAllOrders.Size = new System.Drawing.Size(496, 472); 218 | this.tabPageAllOrders.TabIndex = 2; 219 | this.tabPageAllOrders.Text = "All Orders"; 220 | this.tabPageAllOrders.UseVisualStyleBackColor = true; 221 | // 222 | // dataGridViewAllOrders 223 | // 224 | this.dataGridViewAllOrders.AllowUserToAddRows = false; 225 | this.dataGridViewAllOrders.AllowUserToDeleteRows = false; 226 | this.dataGridViewAllOrders.AllowUserToResizeRows = false; 227 | this.dataGridViewAllOrders.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 228 | this.dataGridViewAllOrders.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 229 | this.dataGridViewAllOrders.Dock = System.Windows.Forms.DockStyle.Fill; 230 | this.dataGridViewAllOrders.Location = new System.Drawing.Point(3, 3); 231 | this.dataGridViewAllOrders.Name = "dataGridViewAllOrders"; 232 | this.dataGridViewAllOrders.ReadOnly = true; 233 | this.dataGridViewAllOrders.RowHeadersVisible = false; 234 | this.dataGridViewAllOrders.Size = new System.Drawing.Size(490, 466); 235 | this.dataGridViewAllOrders.TabIndex = 1; 236 | this.dataGridViewAllOrders.DataSourceChanged += new System.EventHandler(this.dataGridViewAllOrders_DataSourceChanged); 237 | // 238 | // FormMain 239 | // 240 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 241 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 242 | this.ClientSize = new System.Drawing.Size(504, 547); 243 | this.Controls.Add(this.statusStrip1); 244 | this.Controls.Add(this.tabControl); 245 | this.Controls.Add(this.menuStrip1); 246 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 247 | this.MainMenuStrip = this.menuStrip1; 248 | this.MaximizeBox = false; 249 | this.Name = "FormMain"; 250 | this.Text = "CryptoShark"; 251 | this.Load += new System.EventHandler(this.FormMain_Load); 252 | this.menuStrip1.ResumeLayout(false); 253 | this.menuStrip1.PerformLayout(); 254 | this.tabControl.ResumeLayout(false); 255 | this.tabPageHunting.ResumeLayout(false); 256 | this.tabPageHunting.PerformLayout(); 257 | this.tabPageOpenOrders.ResumeLayout(false); 258 | ((System.ComponentModel.ISupportInitialize)(this.dataGridViewOpenOrders)).EndInit(); 259 | this.statusStrip1.ResumeLayout(false); 260 | this.statusStrip1.PerformLayout(); 261 | this.tabPageAllOrders.ResumeLayout(false); 262 | ((System.ComponentModel.ISupportInitialize)(this.dataGridViewAllOrders)).EndInit(); 263 | this.ResumeLayout(false); 264 | this.PerformLayout(); 265 | 266 | } 267 | 268 | #endregion 269 | private System.Windows.Forms.MenuStrip menuStrip1; 270 | private System.Windows.Forms.ToolStripMenuItem applicationToolStripMenuItem; 271 | private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; 272 | private System.Windows.Forms.TabControl tabControl; 273 | private System.Windows.Forms.TabPage tabPageHunting; 274 | private System.Windows.Forms.Button buttonClear; 275 | private System.Windows.Forms.CheckBox checkBoxLogActive; 276 | private System.Windows.Forms.ComboBox comboBoxHuntingTypes; 277 | private System.Windows.Forms.Button buttonStartStop; 278 | private System.Windows.Forms.RichTextBox richTextBox; 279 | private System.Windows.Forms.TabPage tabPageOpenOrders; 280 | private System.Windows.Forms.DataGridView dataGridViewOpenOrders; 281 | private System.Windows.Forms.StatusStrip statusStrip1; 282 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelWallet; 283 | private System.Windows.Forms.TabPage tabPageAllOrders; 284 | private System.Windows.Forms.DataGridView dataGridViewAllOrders; 285 | } 286 | } 287 | 288 | -------------------------------------------------------------------------------- /CryptoShark/CryptoShark.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {310151A0-2089-42B6-A26D-88F8A72A3131} 9 | WinExe 10 | CryptoShark 11 | CryptoShark 12 | v4.7.1 13 | 512 14 | true 15 | true 16 | 17 | 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | Custom-Icon-Design-Flatastic-11-Cash.ico 40 | 41 | 42 | 43 | ..\packages\Binance.0.2.0-beta902\lib\net471\Binance.dll 44 | 45 | 46 | ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll 47 | 48 | 49 | ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll 50 | 51 | 52 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.3.1.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll 53 | 54 | 55 | ..\packages\Microsoft.Extensions.Logging.Abstractions.3.1.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll 56 | 57 | 58 | ..\packages\Microsoft.Extensions.Options.3.1.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll 59 | 60 | 61 | ..\packages\Microsoft.Extensions.Primitives.3.1.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll 62 | 63 | 64 | ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll 65 | 66 | 67 | False 68 | ..\Quantum.Framework.GenericProperties.dll 69 | 70 | 71 | 72 | ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll 73 | 74 | 75 | ..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll 76 | 77 | 78 | 79 | 80 | 81 | ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll 82 | True 83 | True 84 | 85 | 86 | ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll 87 | 88 | 89 | ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll 90 | True 91 | True 92 | 93 | 94 | ..\packages\System.Net.WebSockets.4.3.0\lib\net46\System.Net.WebSockets.dll 95 | True 96 | True 97 | 98 | 99 | ..\packages\System.Net.WebSockets.Client.4.3.2\lib\net46\System.Net.WebSockets.Client.dll 100 | True 101 | True 102 | 103 | 104 | 105 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll 106 | 107 | 108 | ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll 109 | True 110 | True 111 | 112 | 113 | ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll 114 | 115 | 116 | 117 | 118 | ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll 119 | True 120 | True 121 | 122 | 123 | ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll 124 | True 125 | True 126 | 127 | 128 | ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll 129 | True 130 | True 131 | 132 | 133 | ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll 134 | True 135 | True 136 | 137 | 138 | ..\packages\System.Threading.Tasks.Dataflow.4.11.0\lib\netstandard2.0\System.Threading.Tasks.Dataflow.dll 139 | 140 | 141 | ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Form 160 | 161 | 162 | FormMain.cs 163 | 164 | 165 | Form 166 | 167 | 168 | FormSettings.cs 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | True 177 | True 178 | CryptoSharkModel.Context.tt 179 | 180 | 181 | True 182 | True 183 | CryptoSharkModel.tt 184 | 185 | 186 | True 187 | True 188 | CryptoSharkModel.edmx 189 | 190 | 191 | CryptoSharkModel.tt 192 | 193 | 194 | CryptoSharkModel.tt 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | Form 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | FormMain.cs 215 | 216 | 217 | FormSettings.cs 218 | 219 | 220 | ResXFileCodeGenerator 221 | Resources.Designer.cs 222 | Designer 223 | 224 | 225 | True 226 | Resources.resx 227 | 228 | 229 | EntityModelCodeGenerator 230 | CryptoSharkModel.Designer.cs 231 | 232 | 233 | CryptoSharkModel.edmx 234 | 235 | 236 | 237 | SettingsSingleFileGenerator 238 | Settings.Designer.cs 239 | 240 | 241 | True 242 | Settings.settings 243 | True 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | TextTemplatingFileGenerator 253 | CryptoSharkModel.Context.cs 254 | CryptoSharkModel.edmx 255 | 256 | 257 | TextTemplatingFileGenerator 258 | CryptoSharkModel.edmx 259 | CryptoSharkModel.cs 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 269 | 270 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.Context.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" debug="false" hostspecific="true"#> 2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@ 3 | output extension=".cs"#><# 4 | 5 | const string inputFile = @"CryptoSharkModel.edmx"; 6 | var textTransform = DynamicTextTransformation.Create(this); 7 | var code = new CodeGenerationTools(this); 8 | var ef = new MetadataTools(this); 9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors); 10 | var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); 11 | var itemCollection = loader.CreateEdmItemCollection(inputFile); 12 | var modelNamespace = loader.GetModelNamespace(inputFile); 13 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); 14 | 15 | var container = itemCollection.OfType().FirstOrDefault(); 16 | if (container == null) 17 | { 18 | return string.Empty; 19 | } 20 | #> 21 | //------------------------------------------------------------------------------ 22 | // 23 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> 24 | // 25 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> 26 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> 27 | // 28 | //------------------------------------------------------------------------------ 29 | 30 | <# 31 | 32 | var codeNamespace = code.VsNamespaceSuggestion(); 33 | if (!String.IsNullOrEmpty(codeNamespace)) 34 | { 35 | #> 36 | namespace <#=code.EscapeNamespace(codeNamespace)#> 37 | { 38 | <# 39 | PushIndent(" "); 40 | } 41 | 42 | #> 43 | using System; 44 | using System.Data.Entity; 45 | using System.Data.Entity.Infrastructure; 46 | <# 47 | if (container.FunctionImports.Any()) 48 | { 49 | #> 50 | using System.Data.Entity.Core.Objects; 51 | using System.Linq; 52 | <# 53 | } 54 | #> 55 | 56 | <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext 57 | { 58 | public <#=code.Escape(container)#>() 59 | : base("name=<#=container.Name#>") 60 | { 61 | <# 62 | if (!loader.IsLazyLoadingEnabled(container)) 63 | { 64 | #> 65 | this.Configuration.LazyLoadingEnabled = false; 66 | <# 67 | } 68 | 69 | foreach (var entitySet in container.BaseEntitySets.OfType()) 70 | { 71 | // Note: the DbSet members are defined below such that the getter and 72 | // setter always have the same accessibility as the DbSet definition 73 | if (Accessibility.ForReadOnlyProperty(entitySet) != "public") 74 | { 75 | #> 76 | <#=codeStringGenerator.DbSetInitializer(entitySet)#> 77 | <# 78 | } 79 | } 80 | #> 81 | } 82 | 83 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 84 | { 85 | throw new UnintentionalCodeFirstException(); 86 | } 87 | 88 | <# 89 | foreach (var entitySet in container.BaseEntitySets.OfType()) 90 | { 91 | #> 92 | <#=codeStringGenerator.DbSet(entitySet)#> 93 | <# 94 | } 95 | 96 | foreach (var edmFunction in container.FunctionImports) 97 | { 98 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); 99 | } 100 | #> 101 | } 102 | <# 103 | 104 | if (!String.IsNullOrEmpty(codeNamespace)) 105 | { 106 | PopIndent(); 107 | #> 108 | } 109 | <# 110 | } 111 | #> 112 | <#+ 113 | 114 | private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 115 | { 116 | if (typeMapper.IsComposable(edmFunction)) 117 | { 118 | #> 119 | 120 | [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] 121 | <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> 122 | { 123 | <#+ 124 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); 125 | #> 126 | <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> 127 | } 128 | <#+ 129 | } 130 | else 131 | { 132 | #> 133 | 134 | <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> 135 | { 136 | <#+ 137 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); 138 | #> 139 | <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> 140 | } 141 | <#+ 142 | if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) 143 | { 144 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); 145 | } 146 | } 147 | } 148 | 149 | public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) 150 | { 151 | #> 152 | var <#=name#> = <#=isNotNull#> ? 153 | <#=notNullInit#> : 154 | <#=nullInit#>; 155 | 156 | <#+ 157 | } 158 | 159 | public const string TemplateId = "CSharp_DbContext_Context_EF6"; 160 | 161 | public class CodeStringGenerator 162 | { 163 | private readonly CodeGenerationTools _code; 164 | private readonly TypeMapper _typeMapper; 165 | private readonly MetadataTools _ef; 166 | 167 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) 168 | { 169 | ArgumentNotNull(code, "code"); 170 | ArgumentNotNull(typeMapper, "typeMapper"); 171 | ArgumentNotNull(ef, "ef"); 172 | 173 | _code = code; 174 | _typeMapper = typeMapper; 175 | _ef = ef; 176 | } 177 | 178 | public string Property(EdmProperty edmProperty) 179 | { 180 | return string.Format( 181 | CultureInfo.InvariantCulture, 182 | "{0} {1} {2} {{ {3}get; {4}set; }}", 183 | Accessibility.ForProperty(edmProperty), 184 | _typeMapper.GetTypeName(edmProperty.TypeUsage), 185 | _code.Escape(edmProperty), 186 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 187 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 188 | } 189 | 190 | public string NavigationProperty(NavigationProperty navProp) 191 | { 192 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 193 | return string.Format( 194 | CultureInfo.InvariantCulture, 195 | "{0} {1} {2} {{ {3}get; {4}set; }}", 196 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 197 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 198 | _code.Escape(navProp), 199 | _code.SpaceAfter(Accessibility.ForGetter(navProp)), 200 | _code.SpaceAfter(Accessibility.ForSetter(navProp))); 201 | } 202 | 203 | public string AccessibilityAndVirtual(string accessibility) 204 | { 205 | return accessibility + (accessibility != "private" ? " virtual" : ""); 206 | } 207 | 208 | public string EntityClassOpening(EntityType entity) 209 | { 210 | return string.Format( 211 | CultureInfo.InvariantCulture, 212 | "{0} {1}partial class {2}{3}", 213 | Accessibility.ForType(entity), 214 | _code.SpaceAfter(_code.AbstractOption(entity)), 215 | _code.Escape(entity), 216 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); 217 | } 218 | 219 | public string EnumOpening(SimpleType enumType) 220 | { 221 | return string.Format( 222 | CultureInfo.InvariantCulture, 223 | "{0} enum {1} : {2}", 224 | Accessibility.ForType(enumType), 225 | _code.Escape(enumType), 226 | _code.Escape(_typeMapper.UnderlyingClrType(enumType))); 227 | } 228 | 229 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) 230 | { 231 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 232 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 233 | { 234 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 235 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; 236 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; 237 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); 238 | } 239 | } 240 | 241 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) 242 | { 243 | var parameters = _typeMapper.GetParameters(edmFunction); 244 | 245 | return string.Format( 246 | CultureInfo.InvariantCulture, 247 | "{0} IQueryable<{1}> {2}({3})", 248 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 249 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 250 | _code.Escape(edmFunction), 251 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); 252 | } 253 | 254 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) 255 | { 256 | var parameters = _typeMapper.GetParameters(edmFunction); 257 | 258 | return string.Format( 259 | CultureInfo.InvariantCulture, 260 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", 261 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 262 | edmFunction.NamespaceName, 263 | edmFunction.Name, 264 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), 265 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); 266 | } 267 | 268 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 269 | { 270 | var parameters = _typeMapper.GetParameters(edmFunction); 271 | var returnType = _typeMapper.GetReturnType(edmFunction); 272 | 273 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); 274 | if (includeMergeOption) 275 | { 276 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; 277 | } 278 | 279 | return string.Format( 280 | CultureInfo.InvariantCulture, 281 | "{0} {1} {2}({3})", 282 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 283 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 284 | _code.Escape(edmFunction), 285 | paramList); 286 | } 287 | 288 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 289 | { 290 | var parameters = _typeMapper.GetParameters(edmFunction); 291 | var returnType = _typeMapper.GetReturnType(edmFunction); 292 | 293 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); 294 | if (includeMergeOption) 295 | { 296 | callParams = ", mergeOption" + callParams; 297 | } 298 | 299 | return string.Format( 300 | CultureInfo.InvariantCulture, 301 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", 302 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 303 | edmFunction.Name, 304 | callParams); 305 | } 306 | 307 | public string DbSet(EntitySet entitySet) 308 | { 309 | return string.Format( 310 | CultureInfo.InvariantCulture, 311 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}", 312 | Accessibility.ForReadOnlyProperty(entitySet), 313 | _typeMapper.GetTypeName(entitySet.ElementType), 314 | _code.Escape(entitySet)); 315 | } 316 | 317 | public string DbSetInitializer(EntitySet entitySet) 318 | { 319 | return string.Format( 320 | CultureInfo.InvariantCulture, 321 | "{0} = Set<{1}>();", 322 | _code.Escape(entitySet), 323 | _typeMapper.GetTypeName(entitySet.ElementType)); 324 | } 325 | 326 | public string UsingDirectives(bool inHeader, bool includeCollections = true) 327 | { 328 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) 329 | ? string.Format( 330 | CultureInfo.InvariantCulture, 331 | "{0}using System;{1}" + 332 | "{2}", 333 | inHeader ? Environment.NewLine : "", 334 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", 335 | inHeader ? "" : Environment.NewLine) 336 | : ""; 337 | } 338 | } 339 | 340 | public class TypeMapper 341 | { 342 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 343 | 344 | private readonly System.Collections.IList _errors; 345 | private readonly CodeGenerationTools _code; 346 | private readonly MetadataTools _ef; 347 | 348 | public static string FixNamespaces(string typeName) 349 | { 350 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); 351 | } 352 | 353 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) 354 | { 355 | ArgumentNotNull(code, "code"); 356 | ArgumentNotNull(ef, "ef"); 357 | ArgumentNotNull(errors, "errors"); 358 | 359 | _code = code; 360 | _ef = ef; 361 | _errors = errors; 362 | } 363 | 364 | public string GetTypeName(TypeUsage typeUsage) 365 | { 366 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); 367 | } 368 | 369 | public string GetTypeName(EdmType edmType) 370 | { 371 | return GetTypeName(edmType, isNullable: null, modelNamespace: null); 372 | } 373 | 374 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace) 375 | { 376 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); 377 | } 378 | 379 | public string GetTypeName(EdmType edmType, string modelNamespace) 380 | { 381 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); 382 | } 383 | 384 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) 385 | { 386 | if (edmType == null) 387 | { 388 | return null; 389 | } 390 | 391 | var collectionType = edmType as CollectionType; 392 | if (collectionType != null) 393 | { 394 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); 395 | } 396 | 397 | var typeName = _code.Escape(edmType.MetadataProperties 398 | .Where(p => p.Name == ExternalTypeNameAttributeName) 399 | .Select(p => (string)p.Value) 400 | .FirstOrDefault()) 401 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? 402 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : 403 | _code.Escape(edmType)); 404 | 405 | if (edmType is StructuralType) 406 | { 407 | return typeName; 408 | } 409 | 410 | if (edmType is SimpleType) 411 | { 412 | var clrType = UnderlyingClrType(edmType); 413 | if (!IsEnumType(edmType)) 414 | { 415 | typeName = _code.Escape(clrType); 416 | } 417 | 418 | typeName = FixNamespaces(typeName); 419 | 420 | return clrType.IsValueType && isNullable == true ? 421 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : 422 | typeName; 423 | } 424 | 425 | throw new ArgumentException("edmType"); 426 | } 427 | 428 | public Type UnderlyingClrType(EdmType edmType) 429 | { 430 | ArgumentNotNull(edmType, "edmType"); 431 | 432 | var primitiveType = edmType as PrimitiveType; 433 | if (primitiveType != null) 434 | { 435 | return primitiveType.ClrEquivalentType; 436 | } 437 | 438 | if (IsEnumType(edmType)) 439 | { 440 | return GetEnumUnderlyingType(edmType).ClrEquivalentType; 441 | } 442 | 443 | return typeof(object); 444 | } 445 | 446 | public object GetEnumMemberValue(MetadataItem enumMember) 447 | { 448 | ArgumentNotNull(enumMember, "enumMember"); 449 | 450 | var valueProperty = enumMember.GetType().GetProperty("Value"); 451 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); 452 | } 453 | 454 | public string GetEnumMemberName(MetadataItem enumMember) 455 | { 456 | ArgumentNotNull(enumMember, "enumMember"); 457 | 458 | var nameProperty = enumMember.GetType().GetProperty("Name"); 459 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); 460 | } 461 | 462 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) 463 | { 464 | ArgumentNotNull(enumType, "enumType"); 465 | 466 | var membersProperty = enumType.GetType().GetProperty("Members"); 467 | return membersProperty != null 468 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) 469 | : Enumerable.Empty(); 470 | } 471 | 472 | public bool EnumIsFlags(EdmType enumType) 473 | { 474 | ArgumentNotNull(enumType, "enumType"); 475 | 476 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); 477 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); 478 | } 479 | 480 | public bool IsEnumType(GlobalItem edmType) 481 | { 482 | ArgumentNotNull(edmType, "edmType"); 483 | 484 | return edmType.GetType().Name == "EnumType"; 485 | } 486 | 487 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType) 488 | { 489 | ArgumentNotNull(enumType, "enumType"); 490 | 491 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); 492 | } 493 | 494 | public string CreateLiteral(object value) 495 | { 496 | if (value == null || value.GetType() != typeof(TimeSpan)) 497 | { 498 | return _code.CreateLiteral(value); 499 | } 500 | 501 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); 502 | } 503 | 504 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) 505 | { 506 | ArgumentNotNull(types, "types"); 507 | ArgumentNotNull(sourceFile, "sourceFile"); 508 | 509 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); 510 | if (types.Any(item => !hash.Add(item))) 511 | { 512 | _errors.Add( 513 | new CompilerError(sourceFile, -1, -1, "6023", 514 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); 515 | return false; 516 | } 517 | return true; 518 | } 519 | 520 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) 521 | { 522 | return GetItemsToGenerate(itemCollection) 523 | .Where(e => IsEnumType(e)); 524 | } 525 | 526 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType 527 | { 528 | return itemCollection 529 | .OfType() 530 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 531 | .OrderBy(i => i.Name); 532 | } 533 | 534 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) 535 | { 536 | return itemCollection 537 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) 538 | .Select(g => GetGlobalItemName(g)); 539 | } 540 | 541 | public string GetGlobalItemName(GlobalItem item) 542 | { 543 | if (item is EdmType) 544 | { 545 | return ((EdmType)item).Name; 546 | } 547 | else 548 | { 549 | return ((EntityContainer)item).Name; 550 | } 551 | } 552 | 553 | public IEnumerable GetSimpleProperties(EntityType type) 554 | { 555 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 556 | } 557 | 558 | public IEnumerable GetSimpleProperties(ComplexType type) 559 | { 560 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 561 | } 562 | 563 | public IEnumerable GetComplexProperties(EntityType type) 564 | { 565 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 566 | } 567 | 568 | public IEnumerable GetComplexProperties(ComplexType type) 569 | { 570 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 571 | } 572 | 573 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type) 574 | { 575 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 576 | } 577 | 578 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) 579 | { 580 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 581 | } 582 | 583 | public IEnumerable GetNavigationProperties(EntityType type) 584 | { 585 | return type.NavigationProperties.Where(np => np.DeclaringType == type); 586 | } 587 | 588 | public IEnumerable GetCollectionNavigationProperties(EntityType type) 589 | { 590 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); 591 | } 592 | 593 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction) 594 | { 595 | ArgumentNotNull(edmFunction, "edmFunction"); 596 | 597 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); 598 | return returnParamsProperty == null 599 | ? edmFunction.ReturnParameter 600 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); 601 | } 602 | 603 | public bool IsComposable(EdmFunction edmFunction) 604 | { 605 | ArgumentNotNull(edmFunction, "edmFunction"); 606 | 607 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); 608 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); 609 | } 610 | 611 | public IEnumerable GetParameters(EdmFunction edmFunction) 612 | { 613 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 614 | } 615 | 616 | public TypeUsage GetReturnType(EdmFunction edmFunction) 617 | { 618 | var returnParam = GetReturnParameter(edmFunction); 619 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); 620 | } 621 | 622 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) 623 | { 624 | var returnType = GetReturnType(edmFunction); 625 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; 626 | } 627 | } 628 | 629 | public static void ArgumentNotNull(T arg, string name) where T : class 630 | { 631 | if (arg == null) 632 | { 633 | throw new ArgumentNullException(name); 634 | } 635 | } 636 | #> -------------------------------------------------------------------------------- /CryptoShark/Model/CryptoSharkModel.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" debug="false" hostspecific="true"#> 2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@ 3 | output extension=".cs"#><# 4 | 5 | const string inputFile = @"CryptoSharkModel.edmx"; 6 | var textTransform = DynamicTextTransformation.Create(this); 7 | var code = new CodeGenerationTools(this); 8 | var ef = new MetadataTools(this); 9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors); 10 | var fileManager = EntityFrameworkTemplateFileManager.Create(this); 11 | var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); 12 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); 13 | 14 | if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) 15 | { 16 | return string.Empty; 17 | } 18 | 19 | WriteHeader(codeStringGenerator, fileManager); 20 | 21 | foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) 22 | { 23 | fileManager.StartNewFile(entity.Name + ".cs"); 24 | BeginNamespace(code); 25 | #> 26 | <#=codeStringGenerator.UsingDirectives(inHeader: false)#> 27 | <#=codeStringGenerator.EntityClassOpening(entity)#> 28 | { 29 | <# 30 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); 31 | var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); 32 | var complexProperties = typeMapper.GetComplexProperties(entity); 33 | 34 | if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) 35 | { 36 | #> 37 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 38 | public <#=code.Escape(entity)#>() 39 | { 40 | <# 41 | foreach (var edmProperty in propertiesWithDefaultValues) 42 | { 43 | #> 44 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; 45 | <# 46 | } 47 | 48 | foreach (var navigationProperty in collectionNavigationProperties) 49 | { 50 | #> 51 | this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); 52 | <# 53 | } 54 | 55 | foreach (var complexProperty in complexProperties) 56 | { 57 | #> 58 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); 59 | <# 60 | } 61 | #> 62 | } 63 | 64 | <# 65 | } 66 | 67 | var simpleProperties = typeMapper.GetSimpleProperties(entity); 68 | if (simpleProperties.Any()) 69 | { 70 | foreach (var edmProperty in simpleProperties) 71 | { 72 | #> 73 | <#=codeStringGenerator.Property(edmProperty)#> 74 | <# 75 | } 76 | } 77 | 78 | if (complexProperties.Any()) 79 | { 80 | #> 81 | 82 | <# 83 | foreach(var complexProperty in complexProperties) 84 | { 85 | #> 86 | <#=codeStringGenerator.Property(complexProperty)#> 87 | <# 88 | } 89 | } 90 | 91 | var navigationProperties = typeMapper.GetNavigationProperties(entity); 92 | if (navigationProperties.Any()) 93 | { 94 | #> 95 | 96 | <# 97 | foreach (var navigationProperty in navigationProperties) 98 | { 99 | if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) 100 | { 101 | #> 102 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 103 | <# 104 | } 105 | #> 106 | <#=codeStringGenerator.NavigationProperty(navigationProperty)#> 107 | <# 108 | } 109 | } 110 | #> 111 | } 112 | <# 113 | EndNamespace(code); 114 | } 115 | 116 | foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) 117 | { 118 | fileManager.StartNewFile(complex.Name + ".cs"); 119 | BeginNamespace(code); 120 | #> 121 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> 122 | <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> 123 | { 124 | <# 125 | var complexProperties = typeMapper.GetComplexProperties(complex); 126 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); 127 | 128 | if (propertiesWithDefaultValues.Any() || complexProperties.Any()) 129 | { 130 | #> 131 | public <#=code.Escape(complex)#>() 132 | { 133 | <# 134 | foreach (var edmProperty in propertiesWithDefaultValues) 135 | { 136 | #> 137 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; 138 | <# 139 | } 140 | 141 | foreach (var complexProperty in complexProperties) 142 | { 143 | #> 144 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); 145 | <# 146 | } 147 | #> 148 | } 149 | 150 | <# 151 | } 152 | 153 | var simpleProperties = typeMapper.GetSimpleProperties(complex); 154 | if (simpleProperties.Any()) 155 | { 156 | foreach(var edmProperty in simpleProperties) 157 | { 158 | #> 159 | <#=codeStringGenerator.Property(edmProperty)#> 160 | <# 161 | } 162 | } 163 | 164 | if (complexProperties.Any()) 165 | { 166 | #> 167 | 168 | <# 169 | foreach(var edmProperty in complexProperties) 170 | { 171 | #> 172 | <#=codeStringGenerator.Property(edmProperty)#> 173 | <# 174 | } 175 | } 176 | #> 177 | } 178 | <# 179 | EndNamespace(code); 180 | } 181 | 182 | foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) 183 | { 184 | fileManager.StartNewFile(enumType.Name + ".cs"); 185 | BeginNamespace(code); 186 | #> 187 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> 188 | <# 189 | if (typeMapper.EnumIsFlags(enumType)) 190 | { 191 | #> 192 | [Flags] 193 | <# 194 | } 195 | #> 196 | <#=codeStringGenerator.EnumOpening(enumType)#> 197 | { 198 | <# 199 | var foundOne = false; 200 | 201 | foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) 202 | { 203 | foundOne = true; 204 | #> 205 | <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, 206 | <# 207 | } 208 | 209 | if (foundOne) 210 | { 211 | this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); 212 | } 213 | #> 214 | } 215 | <# 216 | EndNamespace(code); 217 | } 218 | 219 | fileManager.Process(); 220 | 221 | #> 222 | <#+ 223 | 224 | public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) 225 | { 226 | fileManager.StartHeader(); 227 | #> 228 | //------------------------------------------------------------------------------ 229 | // 230 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> 231 | // 232 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> 233 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> 234 | // 235 | //------------------------------------------------------------------------------ 236 | <#=codeStringGenerator.UsingDirectives(inHeader: true)#> 237 | <#+ 238 | fileManager.EndBlock(); 239 | } 240 | 241 | public void BeginNamespace(CodeGenerationTools code) 242 | { 243 | var codeNamespace = code.VsNamespaceSuggestion(); 244 | if (!String.IsNullOrEmpty(codeNamespace)) 245 | { 246 | #> 247 | namespace <#=code.EscapeNamespace(codeNamespace)#> 248 | { 249 | <#+ 250 | PushIndent(" "); 251 | } 252 | } 253 | 254 | public void EndNamespace(CodeGenerationTools code) 255 | { 256 | if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) 257 | { 258 | PopIndent(); 259 | #> 260 | } 261 | <#+ 262 | } 263 | } 264 | 265 | public const string TemplateId = "CSharp_DbContext_Types_EF6"; 266 | 267 | public class CodeStringGenerator 268 | { 269 | private readonly CodeGenerationTools _code; 270 | private readonly TypeMapper _typeMapper; 271 | private readonly MetadataTools _ef; 272 | 273 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) 274 | { 275 | ArgumentNotNull(code, "code"); 276 | ArgumentNotNull(typeMapper, "typeMapper"); 277 | ArgumentNotNull(ef, "ef"); 278 | 279 | _code = code; 280 | _typeMapper = typeMapper; 281 | _ef = ef; 282 | } 283 | 284 | public string Property(EdmProperty edmProperty) 285 | { 286 | return string.Format( 287 | CultureInfo.InvariantCulture, 288 | "{0} {1} {2} {{ {3}get; {4}set; }}", 289 | Accessibility.ForProperty(edmProperty), 290 | _typeMapper.GetTypeName(edmProperty.TypeUsage), 291 | _code.Escape(edmProperty), 292 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 293 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); 294 | } 295 | 296 | public string NavigationProperty(NavigationProperty navProp) 297 | { 298 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 299 | return string.Format( 300 | CultureInfo.InvariantCulture, 301 | "{0} {1} {2} {{ {3}get; {4}set; }}", 302 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 303 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 304 | _code.Escape(navProp), 305 | _code.SpaceAfter(Accessibility.ForGetter(navProp)), 306 | _code.SpaceAfter(Accessibility.ForSetter(navProp))); 307 | } 308 | 309 | public string AccessibilityAndVirtual(string accessibility) 310 | { 311 | return accessibility + (accessibility != "private" ? " virtual" : ""); 312 | } 313 | 314 | public string EntityClassOpening(EntityType entity) 315 | { 316 | return string.Format( 317 | CultureInfo.InvariantCulture, 318 | "{0} {1}partial class {2}{3}", 319 | Accessibility.ForType(entity), 320 | _code.SpaceAfter(_code.AbstractOption(entity)), 321 | _code.Escape(entity), 322 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); 323 | } 324 | 325 | public string EnumOpening(SimpleType enumType) 326 | { 327 | return string.Format( 328 | CultureInfo.InvariantCulture, 329 | "{0} enum {1} : {2}", 330 | Accessibility.ForType(enumType), 331 | _code.Escape(enumType), 332 | _code.Escape(_typeMapper.UnderlyingClrType(enumType))); 333 | } 334 | 335 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) 336 | { 337 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 338 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) 339 | { 340 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; 341 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; 342 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; 343 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); 344 | } 345 | } 346 | 347 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) 348 | { 349 | var parameters = _typeMapper.GetParameters(edmFunction); 350 | 351 | return string.Format( 352 | CultureInfo.InvariantCulture, 353 | "{0} IQueryable<{1}> {2}({3})", 354 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 355 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 356 | _code.Escape(edmFunction), 357 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); 358 | } 359 | 360 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) 361 | { 362 | var parameters = _typeMapper.GetParameters(edmFunction); 363 | 364 | return string.Format( 365 | CultureInfo.InvariantCulture, 366 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", 367 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), 368 | edmFunction.NamespaceName, 369 | edmFunction.Name, 370 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), 371 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); 372 | } 373 | 374 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 375 | { 376 | var parameters = _typeMapper.GetParameters(edmFunction); 377 | var returnType = _typeMapper.GetReturnType(edmFunction); 378 | 379 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); 380 | if (includeMergeOption) 381 | { 382 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; 383 | } 384 | 385 | return string.Format( 386 | CultureInfo.InvariantCulture, 387 | "{0} {1} {2}({3})", 388 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), 389 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 390 | _code.Escape(edmFunction), 391 | paramList); 392 | } 393 | 394 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) 395 | { 396 | var parameters = _typeMapper.GetParameters(edmFunction); 397 | var returnType = _typeMapper.GetReturnType(edmFunction); 398 | 399 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); 400 | if (includeMergeOption) 401 | { 402 | callParams = ", mergeOption" + callParams; 403 | } 404 | 405 | return string.Format( 406 | CultureInfo.InvariantCulture, 407 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", 408 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", 409 | edmFunction.Name, 410 | callParams); 411 | } 412 | 413 | public string DbSet(EntitySet entitySet) 414 | { 415 | return string.Format( 416 | CultureInfo.InvariantCulture, 417 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}", 418 | Accessibility.ForReadOnlyProperty(entitySet), 419 | _typeMapper.GetTypeName(entitySet.ElementType), 420 | _code.Escape(entitySet)); 421 | } 422 | 423 | public string UsingDirectives(bool inHeader, bool includeCollections = true) 424 | { 425 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) 426 | ? string.Format( 427 | CultureInfo.InvariantCulture, 428 | "{0}using System;{1}" + 429 | "{2}", 430 | inHeader ? Environment.NewLine : "", 431 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", 432 | inHeader ? "" : Environment.NewLine) 433 | : ""; 434 | } 435 | } 436 | 437 | public class TypeMapper 438 | { 439 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 440 | 441 | private readonly System.Collections.IList _errors; 442 | private readonly CodeGenerationTools _code; 443 | private readonly MetadataTools _ef; 444 | 445 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) 446 | { 447 | ArgumentNotNull(code, "code"); 448 | ArgumentNotNull(ef, "ef"); 449 | ArgumentNotNull(errors, "errors"); 450 | 451 | _code = code; 452 | _ef = ef; 453 | _errors = errors; 454 | } 455 | 456 | public static string FixNamespaces(string typeName) 457 | { 458 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); 459 | } 460 | 461 | public string GetTypeName(TypeUsage typeUsage) 462 | { 463 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); 464 | } 465 | 466 | public string GetTypeName(EdmType edmType) 467 | { 468 | return GetTypeName(edmType, isNullable: null, modelNamespace: null); 469 | } 470 | 471 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace) 472 | { 473 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); 474 | } 475 | 476 | public string GetTypeName(EdmType edmType, string modelNamespace) 477 | { 478 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); 479 | } 480 | 481 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) 482 | { 483 | if (edmType == null) 484 | { 485 | return null; 486 | } 487 | 488 | var collectionType = edmType as CollectionType; 489 | if (collectionType != null) 490 | { 491 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); 492 | } 493 | 494 | var typeName = _code.Escape(edmType.MetadataProperties 495 | .Where(p => p.Name == ExternalTypeNameAttributeName) 496 | .Select(p => (string)p.Value) 497 | .FirstOrDefault()) 498 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? 499 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : 500 | _code.Escape(edmType)); 501 | 502 | if (edmType is StructuralType) 503 | { 504 | return typeName; 505 | } 506 | 507 | if (edmType is SimpleType) 508 | { 509 | var clrType = UnderlyingClrType(edmType); 510 | if (!IsEnumType(edmType)) 511 | { 512 | typeName = _code.Escape(clrType); 513 | } 514 | 515 | typeName = FixNamespaces(typeName); 516 | 517 | return clrType.IsValueType && isNullable == true ? 518 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : 519 | typeName; 520 | } 521 | 522 | throw new ArgumentException("edmType"); 523 | } 524 | 525 | public Type UnderlyingClrType(EdmType edmType) 526 | { 527 | ArgumentNotNull(edmType, "edmType"); 528 | 529 | var primitiveType = edmType as PrimitiveType; 530 | if (primitiveType != null) 531 | { 532 | return primitiveType.ClrEquivalentType; 533 | } 534 | 535 | if (IsEnumType(edmType)) 536 | { 537 | return GetEnumUnderlyingType(edmType).ClrEquivalentType; 538 | } 539 | 540 | return typeof(object); 541 | } 542 | 543 | public object GetEnumMemberValue(MetadataItem enumMember) 544 | { 545 | ArgumentNotNull(enumMember, "enumMember"); 546 | 547 | var valueProperty = enumMember.GetType().GetProperty("Value"); 548 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); 549 | } 550 | 551 | public string GetEnumMemberName(MetadataItem enumMember) 552 | { 553 | ArgumentNotNull(enumMember, "enumMember"); 554 | 555 | var nameProperty = enumMember.GetType().GetProperty("Name"); 556 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); 557 | } 558 | 559 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) 560 | { 561 | ArgumentNotNull(enumType, "enumType"); 562 | 563 | var membersProperty = enumType.GetType().GetProperty("Members"); 564 | return membersProperty != null 565 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) 566 | : Enumerable.Empty(); 567 | } 568 | 569 | public bool EnumIsFlags(EdmType enumType) 570 | { 571 | ArgumentNotNull(enumType, "enumType"); 572 | 573 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); 574 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); 575 | } 576 | 577 | public bool IsEnumType(GlobalItem edmType) 578 | { 579 | ArgumentNotNull(edmType, "edmType"); 580 | 581 | return edmType.GetType().Name == "EnumType"; 582 | } 583 | 584 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType) 585 | { 586 | ArgumentNotNull(enumType, "enumType"); 587 | 588 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); 589 | } 590 | 591 | public string CreateLiteral(object value) 592 | { 593 | if (value == null || value.GetType() != typeof(TimeSpan)) 594 | { 595 | return _code.CreateLiteral(value); 596 | } 597 | 598 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); 599 | } 600 | 601 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) 602 | { 603 | ArgumentNotNull(types, "types"); 604 | ArgumentNotNull(sourceFile, "sourceFile"); 605 | 606 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); 607 | if (types.Any(item => !hash.Add(item))) 608 | { 609 | _errors.Add( 610 | new CompilerError(sourceFile, -1, -1, "6023", 611 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); 612 | return false; 613 | } 614 | return true; 615 | } 616 | 617 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) 618 | { 619 | return GetItemsToGenerate(itemCollection) 620 | .Where(e => IsEnumType(e)); 621 | } 622 | 623 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType 624 | { 625 | return itemCollection 626 | .OfType() 627 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 628 | .OrderBy(i => i.Name); 629 | } 630 | 631 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) 632 | { 633 | return itemCollection 634 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) 635 | .Select(g => GetGlobalItemName(g)); 636 | } 637 | 638 | public string GetGlobalItemName(GlobalItem item) 639 | { 640 | if (item is EdmType) 641 | { 642 | return ((EdmType)item).Name; 643 | } 644 | else 645 | { 646 | return ((EntityContainer)item).Name; 647 | } 648 | } 649 | 650 | public IEnumerable GetSimpleProperties(EntityType type) 651 | { 652 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 653 | } 654 | 655 | public IEnumerable GetSimpleProperties(ComplexType type) 656 | { 657 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 658 | } 659 | 660 | public IEnumerable GetComplexProperties(EntityType type) 661 | { 662 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 663 | } 664 | 665 | public IEnumerable GetComplexProperties(ComplexType type) 666 | { 667 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 668 | } 669 | 670 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type) 671 | { 672 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 673 | } 674 | 675 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) 676 | { 677 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 678 | } 679 | 680 | public IEnumerable GetNavigationProperties(EntityType type) 681 | { 682 | return type.NavigationProperties.Where(np => np.DeclaringType == type); 683 | } 684 | 685 | public IEnumerable GetCollectionNavigationProperties(EntityType type) 686 | { 687 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); 688 | } 689 | 690 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction) 691 | { 692 | ArgumentNotNull(edmFunction, "edmFunction"); 693 | 694 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); 695 | return returnParamsProperty == null 696 | ? edmFunction.ReturnParameter 697 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); 698 | } 699 | 700 | public bool IsComposable(EdmFunction edmFunction) 701 | { 702 | ArgumentNotNull(edmFunction, "edmFunction"); 703 | 704 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); 705 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); 706 | } 707 | 708 | public IEnumerable GetParameters(EdmFunction edmFunction) 709 | { 710 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 711 | } 712 | 713 | public TypeUsage GetReturnType(EdmFunction edmFunction) 714 | { 715 | var returnParam = GetReturnParameter(edmFunction); 716 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); 717 | } 718 | 719 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) 720 | { 721 | var returnType = GetReturnType(edmFunction); 722 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; 723 | } 724 | } 725 | 726 | public static void ArgumentNotNull(T arg, string name) where T : class 727 | { 728 | if (arg == null) 729 | { 730 | throw new ArgumentNullException(name); 731 | } 732 | } 733 | #> --------------------------------------------------------------------------------