207 lines
5.6 KiB
C#
207 lines
5.6 KiB
C#
using System;
|
|
using sharp.json;
|
|
using System.IO;
|
|
using sharp.trading;
|
|
using sharp.trading.cache;
|
|
using sharp.extensions;
|
|
namespace sharp.tradebot
|
|
{
|
|
public class HistoryBot : TradingBot<BasicBotSetup>
|
|
{
|
|
public FileBackedJSONValue<SetupClass> Setup;
|
|
public FileBackedJSONValue<string> CurrentOrderID;
|
|
|
|
public HistoryBot()
|
|
{
|
|
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()
|
|
{
|
|
TradeBotBalance balanceBase = getBalance(Setup.CurrentValue.BaseSymbol);
|
|
TradeBotBalance balanceMarket = getBalance(Setup.CurrentValue.MarketSymbol);
|
|
|
|
if (CurrentOrderID.CurrentValue != null){
|
|
Order o = getOrder(CurrentOrderID.CurrentValue);
|
|
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;
|
|
}
|
|
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);
|
|
HistoryCache cache = HistoryCache.getCache(market);
|
|
|
|
double indication = 0;
|
|
|
|
WeightedIndicator[] indicators = Setup.CurrentValue.Indicators;
|
|
foreach (WeightedIndicator wi in indicators){
|
|
double ind = cache.calulateWeightedAveragesPerVolume(wi.Volume).AveragePrice;
|
|
double weight = wi.Weight;
|
|
Log("Indicator for Volume {0,10} = {1,11:####0.00000000} with a weight of {2,7:#0.####}",wi.Volume,ind,weight);
|
|
indication += ind * wi.Weight;
|
|
}
|
|
|
|
Log("Indicator Sum: {0,11:####0.00000000}", indication);
|
|
|
|
OrderBook orderBook = market.getOrderBook();
|
|
|
|
System.Tuple<double,double> bidask = orderBook.getVolumePrice(5.0);
|
|
|
|
Log("Current Small-Volumes: {0} / {1}",bidask.Item1,bidask.Item2);
|
|
|
|
double smallbid = bidask.Item2 / 5;
|
|
double smallask = bidask.Item1 / 5;
|
|
|
|
Log("Current Small Ask: {0} Bid: {1}", smallask, smallbid);
|
|
|
|
double smallsum = (smallbid + smallask) / 2;
|
|
Log("Current Small-Indicator: {0}", smallsum);
|
|
|
|
double final = indication / (smallsum + indication);
|
|
|
|
Log("Current Final Indication: {0}", final);
|
|
|
|
double marketBalanceAsBase = orderBook.getVolumePrice(balanceMarket.CurrentBalance).Item2;
|
|
|
|
double balancesum = (balanceBase.CurrentBalance + marketBalanceAsBase);
|
|
double currentRatio = marketBalanceAsBase / balancesum;
|
|
|
|
Log("Current Balance Values: {0,11:####0.00000000} {1} / {2,11:####0.00000000} {1} = {3:#0.0000}", balanceBase.CurrentBalance, balanceBase.Currency, marketBalanceAsBase, currentRatio);
|
|
Log("Current Balance Sum: {0,11:####0.00000000} {1}", balancesum, balanceBase.Currency);
|
|
|
|
double targetMarket = balancesum / (1 + final);
|
|
double targetBase = balancesum - targetMarket;
|
|
|
|
Log("Target Balance Values: {0,11:####0.00000000} {2} / {1,11:####0.00000000} {2}", targetBase, targetMarket, balanceBase.Currency);
|
|
|
|
double diff = currentRatio - final;
|
|
diff = Math.Abs(diff);
|
|
|
|
Log("Current Indicator Diff: {0}", diff);
|
|
|
|
if (diff > Setup.CurrentValue.DiffMargin){
|
|
if (CurrentOrderID.CurrentValue != null)
|
|
{
|
|
Log("Canceling old Order before creating new one.");
|
|
TradingEnvironment.DefaultConnection.cancelOrder(CurrentOrderID.CurrentValue);
|
|
}
|
|
else
|
|
{
|
|
double deltaMarket = targetMarket - marketBalanceAsBase;
|
|
OrderType otype;
|
|
double orderVolume;
|
|
double limit;
|
|
|
|
if (deltaMarket > 0)
|
|
{
|
|
// BUY
|
|
otype = OrderType.BUY;
|
|
orderVolume = deltaMarket / orderBook.CurrentAsk;
|
|
limit = orderBook.CurrentAsk;
|
|
}
|
|
else
|
|
{
|
|
// SELL
|
|
otype = OrderType.SELL;
|
|
orderVolume = -deltaMarket / orderBook.CurrentBid;
|
|
limit = orderBook.CurrentBid;
|
|
}
|
|
|
|
try {
|
|
//Order o = createLimitOrder(otype, Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol, orderVolume, limit);
|
|
//CurrentOrderID.CurrentValue = o.OrderID;
|
|
Log("Created balancing Order {0}", CurrentOrderID.CurrentValue);
|
|
} catch (Exception e){
|
|
Log("Exception creating Order: {0}", e.ToString());
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DumpBalances();
|
|
}
|
|
}
|
|
|
|
public override void Save()
|
|
{
|
|
Setup.Save();
|
|
base.Save();
|
|
}
|
|
|
|
public override int SchedulingIntervall()
|
|
{
|
|
return 10;
|
|
}
|
|
|
|
|
|
|
|
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 DiffMargin = 0.1;
|
|
|
|
public WeightedIndicator[] Indicators = new WeightedIndicator[]{
|
|
new WeightedIndicator(),
|
|
new WeightedIndicator()
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
}
|