using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using AgenaTrader.API;
using AgenaTrader.Custom;
using AgenaTrader.Plugins;
using AgenaTrader.Helper;
using System.Collections;
using System.IO;
using System.Text;
using AgenaTrader.Plugins.MoneyHandler;
using System.Threading;
using System.Windows.Forms;
using System.Data.SqlTypes;
using System.Linq.Expressions;
using System.Net;
using System.Globalization;
///
/// Version: 2.0.1
/// -------------------------------------------------------------------------
/// Simon Pucher 2018
/// Christian Kovar 2018
/// -------------------------------------------------------------------------
/// Global utilities as a helper in Agena Trader Script.
/// -------------------------------------------------------------------------
/// Namespace holds all indicators and is required. Do not change it.
///
namespace AgenaTrader.UserCode
{
#region Constants
///
/// Constants to use in Agena Trader Scripts
///
public static class Const
{
//Default Files
public static readonly string DefaultFileStatistic = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Evaluation\\" + "Evaluation.csv";
//Default Strings
public const string DefaultStringDatafeedPeriodicity = "Periodicity of your data feed is suboptimal for this indicator!";
public const string DefaultStringDatafeedBarsRequired = "Please increase bars required!";
public const string DefaultStringDatafeedBarsRequiredCount = "Please increase bars required property to a minimum of {0} bars!";
public const string DefaultStringErrorDuringCalculation = "A problem has occured during the calculation method!";
public const string DefaultExitReasonEOD = "End of day";
//Default values for indicators
public const int DefaultOpenRangeSizeinMinutes = 60;
//Default opacity for drawing
public const int DefaultOpacity = 70;
public const int DefaultLineWidth = 2;
public const int DefaultLineWidth_small = 1;
public const int DefaultLineWidth_large = 3;
public static readonly Color DefaultArrowLongColor = Color.Lime;
public static readonly Color DefaultArrowLong2Color = Color.Green;
public static readonly Color DefaultArrowShortColor = Color.Tomato;
public static readonly Color DefaultArrowShort2Color = Color.Red;
public static readonly Color DefaultIndicatorColor = Color.Orange;
public static readonly Color DefaultIndicatorColor_GreyedOut = Color.Gray;
public static readonly DashStyle DefaultIndicatorDashStyle = DashStyle.Solid;
//Fibonacci Retracements
public const decimal DefaultFibonacciRetracement23_6 = 23.6m;
public const decimal DefaultFibonacciRetracement38_2 = 38.2m;
public const decimal DefaultFibonacciRetracement50 = 50;
public const decimal DefaultFibonacciRetracement61_8 = 61.8m;
public const decimal DefaultFibonacciRetracement100 = 100;
//Fibonacci Extensions
public const decimal DefaultFibonacciExtension161_8 = 161.8m;
public const decimal DefaultFibonacciExtension200 = 200;
public const decimal DefaultFibonacciExtension261_8 = 261.8m;
public const decimal DefaultFibonacciExtension423_6 = 423.6m;
}
#endregion
#region Global static Helper with functions and methods.
///
/// Default Soundfiles by AT
///
public enum Soundfile
{
Alert1,
Alert2,
Alert3,
Alert4,
Announcement,
AutoBreakEven,
AutoChase,
AutoTrail,
Blip,
Buzz,
Camera,
cashreg,
Connected,
ConnectionLost,
Limit_order_filled,
New,
notify,
OffsettedChange,
OrderCancelled,
OrderFilled,
OrderPending,
PositionClosed,
Reversing,
ringin,
ringout,
SOUND136,
StopFilled,
Stop_limit_order_filled,
Stop_order_filled,
TargetFilled,
WMonline
}
///
/// Global static Helper with functions and methods.
///
public static class GlobalUtilities
{
#region Sounds
///
/// Return the filename of the Soundfile.
///
///
///
public static string GetSoundfile(Soundfile soundfile) {
string returnfilename = null;
returnfilename = soundfile.ToString().Replace("_", "-");
returnfilename = returnfilename + ".wav";
return returnfilename;
}
#endregion
#region Colors
///
/// Adjust the brightness of a color.
/// e.g. use this function to create a similiar color in a button click event or on mouse hover.
///
///
///
///
public static Color AdjustBrightness(Color originalColour, double brightnessFactor)
{
return Color.FromArgb(originalColour.A, (int)(originalColour.R * brightnessFactor), (int)(originalColour.G * brightnessFactor), (int)(originalColour.B * brightnessFactor));
}
///
/// Adjust the opacity of a color.
/// e.g. use this function to change the alpha channel of the Color.
///
///
///
///
public static Color AdjustOpacity(Color originalColour, double opacityFactor)
{
return Color.FromArgb((int)(originalColour.A * opacityFactor), originalColour.R, originalColour.G, originalColour.B);
}
#endregion
#region Email
///
/// True if the email address is valid.
///
///
///
public static bool IsValidEmail(string email)
{
if (String.IsNullOrEmpty(email))
{
return false;
}
//todo one liner for .net 4.5
//Note that EmailAddressAttribute is less permissive than System.Net.Mail.MailAddress
//if (new EmailAddressAttribute().IsValid(email))
// return true;
//for .net 3.x
try
{
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}
/////
///// Returns the standard subject for Entry Signal Emails
/////
/////
/////
//public static string GetEmailSubjectEntrySignal(IInstrument instrument, OrderDirection orderaction)
//{
// return "Entry Signal " + instrument.Symbol + " " + orderaction.ToString();
//}
/////
///// Returns the standard text for Entry Signal Emails
/////
/////
/////
/////
//public static string GetEmailBodyEntrySignal(IInstrument instrument, OrderDirection orderaction, string strategyname, TimeFrame timeframe)
//{
// StringBuilder str = new StringBuilder();
// str.AppendLine("Strategy: " + strategyname);
// str.AppendLine("Instrument: " + instrument.Name);
// str.AppendLine("OrderAction: " + orderaction.ToString());
// str.AppendLine("TimeFrame: " + timeframe.ToString());
// return str.ToString();
//}
///
/// Returns the standard subject for emails on order execution.
///
///
///
public static string GetEmailSubject(IExecution execution)
{
return execution.Instrument.Symbol + " Order " + execution.PositionType.ToString() + " executed";
}
///
/// Returns the standard text for emails on order execution.
///
///
///
///
public static string GetEmailText(IExecution execution, string strategyname)
{
StringBuilder str = new StringBuilder();
str.AppendLine("Strategy: " + strategyname);
str.AppendLine("Order " + execution.Name + " on instrument " + execution.Instrument.Name + " was executed.");
str.AppendLine("Position: " + execution.PositionType.ToString());
str.AppendLine("Quantity: " + (execution.Order.Quantity).ToString("F2"));
str.AppendLine("Price: " + (execution.Order.Price).ToString("F2"));
str.AppendLine("Investment: " + (execution.Order.Quantity * execution.Order.Price).ToString("F2"));
return str.ToString();
}
#endregion
#region Markets
///
/// Changes money from one currency into another.
///
///
///
///
///
public static decimal MoneyExchange(double cashamount, Currencies current, Currencies target) {
return new Money(cashamount, current).ConvertToCurrency(target).RoundedAmount;
}
///
/// Calculates the position size regarding to risk management.
///
///
///
public static int AdjustPositionToRiskManagement(IAccountManager accountmanager, IPreferenceManager preferencemanager, IInstrument instrument, double lastprice)
{
//Get Risk Management from Account
IAccount account = accountmanager.GetAccount(instrument, true, true);
if (account == null)
{
return instrument.GetDefaultQuantity();
}
//get the RiskParams on this account connection
ConnectionRiskParams crp = preferencemanager.GetConnectionRiskParams(account.AccountConnection.ConnectionName);
InstrumentRiskParams irp = crp.InstrumentRiskParams[instrument.InstrumentType];
double maxpositionsizeincash = 0.0;
if (irp.BasePositionSizing == BasePositionSizing.OnAmountPerPosition)
{
maxpositionsizeincash = irp.InvestedAmountPerPosition;
}
else if (irp.BasePositionSizing == BasePositionSizing.OnRiskAmountPerTrade)
{
maxpositionsizeincash = account.CashValue / 100 * irp.MaxInvestedAmountPercentage;
}
else if (irp.BasePositionSizing == BasePositionSizing.OnInitialRisk)
{
//hack: because of backtesting
maxpositionsizeincash = account.CashValue / 100 * irp.MaxInvestedAmountPercentage;
}
else
{
throw new NotImplementedException("AdjustPositionToRiskManagement: BasePositionSizing " + irp.BasePositionSizing.ToString() + " not implemented", null);
}
//Check the type of instrument & return the position size
if (instrument.InstrumentType == InstrumentType.Index)
{
//return 1;
return instrument.GetDefaultQuantity();
}
if (instrument.InstrumentType == InstrumentType.Stock
|| instrument.InstrumentType == InstrumentType.CFD)
{
return (int)Math.Floor(decimal.ToDouble(MoneyExchange(maxpositionsizeincash, account.Currency, instrument.Currency)) / lastprice);
}
else if (instrument.InstrumentType == InstrumentType.CFD)
{
return instrument.GetDefaultQuantity();
}
else
{
throw new NotImplementedException("AdjustPositionToRiskManagement: InstrumentType " + instrument.InstrumentType.ToString() + " not implemented", null);
}
}
public static TimeSpan GetOfficialMarketOpeningTime(string Symbol)
{
//Gets official Stock Market Opening Time
//Dirty hack to handle different pre-market times
//technically we can not distinguish between pre-market and market data
//e.g. use this function to determine opening time for Dax-Index (09.00) or Nasdaq-Index(15.30)
if (Symbol.Contains("DE.30") || Symbol.Contains("DE-XTB"))
{
return new TimeSpan(9, 00, 00);
}
else if (Symbol.Contains("US.30") || Symbol.Contains("US-XTB"))
{
return new TimeSpan(15, 30, 00);
}
else
{
return new TimeSpan(9, 00, 00);
}
}
public static TimeSpan GetOfficialMarketClosingTime(string Symbol)
{
//Gets official Stock Market Closing Time
//e.g. use this function to determine closing time for Dax-Index (17.30) or Nasdaq-Index(22.00)
if (Symbol.Contains("DE.30") || Symbol.Contains("DE-XTB"))
{
return new TimeSpan(17, 30, 00);
}
else if (Symbol.Contains("US.30") || Symbol.Contains("US-XTB"))
{
return new TimeSpan(22, 00, 00);
}
else
{
return new TimeSpan(17, 30, 00);
}
}
#endregion
#region web harvester
private static decimal _vdax_new_value = 0;
private static DateTime? _vdax_new_lastcheck = null;
//Opening hours of VDAX are between: 08:50 - 17:50
private static TimeSpan _vdax_new_openinghours_open = new TimeSpan(8, 50, 0);
private static TimeSpan _vdax_new_openinghours_close = new TimeSpan(17, 50, 0);
private static TimeSpan _vdax_new_openinghours_marketdelay = new TimeSpan(0, 15, 0);
///
/// dirty http request for the current VDAX-New value from the onvista website
/// parsing is pretty dirty but does the job. anyway, expect some improvements or
/// adaption as soon as the onvista site is changing :D
///
/// vdax-new value
public static decimal GetCurrentVdaxNew(int _CheckEveryXSeconds)
{
bool checkonline = false;
//Check if we have not done this yet.
if (_vdax_new_lastcheck == null)
{
checkonline = true;
}
//Check the online service each x seconds
else if (_vdax_new_lastcheck.Value.AddSeconds(_CheckEveryXSeconds) <= DateTime.Now)
{
TimeSpan now = DateTime.Now.TimeOfDay;
//If the market is closed we do not need to ask the online service
if ((now >= _vdax_new_openinghours_open) && (now <= _vdax_new_openinghours_close.Add(_vdax_new_openinghours_marketdelay)))
{
checkonline = true;
}
}
//If true we check online for the data
if (checkonline)
{
string url = "http://www.onvista.de/index/VDAX-NEW-Index-12105789";
//Anfrage an die �bergebene URL starten
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
//Antwort-Objekt erstellen
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//Antwort Stream an Streamreader �bergeben
StreamReader sr = new StreamReader(response.GetResponseStream());
//Antwort (HTML Code) auslesen
string html = sr.ReadToEnd();
//Streamreader und Webanfrage schlie�en
sr.Close();
response.Close();
int first = html.IndexOf("