WIP
commit
7c28bbbc60
|
@ -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,255 @@
|
|||
using System;
|
||||
using sharp.tradebot;
|
||||
using sharp.json;
|
||||
using sharp.trading;
|
||||
using System.IO;
|
||||
using sharp.extensions;
|
||||
using sharp.json.attributes;
|
||||
using System.Globalization;
|
||||
namespace BigBot
|
||||
{
|
||||
[JSONClassPolicy( Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class BigBot : TradingBot<BigBotSetup>
|
||||
{
|
||||
FileBackedJSONValue<BigBotSetup> Setup;
|
||||
|
||||
public BigBot()
|
||||
{
|
||||
}
|
||||
|
||||
sharp.tradebot.TradeBotBalance balanceBase;
|
||||
sharp.tradebot.TradeBotBalance balanceMarket;
|
||||
|
||||
[JSONField]
|
||||
public double CurrentMarketCosts;
|
||||
|
||||
[JSONField]
|
||||
double lastCenterRate;
|
||||
[JSONField]
|
||||
double lastDT;
|
||||
|
||||
[JSONField]
|
||||
public SmoothValue[] Gliders;
|
||||
[JSONField]
|
||||
public SmoothValue[] dT;
|
||||
[JSONField]
|
||||
public SmoothValue[] dTdT;
|
||||
|
||||
[JSONField]
|
||||
public string currentOrderID;
|
||||
|
||||
|
||||
|
||||
|
||||
public override void Prepare()
|
||||
{
|
||||
base.Prepare();
|
||||
|
||||
Setup = new FileBackedJSONValue<BigBotSetup>(Path.Combine(BaseDataPath, "setup.json"));
|
||||
if (Setup.CurrentValue == null){
|
||||
Setup.CurrentValue = new BigBotSetup();
|
||||
Setup.Save();
|
||||
}
|
||||
|
||||
if (this.dT.IsNull())
|
||||
{
|
||||
initialize_dT();
|
||||
}
|
||||
if (this.dTdT.IsNull())
|
||||
{
|
||||
initialize_dTdT();
|
||||
}
|
||||
|
||||
|
||||
TradingBotEnvironment.RegisterPeriodic(Worker,15);
|
||||
Log("Prepared");
|
||||
}
|
||||
|
||||
public override void Save(){
|
||||
Setup.Save();
|
||||
base.Save();
|
||||
}
|
||||
|
||||
public override void Unprepare()
|
||||
{
|
||||
TradingBotEnvironment.UnregisterPeriodic(Worker);
|
||||
|
||||
Save();
|
||||
|
||||
Log("Unprepared");
|
||||
|
||||
base.Unprepare();
|
||||
}
|
||||
|
||||
private bool Check(){
|
||||
balanceBase = getBalance(Setup.CurrentValue.BaseSymbol);
|
||||
balanceMarket = getBalance(Setup.CurrentValue.MarketSymbol);
|
||||
|
||||
if (balanceBase.IsNull() || balanceMarket.IsNull()){
|
||||
Log("check failed: balances not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CheckCurrentOrder(){
|
||||
if (!currentOrderID.IsNull()){
|
||||
Order order = getOrder(currentOrderID);
|
||||
if (!order.IsNull() && !order.IsOpen){
|
||||
balanceBase.CurrentBalance -= order.PayedFees;
|
||||
CurrentMarketCosts += order.PayedFees;
|
||||
|
||||
if (order.OrderType == OrderType.BUY){
|
||||
CurrentMarketCosts += order.PayedPrice;
|
||||
balanceBase.CurrentBalance -= order.PayedPrice;
|
||||
balanceMarket.CurrentBalance += order.FilledVolume;
|
||||
} else {
|
||||
CurrentMarketCosts -= order.PayedPrice;
|
||||
balanceBase.CurrentBalance += order.PayedPrice;
|
||||
balanceMarket.CurrentBalance -= order.FilledVolume;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Worker()
|
||||
{
|
||||
if (Setup.CurrentValue.Enabled && Check())
|
||||
{
|
||||
Log("BigBot: Worker() called and enabled!");
|
||||
Log("Next run...");
|
||||
|
||||
Market market = TradingBotEnvironment.TradingConnection.openMarket(Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol);
|
||||
OrderBook orderBook = market.getOrderBook();
|
||||
orderBook.Refresh();
|
||||
System.Tuple<double, double> currentCheck = orderBook.getVolumePrice(Setup.CurrentValue.MarketCheckVolume);
|
||||
double centerPrice = (currentCheck.Item1 + currentCheck.Item2) / 2;
|
||||
double centerRate = centerPrice / Setup.CurrentValue.MarketCheckVolume;
|
||||
|
||||
if (this.Gliders.IsNull())
|
||||
{
|
||||
initializeGliders(centerRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (SmoothValue glide in this.Gliders)
|
||||
{
|
||||
glide.Add(centerRate);
|
||||
}
|
||||
}
|
||||
|
||||
double _dT = (((centerRate - lastCenterRate) / centerRate)) * 100.0;
|
||||
double _dTdT = (_dT - lastDT);
|
||||
|
||||
foreach (SmoothValue dt in this.dT)
|
||||
{
|
||||
dt.Add(_dT);
|
||||
}
|
||||
foreach (SmoothValue dtdt in this.dTdT)
|
||||
{
|
||||
dtdt.Add(_dTdT);
|
||||
}
|
||||
|
||||
double[] Indicators = new double[Gliders.Length - 1];
|
||||
for (int n = 0; n < Indicators.Length; n++)
|
||||
{
|
||||
Indicators[n] = 1.0 - (this.Gliders[0].CurrentValue / this.Gliders[n + 1].CurrentValue);
|
||||
}
|
||||
|
||||
lastCenterRate = centerRate;
|
||||
lastDT = _dT;
|
||||
|
||||
Log("Current volumized Market Values: Ask: {0,11:####0.00000000} {2} Bid: {1,11:####0.00000000} {2}", currentCheck.Item1, currentCheck.Item2, Setup.CurrentValue.BaseSymbol);
|
||||
Log("Current volumized Market Spread: {0,6:##0.00}%", ((currentCheck.Item1 / currentCheck.Item2)-1) * 100);
|
||||
Log("Current volumized Center Rate: {0,11:####0.00000000} {1}", centerRate, Setup.CurrentValue.BaseSymbol);
|
||||
Log("Current indicators [ 0..3 ]: {0,6:##0.00}% / {1,6:##0.00}% / {2,6:##0.00}% / {3,6:##0.00}%", Indicators[0] * 100,Indicators[1] * 100,Indicators[2] * 100,Indicators[3] * 100);
|
||||
|
||||
WriteHistory();
|
||||
|
||||
Save();
|
||||
|
||||
market.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeGliders(double center)
|
||||
{
|
||||
double k = 1;
|
||||
this.Gliders = new SmoothValue[10];
|
||||
for (int n = 0; n < this.Gliders.Length; n++)
|
||||
{
|
||||
this.Gliders[n] = new SmoothValue(k);
|
||||
this.Gliders[n].Set(center);
|
||||
k /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize_dT()
|
||||
{
|
||||
double k = 1;
|
||||
this.dT = new SmoothValue[8];
|
||||
for (int n = 0; n < this.dT.Length; n++)
|
||||
{
|
||||
this.dT[n] = new SmoothValue(k);
|
||||
k /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize_dTdT()
|
||||
{
|
||||
double k = 1;
|
||||
this.dTdT = new SmoothValue[8];
|
||||
for (int n = 0; n < this.dTdT.Length; n++)
|
||||
{
|
||||
this.dTdT[n] = new SmoothValue(k);
|
||||
k /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteHistory()
|
||||
{
|
||||
FileStream s = new FileStream(Path.Combine(BaseDataPath, "gliders.csv"), FileMode.Append);
|
||||
StreamWriter w = new StreamWriter(s);
|
||||
|
||||
foreach (SmoothValue glide in this.Gliders)
|
||||
{
|
||||
w.Write(glide.CurrentValue.ToString(CultureInfo.InvariantCulture));
|
||||
w.Write('\t');
|
||||
}
|
||||
w.WriteLine();
|
||||
w.Close();
|
||||
|
||||
|
||||
s = new FileStream(Path.Combine(BaseDataPath, "dt.csv"), FileMode.Append);
|
||||
w = new StreamWriter(s);
|
||||
|
||||
foreach (SmoothValue dt in this.dT)
|
||||
{
|
||||
w.Write(dt.CurrentValue.ToString(CultureInfo.InvariantCulture));
|
||||
w.Write('\t');
|
||||
}
|
||||
w.WriteLine();
|
||||
w.Close();
|
||||
|
||||
|
||||
s = new FileStream(Path.Combine(BaseDataPath, "dtdt.csv"), FileMode.Append);
|
||||
w = new StreamWriter(s);
|
||||
|
||||
foreach (SmoothValue dtdt in this.dTdT)
|
||||
{
|
||||
w.Write(dtdt.CurrentValue.ToString(CultureInfo.InvariantCulture));
|
||||
w.Write('\t');
|
||||
}
|
||||
w.WriteLine();
|
||||
w.Close();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
public class BigBotSetup : BasicBotSetup
|
||||
{
|
||||
public double MarketCheckVolume = 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?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)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{690293DB-4E8D-44E6-B0AD-3A4FF66E6042}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>BigBot</RootNamespace>
|
||||
<AssemblyName>BigBot</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="BigBot.cs" />
|
||||
<Compile Include="SmoothValue.cs" />
|
||||
<Compile Include="MarketValueBot.cs" />
|
||||
<Compile Include="DifferentingBot.cs" />
|
||||
<Compile Include="HistoryBot.cs" />
|
||||
<Compile Include="SimpleBot.cs" />
|
||||
<Compile Include="SpreadBot.cs" />
|
||||
<Compile Include="StatisticalBot.cs" />
|
||||
<Compile Include="TargetValueBot.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\sharp.tradebot\sharp.tradebot.csproj">
|
||||
<Project>{798D4516-84F8-436D-BD7F-17AD288C6776}</Project>
|
||||
<Name>sharp.tradebot</Name>
|
||||
</ProjectReference>
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,444 @@
|
|||
using System;
|
||||
using sharp.tradebot;
|
||||
using sharp.json.attributes;
|
||||
using sharp.extensions;
|
||||
using sharp.trading;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
namespace BigBot
|
||||
{
|
||||
|
||||
public class DifferentingBot : TradingBot<DifferentialSetup>
|
||||
{
|
||||
[JSONField]
|
||||
GlidingHistory currentValue = new GlidingHistory(1);
|
||||
[JSONField]
|
||||
GlidingHistory[] GlidingHistories;
|
||||
|
||||
[JSONField]
|
||||
double targetVolume = 1;
|
||||
|
||||
[JSONField]
|
||||
string currentOrderID;
|
||||
|
||||
[JSONField]
|
||||
VolumeRate currentVolumeRate;
|
||||
|
||||
[JSONField]
|
||||
double lastOrderLimit;
|
||||
|
||||
[JSONField]
|
||||
SimpleHighLowDetector detector = new SimpleHighLowDetector();
|
||||
|
||||
TextWriter historyWriter;
|
||||
|
||||
public override void Prepare()
|
||||
{
|
||||
base.Prepare();
|
||||
|
||||
double k = 0.25;
|
||||
|
||||
if (this.GlidingHistories.IsNull())
|
||||
{
|
||||
k = 0.25;
|
||||
|
||||
this.GlidingHistories = new GlidingHistory[4];
|
||||
for (int n = 0; n < this.GlidingHistories.Length;n++){
|
||||
this.GlidingHistories[n] = new GlidingHistory(k);
|
||||
k /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastOrderLimit == 0){
|
||||
lastOrderLimit = currentVolumeRate.UnityPrice;
|
||||
}
|
||||
|
||||
historyWriter = new StreamWriter(new FileStream(Path.Combine(BaseDataPath, "history.csv"), FileMode.Append));
|
||||
|
||||
TradingBotEnvironment.RegisterPeriodic(Trade,60);
|
||||
|
||||
}
|
||||
|
||||
public override void Unprepare()
|
||||
{
|
||||
TradingBotEnvironment.UnregisterPeriodic(Trade);
|
||||
|
||||
historyWriter.Close();
|
||||
|
||||
base.Unprepare();
|
||||
}
|
||||
|
||||
private void Trade(){
|
||||
if (BasicSetup.Enabled){
|
||||
TradeBotBalance bMarket = getBalance(BasicSetup.MarketSymbol);
|
||||
|
||||
OrderBook orderBook = BotMarket.getOrderBook();
|
||||
System.Tuple<double,double> marketCheck = orderBook.getVolumePrice(BasicSetup.MarketCheckVolume);
|
||||
|
||||
double currentAskRate = marketCheck.Item1 / BasicSetup.MarketCheckVolume;
|
||||
double currentBidRate = marketCheck.Item2 / BasicSetup.MarketCheckVolume;
|
||||
double currentCenterRate = (currentAskRate + currentBidRate) / 2;
|
||||
|
||||
currentValue.Add(currentCenterRate);
|
||||
|
||||
foreach (GlidingHistory gh in this.GlidingHistories)
|
||||
{
|
||||
gh.Add(currentCenterRate);
|
||||
}
|
||||
|
||||
//detector.Add(this.GlidingHistories[0].centerRate);
|
||||
detector.Add(currentCenterRate);
|
||||
|
||||
writeHistory(currentCenterRate);
|
||||
|
||||
/* Indicators... */
|
||||
|
||||
double qEMA = (this.GlidingHistories[2].centerRate - currentCenterRate) / this.GlidingHistories[2].centerRate;
|
||||
double currentDTDT0 = this.GlidingHistories[0].dTdT;
|
||||
|
||||
|
||||
/* if (
|
||||
((qEMA > 0) && (targetVolume < 1.0 )) ||
|
||||
((qEMA < 0) && (targetVolume > 1.0 ))
|
||||
){
|
||||
targetVolume = 1;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (!BasicSetup.ResetTargetVolume)
|
||||
{
|
||||
targetVolume *= (1.0 + qEMA);
|
||||
} else {
|
||||
targetVolume = 1.0;
|
||||
BasicSetup.ResetTargetVolume = false;
|
||||
}
|
||||
|
||||
if (currentCenterRate > this.currentVolumeRate.UnityPrice){
|
||||
targetVolume = 0.85;
|
||||
} else {
|
||||
targetVolume = 1.15;
|
||||
}
|
||||
|
||||
double currentOrderVolume = (bMarket.CurrentBalance * targetVolume) - bMarket.CurrentBalance;
|
||||
|
||||
if ((Math.Abs(currentOrderVolume) < BotMarket.MinimumTradeVolume) && (BasicSetup.IncreaseOrderVolumeToMinimum)){
|
||||
currentOrderVolume *= BotMarket.MinimumTradeVolume / Math.Abs(currentOrderVolume);
|
||||
}
|
||||
*/
|
||||
|
||||
double currentOrderVolume = currentVolumeRate.Volume * BasicSetup.RelativeTradeVolume;
|
||||
if (currentOrderVolume < BotMarket.MinimumTradeVolume)
|
||||
{
|
||||
currentOrderVolume = BotMarket.MinimumTradeVolume;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
double diffDT01 = this.GlidingHistories[0].dT - this.GlidingHistories[1].dT;
|
||||
|
||||
System.Tuple<double, double> currentOrderPrices = orderBook.getVolumePrice(Math.Abs(currentOrderVolume));
|
||||
double currentBuyRate = currentOrderPrices.Item1 / Math.Abs(currentOrderVolume);
|
||||
double currentSellRate = currentOrderPrices.Item2 / Math.Abs(currentOrderVolume);
|
||||
|
||||
double currentBuyMargin = lastOrderLimit * (1.0 - BasicSetup.MarginBuy);
|
||||
double currentSellMargin = lastOrderLimit * (1.0 + BasicSetup.MarginSell);
|
||||
|
||||
Log("Current: {0,11:###0.000000} {1,4} EMA: {2,11:###0.000000} {1}", currentCenterRate, BasicSetup.BaseSymbol, this.GlidingHistories[2].centerRate.CurrentValue);
|
||||
Log("qEMA: {0,8:###0.0000} % Target Volume: {1,11:###0.000000}", qEMA * 100, targetVolume);
|
||||
|
||||
Log("Current Market Balance: {0,11:###0.000000} {3,4} / {1,11:###0.000000} {4,4} = {2,11:###0.000000} {3,4}/{4,4}",
|
||||
currentVolumeRate.Price,
|
||||
currentVolumeRate.Volume,
|
||||
currentVolumeRate.UnityPrice,
|
||||
BasicSetup.BaseSymbol,
|
||||
BasicSetup.MarketSymbol);
|
||||
|
||||
Log("Current dT(0) - dT(1): {0,8:###0.0000} % / min Current dT(center): {1,8:###0.0000} %", diffDT01, currentValue.dT.CurrentValue);
|
||||
Log("Current Order Volume: {0,11:###0.000000} {2,4} ( Minimum Order Volume: {1,11:###0.000000} {2,4} )", currentOrderVolume, BotMarket.MinimumTradeVolume, BasicSetup.MarketSymbol);
|
||||
Log("Current Order Volume rates: {0,11:###0.000000} {2,4} [ BUY ] / {1,11:###0.000000} {2,4} [ SELL ]",currentBuyRate,currentSellRate,BasicSetup.BaseSymbol);
|
||||
Log("Current Order Margins: {0,11:###0.000000} {2,4} [ BUY ] / {1,11:###0.000000} {2,4} [ SELL ]", currentBuyMargin, currentSellMargin, BasicSetup.BaseSymbol);
|
||||
Log("{0}", this.detector.ToString());
|
||||
|
||||
if (BasicSetup.OrderFixedVolume != 0){
|
||||
if (!currentOrderID.IsNull()){
|
||||
cancelOrder(currentOrderID);
|
||||
} else {
|
||||
double orderVolume = Math.Abs(BasicSetup.OrderFixedVolume);
|
||||
OrderType orderType = BasicSetup.OrderFixedVolume > 0 ? OrderType.BUY : OrderType.SELL;
|
||||
double orderLimit = orderType == OrderType.BUY ? orderBook.CurrentAsk : orderBook.CurrentBid;
|
||||
|
||||
if (orderVolume >= BotMarket.MinimumTradeVolume)
|
||||
{
|
||||
Log("Creating fixed volume Order: {2,4} {0,11:###0.000000} {1,4}", orderVolume, BasicSetup.MarketSymbol, orderType);
|
||||
|
||||
Order o = createLimitOrder(orderType, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, orderVolume, orderLimit);
|
||||
if (o != null){
|
||||
currentOrderID = o.OrderID;
|
||||
}
|
||||
|
||||
BasicSetup.OrderFixedVolume = 0;
|
||||
Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Fixed volume too low for minimum Trade Size of {0,11:###0.000000} {1,4}", BotMarket.MinimumTradeVolume, BasicSetup.MarketSymbol);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (!currentOrderID.IsNull())
|
||||
{
|
||||
cancelOrder(currentOrderID);
|
||||
/* } else if (
|
||||
(this.GlidingHistories[2].dT.LastValue > 0) &&
|
||||
(this.GlidingHistories[2].dT.CurrentValue <= 0) &&
|
||||
(this.GlidingHistories[0].centerRate.CurrentValue < this.GlidingHistories[2].centerRate.CurrentValue) &&
|
||||
(currentSellRate >= currentSellMargin)
|
||||
)
|
||||
{*/
|
||||
} else if (this.detector.HighDetected && (currentSellRate >= currentSellMargin))
|
||||
{
|
||||
// Sell Signal
|
||||
Order o = createLimitOrder(OrderType.SELL, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, currentOrderVolume, currentSellRate);
|
||||
if (o != null)
|
||||
{
|
||||
currentOrderID = o.OrderID;
|
||||
lastOrderLimit = currentSellRate;
|
||||
}
|
||||
/* } else if (
|
||||
(this.GlidingHistories[2].dT.LastValue < 0) &&
|
||||
(this.GlidingHistories[2].dT.CurrentValue >= 0) &&
|
||||
(this.GlidingHistories[0].centerRate.CurrentValue >= this.GlidingHistories[2].centerRate.CurrentValue) &&
|
||||
(currentBuyRate <= currentBuyMargin)
|
||||
)*/
|
||||
} else if (this.detector.LowDetected && (currentBuyRate <= currentBuyMargin))
|
||||
{
|
||||
// Buy Signal
|
||||
Order o = createLimitOrder(OrderType.BUY, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, currentOrderVolume, currentBuyRate);
|
||||
if (o != null)
|
||||
{
|
||||
currentOrderID = o.OrderID;
|
||||
lastOrderLimit = currentBuyRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
double orderVolume = Math.Abs(currentOrderVolume);
|
||||
OrderType orderType = currentOrderVolume < 0 ? OrderType.SELL : OrderType.BUY;
|
||||
|
||||
if (orderVolume >= BotMarket.MinimumTradeVolume)
|
||||
{
|
||||
double margin = (orderType == OrderType.BUY) ? BasicSetup.MarginBuy : BasicSetup.MarginSell;
|
||||
double orderMargin = (orderType == OrderType.BUY) ? (currentVolumeRate.UnityPrice / currentBuyRate) - 1.0 : (currentSellRate / currentVolumeRate.UnityPrice) - 1.0;
|
||||
double orderLimit = (orderType == OrderType.BUY) ? currentBuyRate : currentSellRate;
|
||||
|
||||
if (orderMargin > margin){
|
||||
Log("Order Margin reached");
|
||||
|
||||
if (currentOrderID.IsNull())
|
||||
{
|
||||
if (
|
||||
((orderType == OrderType.BUY) && (diffDT01 >= 0) && (this.currentValue.dT.CurrentValue > -0.0025)) ||
|
||||
((orderType == OrderType.SELL) && (diffDT01 <= 0) && (this.currentValue.dT.CurrentValue < 0.0025))
|
||||
)
|
||||
{
|
||||
Order order = createLimitOrder(orderType, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, orderVolume, orderLimit);
|
||||
if (!order.IsNull()){
|
||||
currentOrderID = order.OrderID;
|
||||
targetVolume = 1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("waiting for dt...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelOrder(currentOrderID);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
DumpBalances();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Balancing()
|
||||
{
|
||||
if (!this.currentOrderID.IsNull()){
|
||||
Order currentOrder = getOrder(currentOrderID);
|
||||
|
||||
if (!currentOrder.IsOpen)
|
||||
{
|
||||
if (currentOrder.OrderType == OrderType.BUY){
|
||||
this.currentVolumeRate.Volume += currentOrder.FilledVolume;
|
||||
this.currentVolumeRate.Price += currentOrder.PayedPrice + currentOrder.PayedFees;
|
||||
} else {
|
||||
this.currentVolumeRate.Volume -= currentOrder.FilledVolume;
|
||||
this.currentVolumeRate.Price -= currentOrder.PayedPrice - currentOrder.PayedFees;
|
||||
}
|
||||
currentOrderID = null;
|
||||
}
|
||||
}
|
||||
base.Balancing();
|
||||
}
|
||||
|
||||
private void writeHistory(double currentCenterRate){
|
||||
historyWriter.Write("{0}\t{1}",DateTime.Now.ToString(),currentCenterRate.ToString(CultureInfo.InvariantCulture));
|
||||
/* for (int n = 0; n < this.GlidingCenterRates.Length;n++){
|
||||
historyWriter.Write("\t{0}\t{1}\t{2}",
|
||||
GlidingCenterRates[n].CurrentValue.ToString(CultureInfo.InvariantCulture),
|
||||
this.dT[n].ToString(CultureInfo.InvariantCulture),
|
||||
this.dTdT[n].ToString(CultureInfo.InvariantCulture)
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
foreach (GlidingHistory gh in this.GlidingHistories)
|
||||
{
|
||||
historyWriter.Write("\t{0}\t{1}\t{2}",
|
||||
gh.centerRate.CurrentValue.ToString(CultureInfo.InvariantCulture),
|
||||
gh.dT.CurrentValue.ToString(CultureInfo.InvariantCulture),
|
||||
gh.dTdT.CurrentValue.ToString(CultureInfo.InvariantCulture)
|
||||
);
|
||||
}
|
||||
|
||||
historyWriter.Write("\t{0}\t{1}\t{2}",
|
||||
currentValue.centerRate.CurrentValue.ToString(CultureInfo.InvariantCulture),
|
||||
currentValue.dT.CurrentValue.ToString(CultureInfo.InvariantCulture),
|
||||
currentValue.dTdT.CurrentValue.ToString(CultureInfo.InvariantCulture)
|
||||
);
|
||||
historyWriter.Write("\t{0}", targetVolume.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
|
||||
historyWriter.WriteLine();
|
||||
historyWriter.Flush();
|
||||
}
|
||||
|
||||
public enum RiseFall { NONE, DETECT, RISING, FALLING };
|
||||
|
||||
private class SimpleHighLowDetector
|
||||
{
|
||||
public RiseFall Currently { get; private set; } = RiseFall.NONE;
|
||||
|
||||
public double Margin { get; set; } = 0.005;
|
||||
|
||||
public double CurrentExtremum { get; private set; }
|
||||
|
||||
public bool LowDetected { get; private set; }
|
||||
public bool HighDetected { get; private set; }
|
||||
|
||||
public double LastLow { get; private set; }
|
||||
public double LastHigh { get; private set; }
|
||||
|
||||
public void Add(double value){
|
||||
LowDetected = false;
|
||||
HighDetected = false;
|
||||
|
||||
if (Currently == RiseFall.NONE)
|
||||
{
|
||||
CurrentExtremum = value;
|
||||
Currently = RiseFall.DETECT;
|
||||
} else if (Currently == RiseFall.DETECT)
|
||||
{
|
||||
if (value > (CurrentExtremum * (1 + Margin))){
|
||||
Currently = RiseFall.RISING;
|
||||
CurrentExtremum = value;
|
||||
} else if (value < (CurrentExtremum * ( 1 - Margin))){
|
||||
Currently = RiseFall.FALLING;
|
||||
CurrentExtremum = value;
|
||||
}
|
||||
} else {
|
||||
if (Currently == RiseFall.FALLING)
|
||||
{
|
||||
if (value < CurrentExtremum){
|
||||
CurrentExtremum = value;
|
||||
} else if (value > ((1.0 + Margin) * CurrentExtremum)){
|
||||
Currently = RiseFall.RISING;
|
||||
LowDetected = true;
|
||||
LastLow = CurrentExtremum;
|
||||
}
|
||||
} else if (Currently == RiseFall.RISING)
|
||||
{
|
||||
if (value > CurrentExtremum){
|
||||
CurrentExtremum = value;
|
||||
} else if (value < ((1.0 - Margin) * CurrentExtremum)){
|
||||
Currently = RiseFall.FALLING;
|
||||
HighDetected = true;
|
||||
LastHigh = CurrentExtremum;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[SimpleHighLowDetector: Currently={0}, Margin={1}, CurrentExtremum={2}, LowDetected={3}, HighDetected={4}]", Currently, Margin, CurrentExtremum, LowDetected, HighDetected);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class GlidingHistory {
|
||||
|
||||
public SmoothValue centerRate;
|
||||
public SmoothValue dT;
|
||||
public SmoothValue dTdT;
|
||||
|
||||
public GlidingHistory()
|
||||
: this(0.25)
|
||||
{
|
||||
}
|
||||
|
||||
public GlidingHistory(double k){
|
||||
this.centerRate = new SmoothValue(k);
|
||||
this.dT = new SmoothValue(k);
|
||||
this.dTdT = new SmoothValue(k);
|
||||
}
|
||||
|
||||
public Double Kp {
|
||||
get { return this.centerRate.Kp; }
|
||||
set {
|
||||
this.centerRate.Kp = value;
|
||||
this.dT.Kp = value;
|
||||
this.dTdT.Kp = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(double centerRateValue){
|
||||
if (centerRate.CurrentValue == 0){
|
||||
this.centerRate.Set(centerRateValue);
|
||||
}
|
||||
|
||||
this.centerRate.Add(centerRateValue);
|
||||
this.dT.Add(this.centerRate.dT);
|
||||
this.dTdT.Add(this.dT.dT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class DifferentialSetup : BasicBotSetup
|
||||
{
|
||||
public double MarketCheckVolume = 1;
|
||||
public double OrderFixedVolume;
|
||||
public bool IncreaseOrderVolumeToMinimum;
|
||||
|
||||
public bool ResetTargetVolume;
|
||||
|
||||
public double MarginBuy = 0.02;
|
||||
public double MarginSell = 0.02;
|
||||
|
||||
public double RelativeTradeVolume = 0.2;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
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()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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("BigBot")]
|
||||
[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,260 @@
|
|||
using System;
|
||||
using System.Net.Sockets;
|
||||
using sharp.trading;
|
||||
namespace sharp.tradebot
|
||||
{
|
||||
public class SimpleBot : TradingBot<BasicBotSetup>
|
||||
{
|
||||
public SimpleBotSetup Setup { get; private set; } = new SimpleBotSetup();
|
||||
|
||||
TradeStep[] TradeSteps;
|
||||
Market market;
|
||||
|
||||
public SimpleBot()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Prepare()
|
||||
{
|
||||
base.Prepare();
|
||||
|
||||
Setup = loadJSON<SimpleBotSetup>("setup.json");
|
||||
TradeSteps = loadJSON<TradeStep[]>("tradesteps.json");
|
||||
|
||||
checkTradeSteps();
|
||||
}
|
||||
|
||||
void checkTradeSteps(){
|
||||
if (TradeSteps.Length == 0){
|
||||
TradeSteps = new TradeStep[Setup.HalfSteps*2];
|
||||
for (int n = 0; n < TradeSteps.Length; n++){
|
||||
TradeSteps[n] = new TradeStep();
|
||||
TradeSteps[n].price_buy = Setup.CenterPrice * ((1.0 - Setup.HalfSpread) + ((double)n * Setup.HalfSpread / (Setup.HalfSteps)));
|
||||
TradeSteps[n].price_sell = TradeSteps[n].price_buy * (1.0 + Setup.Offset);
|
||||
TradeSteps[n].current_base_volume = StepBaseVolume();
|
||||
TradeSteps[n].current_market_volume = StepMarketVolume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double StepBaseVolume()
|
||||
{
|
||||
return Setup.ActiveBaseBalance / (2 * Setup.HalfSteps);
|
||||
}
|
||||
double StepMarketVolume()
|
||||
{
|
||||
return Setup.ActiveMarketBalance / (2 * Setup.HalfSteps);
|
||||
}
|
||||
|
||||
public bool IsRunnable(){
|
||||
if (Setup.marketSymbol == null || Setup.marketSymbol.Equals(""))
|
||||
return false;
|
||||
if (Setup.baseSymbol == null || Setup.baseSymbol.Equals(""))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Trade()
|
||||
{
|
||||
if (IsRunnable()){
|
||||
market = TradingEnvironment.DefaultConnection.openMarket(Setup.marketSymbol, Setup.baseSymbol);
|
||||
}
|
||||
|
||||
if (Setup.Enabled && IsRunnable()){
|
||||
|
||||
Log("SimpleBot is trading");
|
||||
|
||||
checkOrders();
|
||||
|
||||
} else if (IsRunnable()){
|
||||
Console.WriteLine("SimpleBot instance is not enabled: {0}",this.UID);
|
||||
|
||||
Market market = TradingEnvironment.DefaultConnection.openMarket(Setup.marketSymbol, Setup.baseSymbol);
|
||||
OrderBook orderbook = market.getOrderBook();
|
||||
|
||||
Console.WriteLine("Current Minimum Tradesize is {0:#0.00000000} {1}",market.MinimumTradeVolume,market.TradedSymbol);
|
||||
Console.WriteLine("Current Best Bid: {0:#0.00000000} {1} Current best Ask: {2:#0.00000000} {3} , so at the Moment I would...",orderbook.CurrentBid,Setup.baseSymbol,orderbook.CurrentAsk,Setup.baseSymbol);
|
||||
|
||||
foreach (TradeStep step in TradeSteps)
|
||||
{
|
||||
if (step.price_buy < orderbook.CurrentAsk)
|
||||
{
|
||||
Console.WriteLine("Buy {0,8:##0.0000} {1} @ {2,11:##0.000000} {3} := {4,11:##0.000000} {5}", step.volume_to_buy(step.current_base_volume), Setup.marketSymbol, step.price_buy, Setup.baseSymbol, step.volume_to_buy(step.current_base_volume) * step.price_buy, Setup.baseSymbol);
|
||||
}
|
||||
}
|
||||
foreach (TradeStep step in TradeSteps)
|
||||
{
|
||||
if (step.price_sell > orderbook.CurrentBid)
|
||||
{
|
||||
|
||||
Console.WriteLine("Sell {0,8:##0.0000} {1} @ {2,11:##0.000000} {3} := {4,11:##0.000000} {5}", step.volume_to_sell(step.current_market_volume * Setup.CenterPrice), Setup.marketSymbol, step.price_sell, Setup.baseSymbol, step.volume_to_sell(step.current_market_volume * Setup.CenterPrice) * step.price_sell, Setup.baseSymbol);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Console.WriteLine("SimpleBot instance is not enabled and not ready to run: {0}",this.UID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Sell(TradeStep step){
|
||||
if (!Setup.CancelAllOrders)
|
||||
{
|
||||
double volsell = step.volume_to_sell(step.current_market_volume * Setup.CenterPrice);
|
||||
|
||||
Order sell = createLimitOrder(OrderType.SELL, Setup.marketSymbol, Setup.baseSymbol, volsell, step.price_sell);
|
||||
step.current_sell_order_id = sell.OrderID;
|
||||
}
|
||||
}
|
||||
|
||||
void Buy(TradeStep step)
|
||||
{
|
||||
if (!Setup.CancelAllOrders)
|
||||
{
|
||||
double volbuy = step.volume_to_buy(step.current_base_volume);
|
||||
|
||||
Order buyorder = createLimitOrder(OrderType.BUY, Setup.marketSymbol, Setup.baseSymbol, volbuy, step.price_buy);
|
||||
step.current_buy_order_id = buyorder.OrderID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkOrders()
|
||||
{
|
||||
foreach (TradeStep step in TradeSteps)
|
||||
{
|
||||
switch (step.getState())
|
||||
{
|
||||
case StepState.BUYING:
|
||||
{
|
||||
Order order = getOrder(step.current_buy_order_id);
|
||||
|
||||
if (!order.IsOpen)
|
||||
{
|
||||
double mRes = order.FilledVolume * (Setup.Offset - Setup.Fee) * Setup.Reserve;
|
||||
|
||||
Setup.ActiveBaseBalance -= order.PayedPrice;
|
||||
Setup.ActiveBaseBalance -= order.PayedFees;
|
||||
Setup.ActiveMarketBalance += order.FilledVolume - mRes;
|
||||
Setup.ReservedMarketBalance += mRes;
|
||||
step.current_buy_order_id = null;
|
||||
|
||||
Log("BUYED: {0} {1} @ {2} {3} Cost: {4} {5}", order.FilledVolume, Setup.marketSymbol, order.LimitPrice, Setup.baseSymbol, order.PayedPrice + order.PayedFees, Setup.baseSymbol);
|
||||
|
||||
Sell(step);
|
||||
} else if (Setup.CancelAllOrders){
|
||||
TradingEnvironment.DefaultConnection.cancelOrder(order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case StepState.SELLING:
|
||||
{
|
||||
Order order = getOrder(step.current_sell_order_id);
|
||||
|
||||
if (!order.IsOpen)
|
||||
{
|
||||
double bRes = order.PayedPrice * (Setup.Offset - Setup.Fee) * Setup.Reserve;
|
||||
|
||||
Setup.ActiveBaseBalance += order.PayedPrice - bRes;
|
||||
Setup.ActiveBaseBalance -= order.PayedFees;
|
||||
Setup.ReservedBaseBalance += bRes;
|
||||
Setup.ActiveMarketBalance -= order.FilledVolume;
|
||||
step.current_sell_order_id = null;
|
||||
|
||||
Log("SOLD: {0} {1} @ {2} {3} Cost: {4} {5}", order.FilledVolume, Setup.marketSymbol, order.LimitPrice, Setup.baseSymbol, order.PayedPrice + order.PayedFees, Setup.baseSymbol);
|
||||
|
||||
Buy(step);
|
||||
} else if (Setup.CancelAllOrders){
|
||||
TradingEnvironment.DefaultConnection.cancelOrder(order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case StepState.NONE:
|
||||
if (step.price_buy < market.getOrderBook().CurrentAsk)
|
||||
{
|
||||
Buy(step);
|
||||
}
|
||||
else if (step.price_sell > market.getOrderBook().CurrentBid)
|
||||
{
|
||||
Sell(step);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Save()
|
||||
{
|
||||
if (Setup.Enabled)
|
||||
{
|
||||
saveJSON(Setup,"setup.json");
|
||||
saveJSON(TradeSteps, "tradesteps.json");
|
||||
}
|
||||
|
||||
base.Save();
|
||||
}
|
||||
|
||||
|
||||
public class SimpleBotSetup {
|
||||
public bool Enabled = false;
|
||||
public bool CancelAllOrders = false;
|
||||
|
||||
public string marketSymbol = "";
|
||||
public string baseSymbol = "";
|
||||
|
||||
public double CenterPrice;
|
||||
public double HalfSpread = 0.20;
|
||||
public double Offset = 0.0125;
|
||||
public int HalfSteps = 40;
|
||||
|
||||
public double ActiveMarketBalance = 0;
|
||||
public double ReservedMarketBalance = 0;
|
||||
public double ActiveBaseBalance = 0;
|
||||
public double ReservedBaseBalance = 0;
|
||||
|
||||
public double Reserve = 0.5;
|
||||
public double Fee = 0.0025;
|
||||
}
|
||||
|
||||
public enum StepState {
|
||||
NONE, SELLING, BUYING
|
||||
}
|
||||
|
||||
public class TradeStep {
|
||||
public double price_buy;
|
||||
public double price_sell;
|
||||
|
||||
public double current_base_volume;
|
||||
public double current_market_volume;
|
||||
|
||||
public string current_buy_order_id;
|
||||
public string current_sell_order_id;
|
||||
|
||||
public double volume_to_buy(double base_volume){
|
||||
return Math.Round(base_volume / price_buy, 4);
|
||||
}
|
||||
public double volume_to_sell(double base_volume)
|
||||
{
|
||||
return Math.Round(base_volume / price_sell, 4);
|
||||
}
|
||||
|
||||
public StepState getState(){
|
||||
if (current_buy_order_id != null){
|
||||
return StepState.BUYING;
|
||||
}
|
||||
if (current_sell_order_id != null){
|
||||
return StepState.SELLING;
|
||||
}
|
||||
return StepState.NONE;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[TradeStep buy={0,11:##.000000} sell={0,11:##.000000}]",price_buy,price_sell);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using sharp.json.attributes;
|
||||
namespace BigBot
|
||||
{
|
||||
[JSONClassPolicy( Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class SmoothValue
|
||||
{
|
||||
[JSONField(Alias = "last")]
|
||||
public double LastValue { get; private set; }
|
||||
|
||||
[JSONField( Alias = "current")]
|
||||
public double CurrentValue { get; private set; }
|
||||
|
||||
[JSONField(Alias = "Kp")]
|
||||
public double Kp { get; set; }
|
||||
|
||||
[JSONField(Alias = "sum")]
|
||||
private double sum;
|
||||
|
||||
public SmoothValue()
|
||||
{
|
||||
}
|
||||
public SmoothValue(double Kp)
|
||||
{
|
||||
this.Kp = Kp;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
this.sum = 0;
|
||||
}
|
||||
|
||||
public void Set(double value){
|
||||
this.sum = (value / this.Kp) - value;
|
||||
this.CurrentValue = value;
|
||||
this.LastValue = value;
|
||||
}
|
||||
|
||||
public void Add(double value)
|
||||
{
|
||||
LastValue = CurrentValue;
|
||||
|
||||
this.sum += value;
|
||||
CurrentValue = this.sum * this.Kp;
|
||||
this.sum -= CurrentValue;
|
||||
}
|
||||
|
||||
public double dT {
|
||||
get {
|
||||
return this.CurrentValue - this.LastValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator double(SmoothValue svalue){
|
||||
return svalue.CurrentValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
namespace sharp.tradebot
|
||||
{
|
||||
public class SpreadBot: TradingBot<BasicBotSetup>
|
||||
{
|
||||
public SpreadBot()
|
||||
{
|
||||
}
|
||||
|
||||
public override int SchedulingIntervall()
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
|
||||
public class Setup {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using sharp.json;
|
||||
using sharp.trading;
|
||||
using System.IO;
|
||||
namespace sharp.tradebot
|
||||
{
|
||||
public class StatisticalBot : TradingBot<BasicBotSetup>
|
||||
{
|
||||
FileBackedJSONValue<BotSetup> Setup;
|
||||
|
||||
public StatisticalBot()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize()
|
||||
{
|
||||
Setup = new FileBackedJSONValue<BotSetup>(Path.Combine(DataDirectory, "setup.json"));
|
||||
}
|
||||
|
||||
|
||||
public override void Prepare()
|
||||
{
|
||||
base.Prepare();
|
||||
|
||||
if (Setup.CurrentValue == null){
|
||||
Setup.CurrentValue = new BotSetup();
|
||||
Setup.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void Trade()
|
||||
{
|
||||
if (Setup.CurrentValue.Enabled)
|
||||
{
|
||||
Market market = TradingEnvironment.DefaultConnection.openMarket(Setup.CurrentValue.MarketSymbol, Setup.CurrentValue.BaseSymbol);
|
||||
OrderBook orderbook = market.getOrderBook();
|
||||
|
||||
OrderbookVolume[] obvolumes = orderbook.calculateVolumes(Setup.CurrentValue.OrderBookIndicationVolumina);
|
||||
Log("Current Orderbook Indications:");
|
||||
foreach (OrderbookVolume ovol in obvolumes)
|
||||
{
|
||||
Log("Volume: {0,15:#########0.0000} {1} BUY: {2,11:####0.00000000} {3} SELL: {4,11:####0.00000000} {3}", ovol.VolumeBuy, Setup.CurrentValue.MarketSymbol, ovol.PriceBuy, Setup.CurrentValue.BaseSymbol, ovol.PriceSell);
|
||||
Log(" RATIO: {0,11:####0.00000000} AVERAGE: {1,11:####0.00000000} {2}", ovol.PriceBuy / ovol.PriceSell, (ovol.AverageUnitPriceBuy + ovol.AverageUnitPriceSell) / 2, Setup.CurrentValue.BaseSymbol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override int SchedulingIntervall()
|
||||
{
|
||||
return 60;
|
||||
}
|
||||
|
||||
|
||||
class BotSetup {
|
||||
public bool Enabled;
|
||||
|
||||
public string MarketSymbol = "";
|
||||
public string BaseSymbol = "";
|
||||
|
||||
public double[] OrderBookIndicationVolumina = new double[] { 10, 25, 50, 100, 200, 400, 800, 1600, 3200 };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using sharp.json;
|
||||
using System.IO;
|
||||
using sharp.trading;
|
||||
using sharp.trading.cache;
|
||||
using sharp.extensions;
|
||||
using sharp.json.attributes;
|
||||
using sharp.tradebot;
|
||||
|
||||
namespace BigBot
|
||||
{
|
||||
[JSONClassPolicy(Policy = JSONPolicy.ATTRIBUTED)]
|
||||
public class TargetValueBot : TradingBot<SetupClass>
|
||||
{
|
||||
[JSONField]
|
||||
public string CurrentOrderID;
|
||||
|
||||
public override void Prepare()
|
||||
{
|
||||
base.Prepare();
|
||||
|
||||
TradingBotEnvironment.RegisterPeriodic(Trade,10);
|
||||
}
|
||||
|
||||
public override void Unprepare()
|
||||
{
|
||||
TradingBotEnvironment.UnregisterPeriodic(Trade);
|
||||
|
||||
base.Unprepare();
|
||||
}
|
||||
|
||||
|
||||
public void Trade()
|
||||
{
|
||||
TradeBotBalance balanceBase = getBalance(BasicSetup.BaseSymbol);
|
||||
TradeBotBalance balanceMarket = getBalance(BasicSetup.MarketSymbol);
|
||||
|
||||
if (BasicSetup.Enabled){
|
||||
Log("TargetValueBot V2 is trading...");
|
||||
OrderBook orderBook = BotMarket.getOrderBook();
|
||||
|
||||
double testVolume = balanceMarket.CurrentBalance;
|
||||
if (testVolume == 0){
|
||||
testVolume = 1;
|
||||
}
|
||||
|
||||
System.Tuple<double,double> currentValues = orderBook.getVolumePrice(testVolume);
|
||||
|
||||
// Log("Current Market Values: REBUY: {0,11:####0.00000000} {2} SELL: {1,11:####0.00000000} {2}", currentValues.Item1, currentValues.Item2, BasicSetup.BaseSymbol);
|
||||
//1 Log("Current Market Spread: {0,6:##0.00}%", ((currentValues.Item1 / currentValues.Item2)-1)*100);
|
||||
double currentMarketValue = currentValues.Item2;
|
||||
|
||||
double currentUnitValue = currentMarketValue / testVolume;
|
||||
double alpha = BasicSetup.TargetPrice / currentUnitValue;
|
||||
double beta = Math.Pow(alpha, BasicSetup.TargetExponent);
|
||||
|
||||
double finalTargetValue = BasicSetup.TargetValue * beta;
|
||||
|
||||
if (balanceMarket.CurrentBalance <= 0){
|
||||
currentMarketValue = 0;
|
||||
}
|
||||
|
||||
|
||||
double currentAbsDiff = finalTargetValue - currentMarketValue;
|
||||
double currentDiff = currentAbsDiff / finalTargetValue;
|
||||
|
||||
Log("Current Market Balance: {0,10:###0.0000} {1} Current Market Value: {2,10:###0.0000} {3}", balanceMarket.CurrentBalance, balanceMarket.Currency, currentMarketValue, balanceBase.Currency);
|
||||
Log("Current Market Price (bid): {0,10:###0.0000} {1}",currentUnitValue,balanceBase.Currency);
|
||||
Log("Current Target Value: {0,10:###0.0000} {1} Target Value Diff: {2,10:###0.0000} {1} [ {3,6:##0.00}% ]", finalTargetValue, balanceBase.Currency, currentAbsDiff,currentDiff * 100);
|
||||
|
||||
if (!CurrentOrderID.IsNull())
|
||||
{
|
||||
Order order = getOrder(CurrentOrderID);
|
||||
if (!order.IsOpen)
|
||||
{
|
||||
CurrentOrderID = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((currentDiff > BasicSetup.MarginBuy) || (-currentDiff > BasicSetup.MarginSell))
|
||||
{
|
||||
if (!CurrentOrderID.IsNull()){
|
||||
Log("Canceling old Order before creating new one.");
|
||||
TradingEnvironment.DefaultConnection.cancelOrder(CurrentOrderID);
|
||||
} 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 + (BasicSetup.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, BasicSetup.MarketSymbol, orderBook.CurrentAsk, BasicSetup.BaseSymbol, price);
|
||||
Order order = createLimitOrder(OrderType.BUY, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, diffMarket, orderBook.CurrentAsk);
|
||||
if (!order.IsNull()){
|
||||
CurrentOrderID = order.OrderID;
|
||||
}
|
||||
} else {
|
||||
// SELL
|
||||
diffMarket = -diffMarket;
|
||||
double window = orderBook.getVolumePrice(diffMarket).Item1 - orderBook.getVolumePrice(diffMarket).Item2;
|
||||
double price = orderBook.getVolumePrice(diffMarket).Item1 + (BasicSetup.WindowLevelToBuy * window);
|
||||
|
||||
Log("Will sell {0,11:####0.00000000} {1} @ {2,11:####0.00000000} {3} = {4,11:####0.00000000} {3}", diffMarket, BasicSetup.MarketSymbol, orderBook.CurrentBid, BasicSetup.BaseSymbol, price);
|
||||
Order order = createLimitOrder(OrderType.SELL, BasicSetup.MarketSymbol, BasicSetup.BaseSymbol, diffMarket, orderBook.CurrentBid);
|
||||
if (!order.IsNull()){
|
||||
CurrentOrderID = order.OrderID;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DumpBalances();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public override int SchedulingIntervall()
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class WeightedIndicator{
|
||||
public double Volume;
|
||||
public double Weight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SetupClass : BasicBotSetup
|
||||
{
|
||||
public double TargetValue = 0;
|
||||
public double TargetPrice = 0;
|
||||
public double TargetExponent = 3;
|
||||
|
||||
public double MarginSell = 0.02;
|
||||
public double MarginBuy = 0.02;
|
||||
|
||||
public double WindowLevelToBuy = 0.1;
|
||||
public double WindowLevelToSell = 0.8;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue