Skip to content

Commit

Permalink
TTALGO-2105: First version of TPbot v.1.4 has been added
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewKhloptsau committed Nov 22, 2023
1 parent fe7a80d commit c1fc0b8
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 45 deletions.
2 changes: 1 addition & 1 deletion SoftFx.Common/Utility/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ public static bool TryGetDouble(string str, out double value)

public static string InvariantString(double val, string format = "F1") => val.ToString(format, CultureInfo.InvariantCulture);
}
}
}
13 changes: 13 additions & 0 deletions TPtoAllNewPositions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
TPtoAllNewPositions
===

## Idea
This bot does smth awesome


## Parameters



## Inputs

60 changes: 60 additions & 0 deletions TPtoAllNewPositions/TPtoAllNewPositions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using SoftFx.Routines;
using System.Text;
using System;
using System.Threading.Tasks;
using TickTrader.Algo.Api;

namespace TPtoAllNewPositions
{
[TradeBot(Category = "SoftFX Public", DisplayName = "TPtoAllNewPositions", Version = "1.0",
Description = "The bot emulates the TakeProfit for positions on Net account. It sets the specified TP for all new Net positions")]
public class TPtoAllNewPositions : SingleLoopBot<TPtoAllNewPositionsConfiguration>
{
private const string ConfigDefaultFileName = $"{nameof(TPtoAllNewPositions)}.tml";


[Parameter(DisplayName = "Config File", DefaultValue = $"{nameof(TPtoAllNewPositions)}.tml")]
[FileFilter("Toml Config (*.tml)", "*.tml")]
public File ConfigFile { get; set; }


protected override Task InitInternal()
{
LoopTimeout = Config.RunIntervalInSeconds * 1000;

if (Account.Type != AccountTypes.Net)
{
PrintError("Bot works only on Net account");
Abort();
}

return base.InitInternal();
}

protected override Task Iteration()
{
CheckConfigSymbols();
}


protected override string GetConfigFullPath() => ConfigFile.FullPath;

protected override string GetDefaultConfigFileName() => ConfigDefaultFileName;


private void CheckConfigSymbols()
{
var str = new StringBuilder(1 << 10);

foreach (var key in Config.SymbolsSettings.Keys)
if (Symbols[key].IsNull)
str.AppendLine($"Symbol {key} not found on server.");

if (Config.HasErrors)
Status.WriteLine($"Config error:{Environment.NewLine}{Config.GetAllErrors}");

if (str.Length > 0)
Status.WriteLine($"Config warning:{Environment.NewLine}{str}");
}
}
}
18 changes: 18 additions & 0 deletions TPtoAllNewPositions/TPtoAllNewPositions.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="TickTrader.Algo.Api" Version="1.*" />
<PackageReference Include="TickTrader.Algo.Tools" Version="1.*" />
</ItemGroup>

