public MineableReward GetBestMineable(MineableReward bestPoolminedCoin, MineableReward bestNicehashAlgorithm, MineableReward currentReward, Settings settings) { if (bestPoolminedCoin.Mineable != null && bestPoolminedCoin.Reward > bestNicehashAlgorithm.Reward) { Console.WriteLine($"Determined best mining method: Mine {bestPoolminedCoin.Mineable.DisplayName} in a pool at {Helpers.ToCurrency(bestPoolminedCoin.Reward, "$")} per day."); if (currentReward != null && settings.ProfitSwitchThreshold > 0 && currentReward.Mineable.Id != bestPoolminedCoin.Mineable.Id) { if (currentReward.Reward * (1 + settings.ProfitSwitchThreshold) > bestPoolminedCoin.Reward) { Console.WriteLine($"But will stay mining {currentReward.Mineable.DisplayName} because of the profit switch threshold."); return(currentReward); } } return(bestPoolminedCoin); } else if (bestNicehashAlgorithm.Mineable != null) { Console.WriteLine($"Determined best mining method: Provide hash power for {bestNicehashAlgorithm.Mineable.DisplayName} on NiceHash at {Helpers.ToCurrency(bestNicehashAlgorithm.Reward, "$")} per day."); if (currentReward != null && settings.ProfitSwitchThreshold > 0 && currentReward.Mineable.Id != bestNicehashAlgorithm.Mineable.Id) { if (currentReward.Reward * (1 + settings.ProfitSwitchThreshold) > bestNicehashAlgorithm.Reward) { Console.WriteLine($"But will stay mining {currentReward.Mineable.DisplayName} because of the profit switch threshold."); return(currentReward); } } return(bestNicehashAlgorithm); } else { Console.WriteLine("Couldn't determine best mining method."); return(null); } }
public MineableRewardResult GetBestNicehashAlgorithm(IList <NicehashAlgorithm> nicehashAlgorithms, Mineable currentMineable, Dictionary <int, Profit> nicehashProfitsDictionary, Settings settings) { MineableReward currentReward = null; NicehashAlgorithm bestNicehashAlgorithm = null; double bestNicehashAlgorithmProfit = 0; foreach (var nicehashAlgorithm in nicehashAlgorithms.Where(na => na.IsEnabled())) { Profit profit = nicehashProfitsDictionary.GetValueOrDefault(nicehashAlgorithm.ApiId, new Profit()); double preferFactor = 1; if (nicehashAlgorithm.PreferFactor.HasValue) { preferFactor = nicehashAlgorithm.PreferFactor.Value; } else { //Backwards compatibility if (settings.NicehashPreferFactor >= 0) { preferFactor = settings.NicehashPreferFactor; } } double calcProfit = GetReward(profit, nicehashAlgorithm, settings.ProfitTimeframe) * preferFactor; if (currentMineable != null && nicehashAlgorithm.Id == currentMineable.Id) { currentReward = new MineableReward(currentMineable, calcProfit); } if (bestNicehashAlgorithm == null || calcProfit > bestNicehashAlgorithmProfit) { bestNicehashAlgorithmProfit = calcProfit; bestNicehashAlgorithm = nicehashAlgorithm; } } return(new MineableRewardResult(new MineableReward(bestNicehashAlgorithm, bestNicehashAlgorithmProfit), currentReward)); }
public MineableReward GetBestMineable(MineableReward bestPoolminedCoin, MineableReward bestNicehashAlgorithm, MineableReward currentReward, Settings settings) { if (bestPoolminedCoin.Mineable != null) { Console.WriteLine($"Determined best mining method: Mine {bestPoolminedCoin.Mineable.DisplayName} in a pool with relative factor {bestPoolminedCoin.Reward}."); if (currentReward != null && settings.ProfitSwitchThreshold > 0 && currentReward.Mineable.Id != bestPoolminedCoin.Mineable.Id) { if (currentReward.Reward * (1 + settings.ProfitSwitchThreshold) > bestPoolminedCoin.Reward) { Console.WriteLine($"But will stay mining {currentReward.Mineable.DisplayName} because of the profit switch threshold."); return(currentReward); } } return(bestPoolminedCoin); } else { Console.WriteLine("Couldn't determine best mining method."); return(null); } }
public MineableRewardResult GetBestPoolminedCoin(IList <Coin> coins, Mineable currentMineable, Dictionary <ProfitProvider, Dictionary <string, Profit> > poolProfitsDictionary, Settings settings) { MineableReward currentReward = null; Coin bestPoolminedCoin = null; double bestPoolminedCoinProfit = 0; foreach (var coin in coins.Where(c => c.IsEnabled())) { var profit = Helpers.GetPoolProfitForCoin(coin, poolProfitsDictionary, settings); double reward = GetReward(profit, coin, settings.ProfitTimeframe); double calcProfit = coin.PreferFactor.HasValue ? reward * coin.PreferFactor.Value : reward; if (currentMineable != null && coin.Id == currentMineable.Id) { currentReward = new MineableReward(currentMineable, calcProfit); } if (bestPoolminedCoin == null || calcProfit > bestPoolminedCoinProfit) { bestPoolminedCoinProfit = calcProfit; bestPoolminedCoin = coin; } } return(new MineableRewardResult(new MineableReward(bestPoolminedCoin, bestPoolminedCoinProfit), currentReward)); }
private static Task ProfitSwitcherTaskAsync(string appFolderPath, DirectoryInfo appRootFolder, Settings settings, List <Coin> coins, List <NicehashAlgorithm> nicehashAlgorithms, CancellationToken token) { return(Task.Run(() => { //Get pool profit data while (!token.IsCancellationRequested) { var statusCts = new CancellationTokenSource(); var watchdogCts = new CancellationTokenSource(); try { ResetConsole(); // Get pool mined coins profitability var timeoutCts = new CancellationTokenSource(60000); var childCts = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCts.Token); var profitProviders = Helpers.GetPoolProfitProviders(settings, null); foreach (var coin in coins.Where(c => !String.IsNullOrEmpty(c.OverridePoolProfitProviders))) { foreach (var profitProviderString in coin.OverridePoolProfitProviders.Split(",")) { ProfitProvider profitProvider; if (Enum.TryParse(profitProviderString, out profitProvider)) { if (!profitProviders.Contains(profitProvider)) { profitProviders.Add(profitProvider); } } } } var poolProfitsDictionaryUnordered = new Dictionary <ProfitProvider, Dictionary <string, Profit> >(); var profitProviderTasks = new List <Task>(); foreach (var profitProvider in profitProviders) { if (!poolProfitsDictionaryUnordered.ContainsKey(profitProvider)) { profitProviderTasks.Add(Task.Run(() => { IPoolProfitProvider profitProviderClass = PoolProfitProviderFactory.GetPoolProfitProvider(profitProvider); poolProfitsDictionaryUnordered[profitProvider] = profitProviderClass.GetProfits(appRootFolder, settings, coins, childCts.Token); }, childCts.Token)); } } #if DEBUG Stopwatch sw = new Stopwatch(); sw.Start(); #endif Task.WhenAll(profitProviderTasks).Wait(childCts.Token); #if DEBUG sw.Stop(); Console.WriteLine($"Fetching profit data took {(int)sw.Elapsed.TotalSeconds} seconds."); #endif //Reorder because of async var poolProfitsDictionary = new Dictionary <ProfitProvider, Dictionary <string, Profit> >(); foreach (var profitProvider in profitProviders) { if (poolProfitsDictionaryUnordered.ContainsKey(profitProvider)) { poolProfitsDictionary[profitProvider] = poolProfitsDictionaryUnordered[profitProvider]; } } IProfitSwitchingStrategy profitSwitchingStrategy = ProfitSwitchingStrategyFactory.GetProfitSwitchingStrategy(settings.ProfitSwitchingStrategy); MineableReward currentReward = null; // Get best pool mined coin MineableReward bestPoolminedCoin = null; if (!token.IsCancellationRequested) { var result = profitSwitchingStrategy.GetBestPoolminedCoin(coins, _currentMineable, poolProfitsDictionary, settings); bestPoolminedCoin = result?.Result; if (currentReward == null) { currentReward = result?.Current; } if (bestPoolminedCoin?.Mineable != null) { Console.WriteLine("Got best pool mined coin: " + bestPoolminedCoin.Mineable.DisplayName); } else { Console.WriteLine("Couldn't determine best pool mined coin."); } } //Get Nicehash Profit Dictionary <int, Profit> nicehashProfitsDictionary = null; if (!token.IsCancellationRequested) { nicehashProfitsDictionary = NicehashApi.GetProfits(appRootFolder, settings, nicehashAlgorithms, childCts.Token); } //Get best nicehash algorithm MineableReward bestNicehashAlgorithm = null; if (!token.IsCancellationRequested && nicehashProfitsDictionary != null) { var result = profitSwitchingStrategy.GetBestNicehashAlgorithm(nicehashAlgorithms, _currentMineable, nicehashProfitsDictionary, settings); bestNicehashAlgorithm = result?.Result; if (currentReward == null) { currentReward = result?.Current; } if (bestNicehashAlgorithm?.Mineable != null) { Console.WriteLine("Got best nicehash algorithm: " + bestNicehashAlgorithm.Mineable.DisplayName); } else { Console.WriteLine("Couldn't determine best nicehash algorithm."); } } //Sort profit table if (settings.ProfitSorting != SortingMode.None) { var coinProfitComparer = new CoinProfitComparer(settings.ProfitSorting, poolProfitsDictionary); coins.Sort(coinProfitComparer); var nicehashProfitComparer = new NicehashProfitComparer(settings.ProfitSorting, nicehashProfitsDictionary); nicehashAlgorithms.Sort(nicehashProfitComparer); } //Print table if (!token.IsCancellationRequested && nicehashProfitsDictionary != null) { PrintProfitTable(coins, poolProfitsDictionary, nicehashAlgorithms, nicehashProfitsDictionary, settings); } //Mine using best algorithm/coin if (!token.IsCancellationRequested) { Console.WriteLine(); Mineable bestOverallMineable = null; if (_manualSelection && _manualSelectedMineable != null) { bestOverallMineable = _manualSelectedMineable; } else { bestOverallMineable = profitSwitchingStrategy.GetBestMineable(bestPoolminedCoin, bestNicehashAlgorithm, currentReward, settings)?.Mineable; } if (bestOverallMineable != null) { Console.WriteLine($"Determined best mining method: {bestOverallMineable.DisplayName}"); if (_currentMineable == null || _currentMineable.Id != bestOverallMineable.Id) { StartMiner(bestOverallMineable, settings, appFolderPath, appRootFolder); } } else { Log.Information("Couldn't determine best mining method."); } } var statusUpdaterTask = StatusUpdaterTaskAsync(DateTimeOffset.Now.AddSeconds(settings.ProfitCheckInterval), settings, appRootFolder, coins, poolProfitsDictionary, nicehashAlgorithms, nicehashProfitsDictionary, statusCts.Token); if (!token.IsCancellationRequested) { if (settings.ProfitCheckInterval > 0) { Task.Delay(TimeSpan.FromSeconds(settings.ProfitCheckInterval), token).Wait(token); } else { token.WaitHandle.WaitOne(); } } statusCts.Cancel(); } catch (TaskCanceledException) { Log.Information("Cancelled profit task."); statusCts.Cancel(); } catch (AggregateException) { Log.Information("Cancelled profit task 2."); statusCts.Cancel(); } catch (OperationCanceledException) { Log.Information("Cancelled profit task 3."); statusCts.Cancel(); } catch (Exception ex) { Log.Error("Profit switcher task failed: " + ex); statusCts.Cancel(); } } }, token)); }