// Awesome Profit Switching v1.0.6
public class ActionScript
{
private ContextProvider Context = ScriptManager.Context;
public bool Execute(List list)
{
Context.System.LogMessage("Awesome Profit Switching: " + list.Count + " miner(s).");
List poolProfitList = new List();
// Download latest statistics before we check profitability
Context.OnlineService.UpdateStatisticsAll();
Context.System.LogMessage("Awesome Profit Switching: Statistics updated");
// Process each selected miner
foreach (IMinerBase miner in list)
{
if (!miner.IsRunningState)
continue;
Context.System.LogMessage("Awesome Profit Switching processing: " + miner.GetDescription());
ISinglePool currentPool = Context.Pool.GetActive(miner);
if (currentPool != null)
{
// Each miner has its own list of pools
List minerPoolProfitList = new List();
List preservePoolList = new List();
// Get all active pools for the miner (for Primitive miners, include Disabled pools)
List coinPoolList = Context.Pool.GetActivePoolList(miner, false, true, miner.IsPrimitive);
// Add all pools into minerPoolProfitList if it should be target for profit switching
// or to preservePoolList if we can't switch away from that pool
foreach (ISinglePool coinPool in coinPoolList)
{
PoolProfit poolProfit = new PoolProfit(coinPool);
if (poolProfit.IsValid())
{
IPoolStatus poolStatus = miner.GetPoolStatus(poolProfit.Pool);
if (poolStatus != null)
{
poolProfit.Priority = poolStatus.GetPriority();
if (poolProfit.IsPreservePool)
preservePoolList.Add(poolProfit);
else
minerPoolProfitList.Add(poolProfit);
}
}
}
// Sort to get highest profit first in list
minerPoolProfitList.Sort((item1, item2) => item2.GetProfit().CompareTo(item1.GetProfit()));
// Sort preseve pools by Priority order, lowest number first
preservePoolList.Sort((item1, item2) => item1.Priority.CompareTo(item2.Priority));
LogList("Profitability information", minerPoolProfitList);
LogList("Preserve list", preservePoolList);
// Construct list of pools in priority order. First the pools to preserve at top priority and then by profitability
List priorityList = new List();
preservePoolList.ForEach(item => priorityList.Add(item.Pool));
minerPoolProfitList.ForEach(item => priorityList.Add(item.Pool));
if (miner.IsPrimitive)
{
// For nVidia CUDA
if (coinPoolList.Count > 0 && priorityList.Count > 0 && coinPoolList[0].ID != priorityList[0].ID)
{
Context.System.LogMessage("Profitability, Changing to pool: " + priorityList[0].GetDescription());
Context.Pool.Prioritize(miner, priorityList[0]);
}
else
Context.System.LogMessage("Profitability, Already using pool: " + priorityList[0].GetDescription());
}
else
{
Context.Pool.SetPriority(miner, priorityList);
}
}
}
return true;
}
private void LogList(string message, List profitList)
{
string info = string.Empty;
foreach (PoolProfit poolProfit in profitList)
info += " " + poolProfit.Pool.GetDescription() + ", Url: " + poolProfit.Pool.GetUrl() +
", Profit: " + poolProfit.GetProfit() + ", Priority: " + poolProfit.Priority + "\r\n";
Context.System.LogMessage(message + ":\r\n " + info.Trim());
}
}
class PoolProfit
{
// To disable an algorithm, set factor to 0.
// To make it less likely to be used, set to lower value than 1.0.
// Using 0.5 would require the profit to be two times as high before selecting the algorithm
private Dictionary algorithmFactor = new Dictionary {
{ CoinAlgorithm.Scrypt, 1.0 },
{ CoinAlgorithm.ScryptAN, 1.0 },
{ CoinAlgorithm.SHA3, 1.0 },
{ CoinAlgorithm.X11, 1.0 },
{ CoinAlgorithm.X13, 1.0 },
{ CoinAlgorithm.X15, 1.0 },
{ CoinAlgorithm.Nist5, 1.0 },
};
// Define profitability factor for each service type.
private Dictionary serviceTypeFactor = new Dictionary {
{ OnlineServiceType.TradeMyBit, 0.975 }, // 0.5% fee + 2% Auto BTC exchange fee
{ OnlineServiceType.NiceHash, 1.0 },
{ OnlineServiceType.WestHash, 1.0 },
{ OnlineServiceType.LtcRabbit, 0.98 }, // 2% fee
{ OnlineServiceType.Yaamp, 0.99 }, // 1% fee
};
private Dictionary poolServices = new Dictionary {
// NiceHash standard pools
{"nicehash.com:3340", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.Nist5)},
{"nicehash.com:3333", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.Scrypt)},
{"nicehash.com:3335", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.ScryptAN)},
{"nicehash.com:3338", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.SHA3)},
{"nicehash.com:3336", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X11)},
{"nicehash.com:3337", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X13)},
{"nicehash.com:3339", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X15)},
// NiceHash auto-close pools
{"nicehash.com:4340", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.Nist5)},
{"nicehash.com:4333", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.Scrypt)},
{"nicehash.com:4335", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.ScryptAN)},
{"nicehash.com:4338", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.SHA3)},
{"nicehash.com:4336", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X11)},
{"nicehash.com:4337", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X13)},
{"nicehash.com:4339", new PoolService(OnlineServiceType.NiceHash, CoinAlgorithm.X15)},
// WestHash standard pools
{"westhash.com:3340", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.Nist5)},
{"westhash.com:3333", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.Scrypt)},
{"westhash.com:3335", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.ScryptAN)},
{"westhash.com:3338", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.SHA3)},
{"westhash.com:3336", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X11)},
{"westhash.com:3337", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X13)},
{"westhash.com:3339", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X15)},
// WestHash auto-close pools
{"westhash.com:4340", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.Nist5)},
{"westhash.com:4333", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.Scrypt)},
{"westhash.com:4335", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.ScryptAN)},
{"westhash.com:4338", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.SHA3)},
{"westhash.com:4336", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X11)},
{"westhash.com:4337", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X13)},
{"westhash.com:4339", new PoolService(OnlineServiceType.WestHash, CoinAlgorithm.X15)},
// TradeByBit standard pools
{"trademybit.com:7770", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.Nist5)},
{"trademybit.com:3330", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.Scrypt)},
{"trademybit.com:3000", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.Scrypt)}, // Scrypt HighDiff
{"trademybit.com:2220", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.ScryptAN)},
{"trademybit.com:4440", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X11)},
{"trademybit.com:5550", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X13)},
{"trademybit.com:6660", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X15)},
// TradeByBit auto-close pools
{"trademybit.com:4013", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.Nist5)},
{"trademybit.com:4010", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X11)},
{"trademybit.com:4011", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X13)},
{"trademybit.com:4012", new PoolService(OnlineServiceType.TradeMyBit, CoinAlgorithm.X15)},
// LTCRabbit
{"ltcrabbit.com:3333", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.Scrypt)},
{"ltcrabbit.com:3335", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.Scrypt)},
{"ltcrabbit.com:3336", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.Scrypt)},
{"ltcrabbit.com:3337", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.Scrypt)},
{"ltcrabbit.com:3338", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.Scrypt)},
{"ltcrabbit.com:3332", new PoolService(OnlineServiceType.LtcRabbit, CoinAlgorithm.X11)},
// yaamp.com
{"yaamp.com:3433", new PoolService(OnlineServiceType.Yaamp, CoinAlgorithm.Scrypt)},
{"yaamp.com:3533", new PoolService(OnlineServiceType.Yaamp, CoinAlgorithm.X11)},
{"yaamp.com:3633", new PoolService(OnlineServiceType.Yaamp, CoinAlgorithm.X13)},
{"yaamp.com:3733", new PoolService(OnlineServiceType.Yaamp, CoinAlgorithm.X15)},
};
// Always put these pools on top priority, before all profitability pools
private List preservePoolServices = new List() {
"betarigs.com",
"miningrigrentals.com",
};
public bool IsPreservePool { get; private set; }
public int Priority { get; set; }
public ISinglePool Pool { get; private set; }
public OnlineServiceType ServiceType { get; private set; }
public CoinAlgorithm Algorithm { get; private set; }
public double Profit { get; private set; }
private PoolServiceClass PoolClass { get; set; }
private int Port { get; set; }
private class PoolService
{
public OnlineServiceType ServiceType { get; private set; }
public CoinAlgorithm Algorithm { get; private set; }
public PoolService(OnlineServiceType serviceType, CoinAlgorithm algorithm)
{
ServiceType = serviceType;
Algorithm = algorithm;
}
}
private enum PoolServiceClass
{
UserDefined,
MultiCoinPool,
SingleCoinPool,
}
public PoolProfit(ISinglePool pool)
{
Pool = pool;
if (pool != null)
{
string url = pool.GetUrl().ToLower();
// Check if a preserve-pool like Betarigs that we shouldn't prioritize away
IsPreservePool = preservePoolServices.Find(item => url.Contains(item)) != null;
if (!IsPreservePool)
{
// Search for ServiceType (supported multi-pools) using Pool URL
PoolService poolService = null;
foreach (KeyValuePair kvp in poolServices)
{
if (url.EndsWith(kvp.Key))
{
poolService = kvp.Value;
break;
}
}
if (poolService != null)
{
// Multi-pool service
ServiceType = poolService.ServiceType;
Algorithm = poolService.Algorithm;
PoolClass = PoolServiceClass.MultiCoinPool;
}
else
{
// Check if known single coin pool (TradeMyBit)
OnlineServiceType serviceType;
CoinAlgorithm algorithm;
int port;
if (ScriptManager.Context.OnlineService.GetKnownSingleCoinPool(url, out serviceType, out algorithm, out port))
{
ServiceType = serviceType;
Algorithm = algorithm;
Port = port;
PoolClass = PoolServiceClass.SingleCoinPool;
}
else // Any other single coin pool
{
PoolClass = PoolServiceClass.UserDefined;
Algorithm = ScriptManager.Context.Pool.GetPoolAlgorithm(pool);
}
}
}
}
}
public double GetProfit()
{
if (PoolClass == PoolServiceClass.MultiCoinPool)
{
IOnlineServiceEntry entry = ScriptManager.Context.OnlineService.GetEntry(ServiceType, Algorithm);
return (entry != null) ? entry.BtcPerNormalizedMhsPerDay * GetAlgorithmFactor() * GetServiceTypeFactor() : 0;
}
else if (PoolClass == PoolServiceClass.SingleCoinPool)
{
IOnlineServiceEntry entry = ScriptManager.Context.OnlineService.GetEntry(ServiceType, Port);
return (entry != null) ? entry.BtcPerNormalizedMhsPerDay * GetAlgorithmFactor() * GetServiceTypeFactor() : 0;
}
else
return ScriptManager.Context.Pool.GetPoolRevenuePerDay(Pool, true) * GetAlgorithmFactor();
}
public bool IsValid()
{
return Pool != null && (PoolClass != PoolServiceClass.MultiCoinPool || ScriptManager.Context.OnlineService.GetEntry(ServiceType, Algorithm) != null);
}
private double GetAlgorithmFactor()
{
if (algorithmFactor.ContainsKey(Algorithm))
return algorithmFactor[Algorithm];
else
return 1;
}
private double GetServiceTypeFactor()
{
if (serviceTypeFactor.ContainsKey(ServiceType))
return serviceTypeFactor[ServiceType];
else
return 1;
}
}