<ItemGroup>
<Content Include="README.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
97 changes: 97 additions & 0 deletions TPtoAllNewPositions/TPtoAllNewPositionsConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using SoftFx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TPtoAllNewPositions
{
public class TPtoAllNewPositionsConfiguration : BotConfig
{
[Nett.TomlIgnore]
public HashSet<string> ExcludeSymbolsHash { get; } = new();

[Nett.TomlIgnore]
public Dictionary<string, int> SymbolsTP { get; } = new();


public Dictionary<string, string> SymbolsSettings { get; set; }

public List<string> ExcludeSymbols { get; set; }


public int RunIntervalInSeconds { get; set; }

public int DefaultTPInPips { get; set; }

public int TpForCurrentPriceInPips { get; set; }


public TPtoAllNewPositionsConfiguration()
{
RunIntervalInSeconds = 600;
DefaultTPInPips = 100;
TpForCurrentPriceInPips = 5;

SymbolsSettings = new Dictionary<string, string>()
{
["AUDCAD"] = "200",
["AUDCHF"] = "200",
["USDMXN"] = "3000",
["USDRUB"] = "1000",
};

ExcludeSymbols = new List<string>() { "BTCUSD" };
}


public override void Init()
{
if (RunIntervalInSeconds <= 0)
throw new ValidationException($"{nameof(RunIntervalInSeconds)} must be greater than 0");

if (DefaultTPInPips < 0)
throw new ValidationException($"{nameof(DefaultTPInPips)} must be greater or equal than 0");

if (TpForCurrentPriceInPips < 0)
throw new ValidationException($"{nameof(TpForCurrentPriceInPips)} must be greater or equal than 0");

foreach ((var symbol, var tp) in SymbolsSettings)
if (int.TryParse(tp, out var pips))
PrintError($"{symbol} invalid tp = {tp} (cannot be parsed to int)");
else
SymbolsTP.TryAdd(symbol, pips);

ExcludeSymbolsHash.Clear();

foreach (var symbol in ExcludeSymbols)
ExcludeSymbolsHash.Add(symbol);
}


public bool TryGetTP(string symbol, out double tp)
{
tp = SymbolsTP.TryGetValue(symbol, out var pips) ? pips : DefaultTPInPips;

return ExcludeSymbolsHash.Contains(symbol);
}

public override string ToString()
{
var builder = new StringBuilder(1 << 10);

builder.AppendLine("Input config:")
.AppendLine($"{nameof(RunIntervalInSeconds)} = {RunIntervalInSeconds};")
.AppendLine($"{nameof(DefaultTPInPips)} = {DefaultTPInPips};")
.AppendLine($"{nameof(TpForCurrentPriceInPips)} = {TpForCurrentPriceInPips};")
.AppendLine()
.AppendLine($"[{nameof(SymbolsSettings)}]")
.Append($"{string.Join($"{Environment.NewLine}", SymbolsTP.Select(u => $"{u.Key}={u.Value}"))}")
.AppendLine()
.AppendLine($"[{nameof(ExcludeSymbols)}]")
.Append($"{string.Join(",", ExcludeSymbols)}");

return builder.ToString();
}
}
}
19 changes: 8 additions & 11 deletions TPtoAllNewPositionsInPercents/LimitWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ namespace TPtoAllNewPositionsInPercents
{
internal sealed class LimitWatcher
{
private readonly Dictionary<string, TradePair> _pairs = new Dictionary<string, TradePair>();
private readonly TPtoAllNewPositionsInPercents _bot;
private readonly Dictionary<string, TradePair> _pairs = new();
private readonly TPtoAllNewPositions _bot;


public LimitWatcher(TPtoAllNewPositionsInPercents bot)
public LimitWatcher(TPtoAllNewPositions bot)
{
_bot = bot;

UploadPosition();
CloseOldPositions(); //Closing a chain with a closed position
CloseOldOrders(); //Closing a chain with a closed position
}


Expand All @@ -35,22 +35,19 @@ private void AddTradePair(NetPosition position)
{
var symbol = position.Symbol;

if (!_pairs.ContainsKey(symbol))
if (!_pairs.ContainsKey(symbol) && !_bot.Config.IsExcludeSymbol(symbol))
_pairs.Add(symbol, new TradePair(_bot, symbol));
}

private void RemoveTradePair(NetPosition position)
{
var symbol = position.Symbol;

if (_pairs.TryGetValue(symbol, out TradePair pair))
{
_pairs.Remove(symbol);
if (_pairs.TryGetValue(symbol, out TradePair pair) && _pairs.Remove(symbol))
pair.RemoveChain();
}
}

private void CloseOldPositions() => _bot.Account.Orders.Where(u => u.Comment.StartsWith(_bot.CommentPrefix) && !_pairs.ContainsKey(u.Symbol)).ToList()
.ForEach(u => _bot.CancelOrder(u.Id));
private void CloseOldOrders() => _bot.Account.Orders.Where(u => u.Comment.StartsWith(_bot.CommentPrefix) && !_pairs.ContainsKey(u.Symbol)).ToList()
.ForEach(u => _bot.CancelOrder(u.Id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

namespace TPtoAllNewPositionsInPercents
{
[TradeBot(Category = "SoftFX Public", DisplayName = "TPtoAllNewPositionsInPercents", Version = "1.3",
[TradeBot(Category = "SoftFX Public", DisplayName = "TPtoAllNewPositions", Version = "1.4",
Description = "The bot emulates the TakeProfit for positions on Net account. Every time interval it checks the amount of positions and" +
" updates the limit orders set so that the Amount of position opened by a symbol is equivalent the amount of limit orders.")]
public class TPtoAllNewPositionsInPercents : SingleLoopBot<TPtoAllNewPositionsPercentsConfiguration>
public class TPtoAllNewPositions : SingleLoopBot<TPtoAllNewPositionsConfiguration>
{
private const string ConfigDefaultFileName = "TPtoAllNewPositionsInPercents.tml";
private const string ConfigDefaultFileName = "TPtoAllNewPositions.tml";

private LimitWatcher _limitWatcher;

Expand Down
Loading

0 comments on commit c1fc0b8

Please sign in to comment.