BigBot/MarketValueBot.cs

179 lines
5.9 KiB
C#

using System;
using sharp.json;
using System.IO;
using sharp.trading;
using sharp.trading.cache;
using sharp.extensions;
using sharp.tradebot;
namespace BigBot
{
public class MarketValueBot : TradingBot<BasicBotSetup>
{
public FileBackedJSONValue<SetupClass> Setup;
public FileBackedJSONValue<string> CurrentOrderID;
public MarketValueBot()
{
initialize();
}
private void initialize()
{
Setup = new FileBackedJSONValue<SetupClass>(Path.Combine(DataDirectory, "setup.json"));
CurrentOrderID = new FileBackedJSONValue<string>(Path.Combine(DataDirectory, "currentorder.json"));
}
public override void Prepare()
{
base.Prepare();
if (Setup.CurrentValue == null){
Setup.CurrentValue = new SetupClass();
}
}
public void Trade()
{
sharp.tradebot.TradeBotBalance balanceBase = getBalance(Setup.CurrentValue.BaseSymbol);
sharp.tradebot.TradeBotBalance balanceMarket = getBalance(Setup.CurrentValue.MarketSymbol);
if (CurrentOrderID.CurrentValue != null){
Order o = getOrder(CurrentOrderID.CurrentValue);
if (o.IsOpen)
{
TradingEnvironment.DefaultConnection.refreshOrder(o);
}
if (!o.IsOpen){
if (o.OrderType == OrderType.BUY){
balanceBase.CurrentBalance -= o.PayedFees + o.PayedPrice;
balanceMarket.CurrentBalance += o.FilledVolume;
} else {
balanceBase.CurrentBalance += o.PayedPrice - o.PayedFees;
balanceMarket.CurrentBalance -= o.FilledVolume;
}
Log("Order has been closed: {0}", o.ToString());
CurrentOrderID.CurrentValue = null;
Save();
}
}
if (Setup.CurrentValue.Enabled){
Log("Bot enabled");
/* Manage Balances */
if (Setup.CurrentValue.BaseBalanceChange != 0)
{
balanceBase.CurrentBalance += Setup.CurrentValue.BaseBalanceChange;
Setup.CurrentValue.BaseBalanceChange = 0;
Setup.Save();
}
if (Setup.CurrentValue.MarketBalanceChange != 0)
{
balanceMarket.CurrentBalance += Setup.CurrentValue.MarketBalanceChange;
Setup.CurrentValue.MarketBalanceChange = 0;
Setup.Save();
}
Market market = TradingEnvironment.DefaultConnection.openMarket(Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol);
OrderBook orderBook = market.getOrderBook();
System.Tuple<double,double> currentValues = orderBook.getVolumePrice(balanceMarket.CurrentBalance);
Log("Current Market Values: REBUY: {0,11:####0.00000000} {2} SELL: {1,11:####0.00000000} {2}", currentValues.Item1, currentValues.Item2, Setup.CurrentValue.BaseSymbol);
Log("Current Market Spread: {0,6:##0.00}%", ((currentValues.Item1 / currentValues.Item2)-1)*100);
double currentAbsDiff = Setup.CurrentValue.TargetValue - currentValues.Item2;
double currentDiff = currentAbsDiff / Setup.CurrentValue.TargetValue;
Log("Current Diff: {0,8:##0.0000} {1} [ {2,6:##0.00}% ] Limit: {3,6:##0.00}% / {4,6:##0.00}%", currentAbsDiff, Setup.CurrentValue.BaseSymbol, currentDiff * 100, Setup.CurrentValue.DiffMargin * 100, Setup.CurrentValue.DiffMarginBuy * 100);
if ((currentDiff > Setup.CurrentValue.DiffMarginBuy) || (-currentDiff > Setup.CurrentValue.DiffMargin))
{
if (CurrentOrderID.CurrentValue != null)
{
Log("Canceling old Order before creating new one.");
TradingEnvironment.DefaultConnection.cancelOrder(CurrentOrderID.CurrentValue);
} else
{
double diffMarket = currentAbsDiff / orderBook.CurrentBid;
if (diffMarket > 0){
// Buy
double window = orderBook.getVolumePrice(diffMarket).Item1 - orderBook.getVolumePrice(diffMarket).Item2;
double price = orderBook.getVolumePrice(diffMarket).Item1 + (Setup.CurrentValue.WindowLevelToBuy * window);
if (price >= balanceBase.CurrentBalance){
diffMarket *= balanceBase.CurrentBalance / price;
price = orderBook.getVolumePrice(diffMarket).Item1;
}
Log("Will buy {0,11:####0.00000000} {1} @ {2,11:####0.00000000} {3} = {4,11:####0.00000000} {3}", diffMarket, Setup.CurrentValue.MarketSymbol, orderBook.CurrentAsk, Setup.CurrentValue.BaseSymbol, price);
Order order = createLimitOrder(OrderType.BUY, Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol, diffMarket, orderBook.CurrentAsk);
CurrentOrderID.CurrentValue = order.OrderID;
} else {
// SELL
diffMarket = -diffMarket;
double window = orderBook.getVolumePrice(diffMarket).Item1 - orderBook.getVolumePrice(diffMarket).Item2;
double price = orderBook.getVolumePrice(diffMarket).Item1 + (Setup.CurrentValue.WindowLevelToBuy * window);
Log("Will sell {0,11:####0.00000000} {1} @ {2,11:####0.00000000} {3} = {4,11:####0.00000000} {3}", diffMarket, Setup.CurrentValue.MarketSymbol, orderBook.CurrentAsk, Setup.CurrentValue.BaseSymbol, price);
Order order = createLimitOrder(OrderType.SELL, Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol, diffMarket, orderBook.CurrentBid);
CurrentOrderID.CurrentValue = order.OrderID;
}
}
}
DumpBalances();
Log("--------------------------------------------------");
Log("Current Total: {0,11:####0.00000000} {1} ", balanceBase.CurrentBalance + currentValues.Item2, balanceBase.Currency);
Log("==================================================");
}
}
public override void Save()
{
Setup.Save();
base.Save();
}
public override int SchedulingIntervall()
{
return 15;
}
public class WeightedIndicator{
public double Volume;
public double Weight;
}
public class SetupClass {
public bool Enabled;
public string MarketSymbol = "";
public string BaseSymbol = "";
public double BaseBalanceChange;
public double MarketBalanceChange;
public double TargetValue = 0;
public double DiffMargin = 0.02;
public double DiffMarginBuy = 0.03;
public double WindowLevelToBuy = 0.1;
public double WindowLevelToSell = 0.8;
}
}
}