Initial Commit
commit
bf1b64db7d
|
@ -0,0 +1,40 @@
|
|||
# Autosave files
|
||||
*~
|
||||
|
||||
# build
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
packages/
|
||||
TestResults/
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.DS_Store
|
||||
*.sln.cache
|
||||
*.suo
|
||||
*.cache
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.log
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.user
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
Thumbs.db
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# resharper
|
||||
*_Resharper.*
|
||||
*.Resharper
|
||||
|
||||
# dotCover
|
||||
*.dotCover
|
|
@ -0,0 +1,370 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using sharp.tradebot;
|
||||
using sharp.json;
|
||||
using sharp.json.attributes;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using sharp.trading.logging;
|
||||
using sharp.trading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Remoting;
|
||||
|
||||
namespace TradeBot
|
||||
{
|
||||
public class BotManager
|
||||
{
|
||||
public TradingBotEnvironment BotEnvironment { get; private set; }
|
||||
public String DataBaseFile { get; private set; }
|
||||
|
||||
|
||||
List<TradingBotInstance> instances = new List<TradingBotInstance>();
|
||||
|
||||
public BotManager(string baseDirectory)
|
||||
{
|
||||
DataBaseFile = Path.Combine(baseDirectory, "botmanager.json");
|
||||
BotEnvironment = new TradingBotEnvironment(TradingEnvironment.DefaultConnection, baseDirectory);
|
||||
|
||||
if (!Directory.Exists(Path.Combine(BotEnvironment.BaseDataDirectory, "logs"))){
|
||||
Directory.CreateDirectory(Path.Combine(BotEnvironment.BaseDataDirectory, "logs"));
|
||||
}
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
TradingBotInstance[] _instances = JSON.ReadFrom(DataBaseFile,new TradingBotInstance[0]).To<TradingBotInstance[]>();
|
||||
if (_instances != null)
|
||||
{
|
||||
instances.AddRange(_instances);
|
||||
}
|
||||
}
|
||||
|
||||
private void save()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
JSON.From(instances.ToArray()).WriteTo(DataBaseFile, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
public Guid RegisterBot(string DllPath, string ClassName)
|
||||
{
|
||||
Guid guid = Guid.NewGuid();
|
||||
lock (this)
|
||||
{
|
||||
RegisterBot(DllPath, ClassName, guid);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
public void RegisterBot(string DllPath, string ClassName, Guid uid)
|
||||
{
|
||||
TradingBotInstance i = new TradingBotInstance();
|
||||
i.DllPath = DllPath;
|
||||
i.ClassName = ClassName;
|
||||
i.UID = uid;
|
||||
lock (this)
|
||||
{
|
||||
this.instances.Add(i);
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterBot(Guid guid)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
foreach (TradingBotInstance inst in instances)
|
||||
{
|
||||
if (inst.UID.Equals(guid))
|
||||
{
|
||||
UnloadBot(inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void LoadBot(String uid){
|
||||
LoadBot(findBot(Guid.Parse(uid)));
|
||||
}
|
||||
public void UnloadBot(String uid)
|
||||
{
|
||||
UnloadBot(findBot(Guid.Parse(uid)));
|
||||
}
|
||||
|
||||
public void LoadBot(Guid uid)
|
||||
{
|
||||
LoadBot(findBot(uid));
|
||||
}
|
||||
public void UnloadBot(Guid uid)
|
||||
{
|
||||
UnloadBot(findBot(uid));
|
||||
}
|
||||
|
||||
public void LoadBotAndPrepare(Guid uid)
|
||||
{
|
||||
LoadBotAndPrepare(findBot(uid));
|
||||
}
|
||||
|
||||
|
||||
public void LoadBotAndPrepare(TradingBotInstance bot)
|
||||
{
|
||||
bot.Load(BotEnvironment);
|
||||
bot.Prepare();
|
||||
}
|
||||
|
||||
public void LoadBot(TradingBotInstance bot)
|
||||
{
|
||||
bot.Load(BotEnvironment);
|
||||
}
|
||||
public void UnloadBot(TradingBotInstance bot)
|
||||
{
|
||||
bot.Unload();
|
||||
}
|
||||
|
||||
public void LoadAllBots(){
|
||||
foreach (TradingBotInstance bot in instances){
|
||||
bot.Load(BotEnvironment);
|
||||
}
|
||||
}
|
||||
|
||||
public TradingBotInstance[] RegisteredBots{
|
||||
get { return this.instances.ToArray(); }
|
||||
}
|
||||
|
||||
private TradingBotInstance findBot(Guid uid){
|
||||
foreach (TradingBotInstance inst in instances){
|
||||
if (inst.UID.Equals(uid)){
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("[BotManager Dump]");
|
||||
foreach (TradingBotInstance i in instances)
|
||||
{
|
||||
sb.AppendLine(i.ToString());
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[JSONClassPolicy(Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class TradingBotInstance : MarshalByRefObject
|
||||
{
|
||||
[JSONField]
|
||||
public String DllPath { get; set; }
|
||||
[JSONField]
|
||||
public String ClassName { get; set; }
|
||||
[JSONField]
|
||||
public Guid UID { get; set; }
|
||||
|
||||
private AppDomain _appDomain;
|
||||
private Assembly _assembly;
|
||||
private TradeBotLoader loader;
|
||||
private TradingBot _instance;
|
||||
private Logger _logger;
|
||||
|
||||
/*
|
||||
|
||||
public void Load(TradingBotEnvironment environment)
|
||||
{
|
||||
AppDomainSetup ads = new AppDomainSetup();
|
||||
// ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
this._appDomain = AppDomain.CreateDomain(String.Format("TradeBotLoader:{0}:{1}", UID, Guid.NewGuid().ToString()), AppDomain.CurrentDomain.Evidence, ads);
|
||||
this.loader = (TradeBotLoader)this._appDomain.CreateInstanceFromAndUnwrap("sharp.tradebot.dll", "sharp.tradebot.TradeBotLoader");
|
||||
this.loader.DllPath = DllPath;
|
||||
this.loader.ClassName = ClassName;
|
||||
this.loader.UID = UID;
|
||||
|
||||
this.loader.Load(environment);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
if (this.loader != null){
|
||||
this.loader.Unload();
|
||||
}
|
||||
AppDomain.Unload(this._appDomain);
|
||||
this._appDomain = null;
|
||||
this.loader = null;
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
if (this.loader != null){
|
||||
this.loader.Prepare();
|
||||
}
|
||||
}
|
||||
|
||||
public void Unprepare()
|
||||
{
|
||||
if (this.loader != null){
|
||||
this.loader.Unprepare();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
public void Load(TradingBotEnvironment environment)
|
||||
{
|
||||
//AppDomainSetup ads = new AppDomainSetup();
|
||||
// ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
//this._appDomain = AppDomain.CreateDomain(String.Format("{0}:{1}:{2}:{3}", DllPath, ClassName, UID, Guid.NewGuid().ToString()), AppDomain.CurrentDomain.Evidence, ads);
|
||||
//this._instance = (TradingBot)this._appDomain.CreateInstanceFromAndUnwrap(DllPath, ClassName);
|
||||
this._instance = (TradingBot)Activator.CreateInstanceFrom(DllPath, ClassName).Unwrap();
|
||||
this._logger = new FileLogger(Path.Combine(environment.BaseDataDirectory, "logs", String.Format("{0}.log", UID.ToString())));
|
||||
this._instance.AfterLoad(environment, UID, this._logger,null);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
if (this._instance != null)
|
||||
{
|
||||
lock (this._instance)
|
||||
{
|
||||
if (this._instance.IsPrepared)
|
||||
{
|
||||
this._instance.Unprepare();
|
||||
}
|
||||
this._logger.Close();
|
||||
this._logger = null;
|
||||
}
|
||||
this._instance = null;
|
||||
//AppDomain.Unload(this._appDomain);
|
||||
this._appDomain = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
if (this._instance != null)
|
||||
{
|
||||
lock (this._instance)
|
||||
{
|
||||
this._instance.Prepare();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unprepare()
|
||||
{
|
||||
if (this._instance != null)
|
||||
{
|
||||
lock (this._instance)
|
||||
{
|
||||
this._instance.Unprepare();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
[JSONClassPolicy(Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class BotDll
|
||||
{
|
||||
[JSONField]
|
||||
public string FileName { get; private set;}
|
||||
|
||||
private AppDomain appDomain;
|
||||
private Assembly assembly;
|
||||
|
||||
public Type[] BotClasses { get; private set; }
|
||||
|
||||
public BotDll(string filename){
|
||||
FileName = filename;
|
||||
}
|
||||
|
||||
public void Load(){
|
||||
if (appDomain == null){
|
||||
AppDomainSetup ads = new AppDomainSetup();
|
||||
ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
this.appDomain = AppDomain.CreateDomain(FileName,AppDomain.CurrentDomain.Evidence,ads);
|
||||
|
||||
//this.assembly = this.appDomain.Load(FileName);
|
||||
|
||||
try {
|
||||
TradingBot bot = (TradingBot)this.appDomain.CreateInstanceFromAndUnwrap(FileName, "BigBot.BigBot");
|
||||
} catch (Exception e){
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
Scan();
|
||||
} else {
|
||||
throw new InvalidOperationException("BotDll already loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload(){
|
||||
if (appDomain != null){
|
||||
|
||||
AppDomain.Unload(appDomain);
|
||||
|
||||
BotClasses = null;
|
||||
assembly = null;
|
||||
appDomain = null;
|
||||
|
||||
} else {
|
||||
throw new InvalidOperationException("BotDll is not loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
private void Scan(){
|
||||
List<Type> botclasses = new List<Type>();
|
||||
|
||||
Console.WriteLine("Scanning....");
|
||||
|
||||
foreach (Type t in this.assembly.ExportedTypes){
|
||||
if (t.IsSubclassOf(typeof(TradingBot))){
|
||||
Console.WriteLine("Found BotClass: {0}", t.Name);
|
||||
botclasses.Add(t);
|
||||
} else {
|
||||
Console.WriteLine(" No BotClass: {0}", t.Name);
|
||||
}
|
||||
}
|
||||
|
||||
BotClasses = botclasses.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
[JSONClassPolicy(Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class BotInstance
|
||||
{
|
||||
[JSONField]
|
||||
public String ClassName { get; private set; }
|
||||
[JSONField]
|
||||
public String InstanceUID { get; private set; }
|
||||
|
||||
public BotDll Dll { get; set; }
|
||||
|
||||
public BotInstance(){
|
||||
InstanceUID = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
**/
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using sharp.tradebot;
|
||||
|
||||
namespace TradeBot
|
||||
{
|
||||
public class BotSpecification : MarshalByRefObject
|
||||
{
|
||||
public string DllPath { get; private set; }
|
||||
public string ClassName { get; private set; }
|
||||
public object[] Arguments { get; private set; }
|
||||
|
||||
public string BotSpec { get { return string.Format("{0}:{1}",ClassName,DllPath); } }
|
||||
|
||||
public bool IsLoaded
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentInstance != null;
|
||||
}
|
||||
}
|
||||
public TradingBot CurrentInstance
|
||||
{
|
||||
get {
|
||||
return this.currentInstance;
|
||||
}
|
||||
}
|
||||
|
||||
AppDomain Domain;
|
||||
Assembly Assembly;
|
||||
Type ClassType;
|
||||
|
||||
TradingBot currentInstance;
|
||||
|
||||
public BotSpecification(string dllpath,string className,object[] arguments)
|
||||
{
|
||||
DllPath = dllpath;
|
||||
ClassName = className;
|
||||
}
|
||||
|
||||
public void Unload(){
|
||||
currentInstance = null;
|
||||
ClassType = null;
|
||||
Assembly = null;
|
||||
AppDomain.Unload(Domain);
|
||||
Domain = null;
|
||||
}
|
||||
public void Load(){
|
||||
if (Domain != null){
|
||||
Unload();
|
||||
}
|
||||
|
||||
Domain = AppDomain.CreateDomain(DllPath);
|
||||
Assembly = Domain.Load(DllPath);
|
||||
ClassType = Assembly.GetType(ClassName);
|
||||
}
|
||||
|
||||
TradingBot TradingBot {
|
||||
get
|
||||
{
|
||||
if (currentInstance == null){
|
||||
currentInstance = (TradingBot)Activator.CreateInstance(ClassType);
|
||||
}
|
||||
return currentInstance;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
using System;
|
||||
using sharp.trading.bittrex;
|
||||
using sharp.extensions;
|
||||
using sharp.trading;
|
||||
using System.Collections.Generic;
|
||||
using sharp.json;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.CodeDom;
|
||||
using sharp.trading.cache;
|
||||
using sharp.json.network;
|
||||
using sharp.tradebot.rpc;
|
||||
using System.Net.WebSockets;
|
||||
using TradeBot;
|
||||
using System.Net.Sockets;
|
||||
|
||||
|
||||
/**
|
||||
* tradebot.exe [ --test ] --servicedaemon [ --port <port> ]
|
||||
* --newbot [ --dll <dllpath> ] --class <className>
|
||||
* --unload <uuid>
|
||||
* --load <uuid>
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
namespace sharp.tradebot
|
||||
{
|
||||
class TradeBotApplication
|
||||
{
|
||||
public static int jsonPort = 33555;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ArgumentReader ar = new ArgumentReader(args);
|
||||
|
||||
while (ar.MoveNext())
|
||||
{
|
||||
switch (ar.Current)
|
||||
{
|
||||
case "--test":
|
||||
TradingEnvironment.DataDirectory = "sharp.trading.data";
|
||||
jsonPort = 33554;
|
||||
break;
|
||||
case "--servicedaemon":
|
||||
ServiceDaemon.Run(ar.Reminder());
|
||||
return;
|
||||
case "--shutdown":
|
||||
ShutDown();
|
||||
return;
|
||||
case "--register":
|
||||
callDaemon("register", ar.NextFollowing(3));
|
||||
return;
|
||||
case "--unregister":
|
||||
callDaemon("unregister", ar.NextFollowing(1));
|
||||
return;
|
||||
case "--load":
|
||||
callDaemon("load", ar.NextFollowing(1));
|
||||
return;
|
||||
case "--unload":
|
||||
callDaemon("unload", ar.NextFollowing(1));
|
||||
return;
|
||||
case "--reload":
|
||||
callDaemon("reload", ar.NextFollowing(1));
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShutDown(){
|
||||
callDaemon("shutdown",new string[0]);
|
||||
}
|
||||
|
||||
|
||||
private static bool callDaemon(string command,string[] arguments){
|
||||
RPCRequest request = new RPCRequest();
|
||||
request.Command = command;
|
||||
request.Arguments = arguments;
|
||||
|
||||
JSONTcpClient client = new JSONTcpClient(jsonPort);
|
||||
client.Send(JSON.From(request));
|
||||
|
||||
JSON jresponse = client.Receive();
|
||||
RPCResponse response = jresponse.To<RPCResponse>();
|
||||
Console.WriteLine("callDaemon: Daemon Message: {0}",response.Message);
|
||||
|
||||
request = new RPCRequest();
|
||||
request.Arguments = new string[0];
|
||||
request.Command = "disconnect";
|
||||
client.Send(JSON.From(request));
|
||||
|
||||
return response.Success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TradeBotApplication app = new TradeBotApplication();
|
||||
//app.Initialize(args);
|
||||
//app.Prepare();
|
||||
|
||||
//try
|
||||
//{
|
||||
// IEnumerator ae = app.Arguments.ToArray().GetEnumerator();
|
||||
// while (ae.MoveNext())
|
||||
// {
|
||||
// switch (ae.Current.ToString())
|
||||
// {
|
||||
// case "-test":
|
||||
// app.Arguments.Remove(ae.Current.ToString());
|
||||
// jsonPort = 33554;
|
||||
// break;
|
||||
// case "-servicedaemon":
|
||||
// app.Mode = AppMode.SERVICEDAEMON;
|
||||
// app.Arguments.Remove(ae.Current.ToString());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//} catch (Exception e){
|
||||
// Console.WriteLine("Exception while handling command line arguments. {0}",e.ToString());
|
||||
// app.LockFile.Unlock();
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
//app.Start();
|
||||
//app.Shutdown();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//public enum AppMode {
|
||||
// DEFAULT, SERVICEDAEMON
|
||||
//}
|
||||
|
||||
//public LockFile LockFile { get; private set; }
|
||||
|
||||
//public AppMode Mode { get; set; } = AppMode.DEFAULT;
|
||||
|
||||
//List<TradingBot> tradingBots = new List<TradingBot>();
|
||||
|
||||
//List<string> Arguments = new List<string>();
|
||||
|
||||
//public TradeBotApplication()
|
||||
//{
|
||||
// this.LockFile = new LockFile(getLockFileName());
|
||||
//}
|
||||
|
||||
//public string getLockFileName(){
|
||||
// return Path.Combine(TradingBotEnvironment.BaseDataDirectory, "tradebot.lock");
|
||||
//}
|
||||
|
||||
//private void Initialize(string[] arguments)
|
||||
//{
|
||||
// this.Arguments.AddRange(arguments);
|
||||
|
||||
// if (TradingEnvironment.DefaultConnection == null)
|
||||
// {
|
||||
// TradingEnvironment.DefaultConnection = new BittrexConnector();
|
||||
// }
|
||||
// DirectoryExtensions.EnsureDirectoryExists(TradingBotEnvironment.BaseDataDirectory);
|
||||
|
||||
// LockFile.Lock();
|
||||
//}
|
||||
|
||||
//private void Prepare(){
|
||||
// if (!LockFile.IsLocked){
|
||||
// LockFile.Lock();
|
||||
// }
|
||||
|
||||
// bool shouldSave = false;
|
||||
|
||||
// if (!Directory.Exists(Path.Combine(TradingBotEnvironment.BaseDataDirectory,"sys"))){
|
||||
// Directory.CreateDirectory(Path.Combine(TradingBotEnvironment.BaseDataDirectory, "sys"));
|
||||
// }
|
||||
|
||||
// if (File.Exists(Path.Combine(TradingBotEnvironment.BaseDataDirectory,"sys","connector.json"))){
|
||||
// JSON connector = JSON.ReadFrom(Path.Combine(TradingBotEnvironment.BaseDataDirectory,"sys","connector.json"));
|
||||
// if (connector["class"] != null){
|
||||
// Type t = Type.GetType(connector["class"].String);
|
||||
// TradingConnection c = (TradingConnection)Activator.CreateInstance(t, connector["arguments"].To<string[]>());
|
||||
// TradingEnvironment.DefaultConnection = c;
|
||||
// }
|
||||
// } else {
|
||||
// TradingEnvironment.DefaultConnection = new BittrexConnector();
|
||||
// shouldSave = true;
|
||||
// }
|
||||
|
||||
// if (File.Exists(Path.Combine(TradingBotEnvironment.BaseDataDirectory,"sys","bots.json"))){
|
||||
// JSON bots = JSON.ReadFrom(Path.Combine(TradingBotEnvironment.BaseDataDirectory, "sys", "bots.json"));
|
||||
// foreach (JSON bot in bots){
|
||||
// Type t = Type.GetType(bot["class"].String);
|
||||
// TradingBot tbot = (TradingBot)Activator.CreateInstance(t, new object[] { new Guid(bot["uuid"].String) } );
|
||||
|
||||
// AddTradingBot(tbot);
|
||||
// }
|
||||
// } else {
|
||||
// shouldSave = true;
|
||||
// }
|
||||
|
||||
|
||||
// if (shouldSave){
|
||||
// Save();
|
||||
// }
|
||||
//}
|
||||
|
||||
//public void Save()
|
||||
//{
|
||||
// if (!LockFile.IsLocked){
|
||||
// throw new Exception("Cannot save, file lock not locked");
|
||||
// }
|
||||
|
||||
// JSONObject connector = new JSONObject();
|
||||
// if (TradingEnvironment.DefaultConnection == null)
|
||||
// {
|
||||
// connector["class"] = null;
|
||||
// connector["arguments"] = new JSONArray();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// connector["class"] = TradingEnvironment.DefaultConnection.GetType().AssemblyQualifiedName;
|
||||
// connector["arguments"] = JSON.From(TradingEnvironment.DefaultConnection.getConstructorArguments());
|
||||
// }
|
||||
// connector.WriteTo(Path.Combine(TradingBotEnvironment.BaseDataDirectory, "sys", "connector.json"),true);
|
||||
|
||||
|
||||
// JSONArray bots = new JSONArray();
|
||||
|
||||
// foreach (TradingBot bot in TradingBots)
|
||||
// {
|
||||
// JSONObject o = new JSONObject();
|
||||
// o["class"] = bot.GetType().AssemblyQualifiedName;
|
||||
// o["uuid"] = bot.UID.ToString();
|
||||
// bots.Add(o);
|
||||
// }
|
||||
// bots.WriteTo(Path.Combine(TradingBotEnvironment.BaseDataDirectory, "sys", "bots.json"),true);
|
||||
|
||||
//}
|
||||
|
||||
//private void Shutdown()
|
||||
//{
|
||||
// if (LockFile.IsLocked){
|
||||
// LockFile.Unlock();
|
||||
// }
|
||||
//}
|
||||
|
||||
//public void Start(){
|
||||
|
||||
// switch (Mode){
|
||||
// case AppMode.SERVICEDAEMON:
|
||||
// ServiceDaemon();
|
||||
// break;
|
||||
// default:
|
||||
// Run();
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public void ServiceDaemon(){
|
||||
// ServiceManager.Default.GetHashCode();
|
||||
|
||||
// while (true){
|
||||
// Thread.Sleep(1000);
|
||||
|
||||
// if (File.Exists(Path.Combine(TradingEnvironment.DataDirectory, "daemon.shutdown"))){
|
||||
// File.Delete(Path.Combine(TradingEnvironment.DataDirectory, "daemon.shutdown"));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// ServiceManager.Default.Shutdown();
|
||||
|
||||
//}
|
||||
|
||||
//public void Run()
|
||||
//{
|
||||
// foreach (TradingBot bot in tradingBots)
|
||||
// {
|
||||
// RunBot(bot);
|
||||
// }
|
||||
//}
|
||||
|
||||
//public void Run(string[] uids)
|
||||
//{
|
||||
// foreach (TradingBot bot in tradingBots)
|
||||
// {
|
||||
// if (uids.Contains(bot.UID.ToString())){
|
||||
// RunBot(bot);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//private void RunBot(TradingBot bot)
|
||||
//{
|
||||
// Console.WriteLine("Running Bot: {0}", bot.ToString());
|
||||
|
||||
// try {
|
||||
// bot.Prepare();
|
||||
// bot.Trade();
|
||||
// bot.Finish();
|
||||
// } catch (Exception e){
|
||||
// Console.WriteLine("Bot threw exception: {0}",e.ToString());
|
||||
// bot.Unlock();
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
//public TradingBot[] TradingBots {
|
||||
// get { return tradingBots.ToArray(); }
|
||||
//}
|
||||
|
||||
//public void AddTradingBot(TradingBot bot){
|
||||
// this.tradingBots.Add(bot);
|
||||
//}
|
||||
|
||||
//public void RemoveTradingBot(TradingBot bot){
|
||||
// this.tradingBots.Remove(bot);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Double ConvertValue(string valueSymbol,double volume,string targetSymbol){
|
||||
|
||||
if (valueSymbol.Equals(targetSymbol)){
|
||||
return volume;
|
||||
}
|
||||
|
||||
Market primMarket;
|
||||
Market secMarket;
|
||||
|
||||
try
|
||||
{
|
||||
primMarket = TradingEnvironment.DefaultConnection.openMarket(valueSymbol, targetSymbol);
|
||||
return primMarket.getOrderBook().getVolumePrice(volume).Item2;
|
||||
} catch (Exception e){
|
||||
Console.WriteLine("Direct conversion from {0} to {1} is not available",valueSymbol,targetSymbol);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
primMarket = TradingEnvironment.DefaultConnection.openMarket(valueSymbol, "BTC");
|
||||
secMarket = TradingEnvironment.DefaultConnection.openMarket("BTC", targetSymbol);
|
||||
|
||||
return secMarket.getOrderBook().getVolumePrice(primMarket.getOrderBook().getVolumePrice(volume).Item2).Item2;
|
||||
} catch (Exception e){
|
||||
Console.WriteLine("Conversion of {0} to {1} via BTC not available.",valueSymbol,targetSymbol);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void DumpBalances(string targetSymbol)
|
||||
{
|
||||
TradingConnection c = TradingEnvironment.DefaultConnection;
|
||||
double targetBalance = 0;
|
||||
|
||||
foreach (trading.Balance balance in c.getBalances())
|
||||
{
|
||||
if (balance.CurrentBalance > 0)
|
||||
{
|
||||
double targetValue = ConvertValue(balance.Currency, balance.CurrentBalance, targetSymbol);
|
||||
|
||||
Console.WriteLine("Balance: {0,12:#####0.000000} {1,4} => {2,12:#####0.000000} {3}", balance.CurrentBalance, balance.Currency, targetValue, targetSymbol);
|
||||
targetBalance += targetValue;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Current {1} Value: {0,12:#####0.00} {1}", targetBalance, targetSymbol);
|
||||
Console.WriteLine();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Information about this assembly is defined by the following attributes.
|
||||
// Change them to the values specific to your project.
|
||||
|
||||
[assembly: AssemblyTitle("TradeBot")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
|
||||
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
|
||||
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
// The following attributes are used to specify the signing key for the assembly,
|
||||
// if desired. See the Mono documentation for more information about signing.
|
||||
|
||||
//[assembly: AssemblyDelaySign(false)]
|
||||
//[assembly: AssemblyKeyFile("")]
|
|
@ -0,0 +1,212 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using sharp.json.network;
|
||||
using sharp.trading;
|
||||
using sharp.tradebot;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using sharp.json;
|
||||
using sharp.tradebot.rpc;
|
||||
using sharp.extensions;
|
||||
using sharp.trading.bittrex;
|
||||
namespace TradeBot
|
||||
{
|
||||
public static class ServiceDaemon
|
||||
{
|
||||
public static bool daemonShouldExit = false;
|
||||
public static bool ShouldExit()
|
||||
{
|
||||
return daemonShouldExit;
|
||||
}
|
||||
|
||||
public static BotManager botManager;
|
||||
|
||||
public static void Run(String[] args){
|
||||
ArgumentReader ar = new ArgumentReader(args);
|
||||
|
||||
while (ar.MoveNext()){
|
||||
switch (ar.Current)
|
||||
{
|
||||
case "--test":
|
||||
TradingEnvironment.DataDirectory = "sharp.trading.data";
|
||||
TradeBotApplication.jsonPort = 33554;
|
||||
break;
|
||||
case "--port":
|
||||
ar.MoveNext();
|
||||
TradeBotApplication.jsonPort = int.Parse(ar.Current);
|
||||
return;
|
||||
default:
|
||||
throw new ArgumentException(String.Format("Unexpected Argument: {0}", ar.Current));
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(Path.Combine(TradingEnvironment.DataDirectory,"connector.json"))){
|
||||
JSON connector = JSON.ReadFrom(Path.Combine(TradingEnvironment.DataDirectory, "connector.json"));
|
||||
if (connector["class"] != null){
|
||||
Type t = Type.GetType(connector["class"].String);
|
||||
TradingConnection c = (TradingConnection)Activator.CreateInstance(t, connector["arguments"].To<string[]>());
|
||||
TradingEnvironment.DefaultConnection = c;
|
||||
}
|
||||
} else {
|
||||
TradingEnvironment.DefaultConnection = new BittrexConnector();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JSONTcpServer jsonServer = new JSONTcpServer(TradeBotApplication.jsonPort);
|
||||
jsonServer.ClientConnected = JSONClientConnected;
|
||||
jsonServer.Start();
|
||||
|
||||
botManager = new BotManager(TradingEnvironment.DataDirectory);
|
||||
botManager.LoadAllBots();
|
||||
|
||||
foreach (TradingBotInstance bot in botManager.RegisteredBots){
|
||||
bot.Prepare();
|
||||
}
|
||||
|
||||
while (!ShouldExit())
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
Console.WriteLine("Servicedaemon shutting down");
|
||||
|
||||
botManager.BotEnvironment.Stop();
|
||||
|
||||
foreach (TradingBotInstance bot in botManager.RegisteredBots){
|
||||
bot.Unprepare();
|
||||
}
|
||||
foreach (TradingBotInstance bot in botManager.RegisteredBots){
|
||||
bot.Unload();
|
||||
}
|
||||
|
||||
botManager.Save();
|
||||
jsonServer.Stop();
|
||||
}
|
||||
|
||||
private static void JSONClientConnected(JSONTcpClient client)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
JSON jrequest = client.Receive();
|
||||
RPCRequest request = jrequest.To<RPCRequest>();
|
||||
RPCResponse response = new RPCResponse();
|
||||
|
||||
if (request.Command.Equals("disconnect"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (request.Command)
|
||||
{
|
||||
case "newbot":
|
||||
Console.WriteLine("request to create new bot: {0} from {1}", request.Arguments[0], request.Arguments[1]);
|
||||
response.Message = "Bot created";
|
||||
response.Success = true;
|
||||
break;
|
||||
case "shutdown":
|
||||
response.Message = "Daemon shutting down";
|
||||
response.Success = true;
|
||||
daemonShouldExit = true;
|
||||
break;
|
||||
|
||||
case "register":
|
||||
try
|
||||
{
|
||||
botManager.RegisterBot(request.Arguments[0],request.Arguments[1]);
|
||||
|
||||
Console.WriteLine(botManager.ToString());
|
||||
|
||||
response.Message = "registered.";
|
||||
response.Success = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.Message = String.Format("Exception: {0}", e);
|
||||
response.Success = false;
|
||||
}
|
||||
break;
|
||||
case "unregister":
|
||||
try
|
||||
{
|
||||
botManager.UnregisterBot(Guid.Parse(request.Arguments[0]));
|
||||
|
||||
response.Message = "unregistered.";
|
||||
response.Success = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.Message = String.Format("Exception: {0}", e);
|
||||
response.Success = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case "load":
|
||||
try
|
||||
{
|
||||
botManager.LoadBotAndPrepare(Guid.Parse(request.Arguments[0]));
|
||||
|
||||
response.Message = "loaded.";
|
||||
response.Success = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.Message = String.Format("Exception: {0}", e);
|
||||
response.Success = false;
|
||||
}
|
||||
break;
|
||||
case "unload":
|
||||
try
|
||||
{
|
||||
botManager.UnloadBot(Guid.Parse(request.Arguments[0]));
|
||||
|
||||
response.Message = "unloaded.";
|
||||
response.Success = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.Message = String.Format("Exception: {0}", e);
|
||||
response.Success = false;
|
||||
}
|
||||
break;
|
||||
case "reload":
|
||||
try
|
||||
{
|
||||
botManager.UnloadBot(Guid.Parse(request.Arguments[0]));
|
||||
botManager.LoadBotAndPrepare(Guid.Parse(request.Arguments[0]));
|
||||
|
||||
response.Message = "reloaded.";
|
||||
response.Success = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.Message = String.Format("Exception: {0}", e);
|
||||
response.Success = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
response.Success = false;
|
||||
response.Message = string.Format("Unknown command: {0}", request.Command);
|
||||
break;
|
||||
}
|
||||
client.Send(JSON.From(response));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("JSONClientConnection: Exception: " + e.ToString());
|
||||
}
|
||||
client.Close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{AA4843D6-D960-4273-8CC4-3C737471D9CF}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>TradeBot</RootNamespace>
|
||||
<AssemblyName>TradeBot</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Runtime.Remoting" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="BotSpecification.cs" />
|
||||
<Compile Include="rpc\RPCRequest.cs" />
|
||||
<Compile Include="rpc\RPCResponse.cs" />
|
||||
<Compile Include="BotManager.cs" />
|
||||
<Compile Include="ServiceDaemon.cs" />
|
||||
<Compile Include="TradeBotHost.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\sharp-trading\sharp.trading.csproj">
|
||||
<Project>{CAAC53CC-671C-4B1E-8403-1E53D1D40D66}</Project>
|
||||
<Name>sharp.trading</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
|
||||
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
|
||||
<Name>sharp.extensions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\sharp-json\sharp.json.csproj">
|
||||
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
||||
<Name>sharp.json</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\sharp.tradebot\sharp.tradebot.csproj">
|
||||
<Project>{798D4516-84F8-436D-BD7F-17AD288C6776}</Project>
|
||||
<Name>sharp.tradebot</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\BigBot\BigBot.csproj">
|
||||
<Project>{690293DB-4E8D-44E6-B0AD-3A4FF66E6042}</Project>
|
||||
<Name>BigBot</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="rpc\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Runtime.Remoting.Channels.Ipc;
|
||||
using System.Runtime.Remoting.Channels;
|
||||
|
||||
namespace TradeBot
|
||||
{
|
||||
public class TradeBotHost : MarshalByRefObject
|
||||
{
|
||||
IpcChannel ipcChannel;
|
||||
|
||||
public TradeBotHost(string hostID)
|
||||
{
|
||||
ipcChannel = new IpcChannel(String.Format("bot.host.{0}",hostID));
|
||||
ChannelServices.RegisterChannel(ipcChannel,true);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
namespace sharp.tradebot.rpc
|
||||
{
|
||||
public class RPCRequest
|
||||
{
|
||||
public string Command;
|
||||
public string[] Arguments;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
namespace sharp.tradebot.rpc
|
||||
{
|
||||
public class RPCResponse
|
||||
{
|
||||
public bool Success;
|
||||
public string Message;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue