SE
Topics
Forum Topics not found
Replies
serebryana3
15 May 2024, 12:48
( Updated at: 16 May 2024, 05:31 )
RE: New Bot
PanagiotisCharalampous said:
Hi there,
Can you record a video demonstrating the exact steps you are following to encounter this issue?
Best regards,
Panagiotis
Hi there,
Here is the link to video
Thanks
@serebryana3
serebryana3
18 May 2024, 09:08 ( Updated at: 19 May 2024, 05:16 )
RE: RE: RE: New Bot
PanagiotisCharalampous said:
using System;
using System.Collections.Generic;
using System.Threading;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SampleTradingPanel : Robot
{
[Parameter("Vertical Position", Group = "Panel alignment", DefaultValue = VerticalAlignment.Top)]
public VerticalAlignment PanelVerticalAlignment { get; set; }
[Parameter("Horizontal Position", Group = "Panel alignment", DefaultValue = HorizontalAlignment.Left)]
public HorizontalAlignment PanelHorizontalAlignment { get; set; }
[Parameter("Risk_default", Group = "x", DefaultValue = 1.5, MinValue = 0.1, Step = 0.1)]
public double Risk { get; set; }
[Parameter("Risk_step", Group = "x", DefaultValue = 0.5, MinValue = 0.1)]
public double Risk_step { get; set; }
protected override void OnStart()
{
var tradingPanel = new TradingPanel(this, Symbol, Chart, Risk, Risk_step);
var border = new Border
{
VerticalAlignment = PanelVerticalAlignment,
HorizontalAlignment = PanelHorizontalAlignment,
Style = Styles.CreatePanelBackgroundStyle(),
Margin = "20 20 20 20",
Width = 245,
Child = tradingPanel
};
Chart.AddControl(border);
Chart.MouseUp += tradingPanel.Chart_MouseUp;
Chart.KeyDown += tradingPanel.Chart_KeyDown;
}
}
public class TradingPanel : CustomControl
{
private TextBox Input { get; set; }
private Button Limit { get; set; }
private Button Market { get; set; }
private readonly Robot _robot;
private readonly Symbol _symbol;
Chart _chart;
private double RiskStep { get; set; }
private bool UsePercent { get; set; }
LimitOrderState LimitState { get; set; }
bool IsLong { get; set; }
double LimitStopLoss { get; set; }
MarketOrderState MarketState { get; set; }
double MarketStopLoss { get; set; }
public TradingPanel(Robot robot, Symbol symbol, Chart chart, double riskDef, double riskStep)
{
_robot = robot;
_symbol = symbol;
_chart = chart;
RiskStep = riskStep;
AddChild(CreateContentPanel(riskDef));
}
internal void Chart_MouseUp(ChartMouseEventArgs obj)
{
try
{
#region Limit
if (LimitState == LimitOrderState.DetectingStopPrice)
{
LimitStopLoss = obj.YValue;
LimitState = LimitOrderState.PlacingLimitOrder;
Limit.Text = "ORDER";
if (obj.YValue > _symbol.Ask)
IsLong = false;
else if (obj.YValue < _symbol.Ask)
IsLong = true;
_chart.DrawHorizontalLine("StopLine", obj.YValue, Color.Red);
}
else if (LimitState == LimitOrderState.PlacingLimitOrder)
{
_chart.RemoveObject("StopLine");
double volume;
if (UsePercent)
{
volume = _symbol.VolumeForProportionalRisk(ProportionalAmountType.Balance, double.Parse(Input.Text), Math.Abs((obj.YValue - LimitStopLoss) / _symbol.PipSize));
volume = volume * _robot.Account.FreeMargin / _robot.Account.Balance;
volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.ToNearest);
}
else
{
volume = _symbol.VolumeForFixedRisk(double.Parse(Input.Text), Math.Abs((obj.YValue - LimitStopLoss) / _symbol.PipSize));
volume = volume * _robot.Account.FreeMargin / _robot.Account.Balance;
volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.ToNearest);
}
_robot.PlaceLimitOrderAsync(IsLong ? TradeType.Buy : TradeType.Sell, _symbol.Name, volume, obj.YValue, "CustomPanel", Math.Abs(obj.YValue - LimitStopLoss) / _symbol.PipSize, null,
(TradeResult result) =>
{
if (result != null && !result.IsSuccessful)
{
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
}
});
LimitState = LimitOrderState.PlacingTakeProfit;
Limit.Text = "TAKE";
}
else if (LimitState == LimitOrderState.PlacingTakeProfit)
{
_robot.ModifyPendingOrderAsync(_robot.PendingOrders[^1], _robot.PendingOrders[^1].TargetPrice, _robot.PendingOrders[^1].StopLossPips, Math.Abs(obj.YValue - _robot.PendingOrders[^1].TargetPrice) / _symbol.PipSize,
(TradeResult result) =>
{
if (result == null || !result.IsSuccessful)
{
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
}
});
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
}
#endregion
#region Market
if (MarketState == MarketOrderState.DetectingStopPrice)
{
MarketStopLoss = obj.YValue;
double volume;
double volume1;
if (UsePercent)
{
volume = _symbol.VolumeForProportionalRisk(ProportionalAmountType.Balance, double.Parse(Input.Text), Math.Abs((_symbol.Ask - MarketStopLoss) / _symbol.PipSize));
volume1 = volume;
volume = volume * _robot.Account.FreeMargin / _robot.Account.Balance;
volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.ToNearest);
}
else
{
volume = _symbol.VolumeForFixedRisk(double.Parse(Input.Text), Math.Abs((_symbol.Ask - MarketStopLoss) / _symbol.PipSize));
volume1 = volume;
volume = volume * _robot.Account.FreeMargin / _robot.Account.Balance;
volume = _symbol.NormalizeVolumeInUnits(volume, RoundingMode.ToNearest);
}
TradeType type = TradeType.Buy;
if (MarketStopLoss > _symbol.Ask)
type = TradeType.Sell;
var res = _robot.ExecuteMarketOrder(type, _symbol.Name, volume);
if (res != null)
{
_robot.ModifyPositionAsync(res.Position, MarketStopLoss, null, null);
_robot.Print($"volume {volume1}");
_robot.Print($"res.Position.VolumeInUnits {res.Position.VolumeInUnits}");
double dif = Math.Abs(volume1 - res.Position.VolumeInUnits) / volume1;
_robot.Print($"dif {dif}");
if (dif > 0.2d)
{
_robot.Print($"Разница между рассчитанным и исполненным объемом {Math.Round(dif,2) * 100}%");
_robot.Notifications.PlaySound(SoundType.Announcement);
}
}
MarketState = MarketOrderState.PlacingTakeProfit;
Market.Text = "STOP";
}
else if (MarketState == MarketOrderState.PlacingTakeProfit)
{
var lastPosition = _robot.Positions[^1];
if (lastPosition != null)
{
double newTakeProfitPrice = obj.YValue;
_robot.ModifyPositionAsync(lastPosition, lastPosition.StopLoss, newTakeProfitPrice,
(TradeResult result) =>
{
if (result == null || !result.IsSuccessful)
{
_robot.Print("Failed to modify the take profit: {0}", result.Error);
}
else
{
_robot.Print("Take profit successfully modified.");
}
});
}
else
{
_robot.Print("No open positions found.");
}
MarketState = MarketOrderState.Default;
Limit.Text = "MARKET";
}
#endregion
}
catch
{
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
MarketState = MarketOrderState.Default;
Market.Text = "MARKET";
}
}
internal void Chart_KeyDown(ChartKeyboardEventArgs obj)
{
if (obj.Key == Key.Escape)
{
_chart.RemoveObject("StopLine");
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
MarketState = MarketOrderState.Default;
Market.Text = "MARKET";
}
}
private Grid CreateContentPanel(double riskDef)
{
var grid = new Grid(1, 2)
{
Margin = 10
};
var gridLeft = new Grid(1, 3);
Input = CreateInput(riskDef);
gridLeft.AddChild(Input, 0, 0);
var percentMoneySwitchButton = CreateSwitchButton("$", Styles.CreateGreenButtonStyle());
gridLeft.AddChild(percentMoneySwitchButton, 0, 1);
var gridLeftInner = new Grid(2, 1);
var plusButton = CreatePlusMinusButton("+", Styles.CreateGreenButtonStyle());
gridLeftInner.AddChild(plusButton, 0, 0);
var minusButton = CreatePlusMinusButton("-", Styles.CreateGreenButtonStyle());
gridLeftInner.AddChild(minusButton, 1, 0);
gridLeft.AddChild(gridLeftInner, 0, 2);
var gridRight = new Grid(1, 2);
var limitButton = CreateLimitButton("LIMIT", Styles.CreateGreenButtonStyle());
gridRight.AddChild(limitButton, 0, 0);
var marketButton = CreateMarketButton("MARKET", Styles.CreateGreenButtonStyle());
gridRight.AddChild(marketButton, 0, 1);
grid.AddChild(gridLeft, 0, 0);
grid.AddChild(gridRight, 0, 1);
return grid;
}
private TextBox CreateInput(double riskDef)
{
var newInput = new TextBox
{
Margin = "2",
Text = riskDef.ToString(),
Style = Styles.CreateInputStyle()
};
return newInput;
}
private Button CreateSwitchButton(string text, Style style)
{
var button = new Button
{
Text = text,
Style = style,
Height = 28,
Margin = "2"
};
button.Click += (button) =>
{
if (button.Button.Text == "%")
{
button.Button.Text = "$";
UsePercent = false;
}
else
{
button.Button.Text = "%";
UsePercent = true;
}
};
return button;
}
private Button CreatePlusMinusButton(string text, Style style)
{
var button = new Button
{
Text = text,
Style = style,
Height = 12,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalContentAlignment = HorizontalAlignment.Center,
Margin = "2"
};
if (text == "+")
button.Click += args =>
{
if (double.TryParse(Input.Text, out double buf))
Input.Text = (buf + RiskStep).ToString();
};
else
button.Click += args =>
{
if (double.TryParse(Input.Text, out double buf))
Input.Text = (buf - RiskStep).ToString();
};
return button;
}
private Button CreateLimitButton(string text, Style style)
{
var button = new Button
{
Text = text,
Style = style,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalContentAlignment = HorizontalAlignment.Center,
Margin = "2"
};
button.Click += (button) =>
{
if (LimitState == LimitOrderState.Default)
LimitState = LimitOrderState.DetectingStopPrice;
MarketState = MarketOrderState.Default;
Market.Text = "MARKET";
if (button.Button.Text == "LIMIT")
button.Button.Text = "STOP";
};
Limit = button;
return button;
}
private Button CreateMarketButton(string text, Style style)
{
var button = new Button
{
Text = text,
Style = style,
VerticalContentAlignment = VerticalAlignment.Center,
HorizontalContentAlignment = HorizontalAlignment.Center,
Margin = "2"
};
button.Click += (button) =>
{
if (MarketState == MarketOrderState.Default)
MarketState = MarketOrderState.DetectingStopPrice;
LimitState = LimitOrderState.Default;
Limit.Text = "LIMIT";
if (button.Button.Text == "MARKET")
button.Button.Text = "STOP";
};
Market = button;
return button;
}
enum LimitOrderState
{
Default,
DetectingStopPrice,
PlacingLimitOrder,
PlacingTakeProfit
}
enum MarketOrderState
{
Default,
DetectingStopPrice,
PlacingTakeProfit
}
}
public static class Styles
{
public static Style CreatePanelBackgroundStyle()
{
var style = new Style();
style.Set(ControlProperty.CornerRadius, 3);
style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#292929"), 0.85m), ControlState.DarkTheme);
style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.85m), ControlState.LightTheme);
style.Set(ControlProperty.BorderColor, Color.FromHex("#3C3C3C"), ControlState.DarkTheme);
style.Set(ControlProperty.BorderColor, Color.FromHex("#C3C3C3"), ControlState.LightTheme);
style.Set(ControlProperty.BorderThickness, new Thickness(1));
return style;
}
public static Style CreateInputStyle()
{
var style = new Style(DefaultStyles.TextBoxStyle);
style.Set(ControlProperty.BackgroundColor, Color.FromHex("#1A1A1A"), ControlState.DarkTheme);
style.Set(ControlProperty.BackgroundColor, Color.FromHex("#111111"), ControlState.DarkTheme | ControlState.Hover);
style.Set(ControlProperty.BackgroundColor, Color.FromHex("#E7EBED"), ControlState.LightTheme);
style.Set(ControlProperty.BackgroundColor, Color.FromHex("#D6DADC"), ControlState.LightTheme | ControlState.Hover);
style.Set(ControlProperty.CornerRadius, 3);
return style;
}
public static Style CreateGreenButtonStyle()
{
return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
}
private static Style CreateButtonStyle(Color color, Color hoverColor)
{
var style = new Style(DefaultStyles.ButtonStyle);
style.Set(ControlProperty.Padding, new Thickness(2, 0, 2, 0));
style.Set(ControlProperty.BackgroundColor, color, ControlState.DarkTheme);
style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.DarkTheme | ControlState.Hover);
style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.LightTheme | ControlState.Hover);
style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.DarkTheme);
style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.LightTheme);
return style;
}
private static Color GetColorWithOpacity(Color baseColor, decimal opacity)
{
var alpha = (int)Math.Round(byte.MaxValue * opacity, MidpointRounding.AwayFromZero);
return Color.FromArgb(alpha, baseColor);
}
}
}
@serebryana3