Skip to content

Commit

Permalink
Addition of version number
Browse files Browse the repository at this point in the history
  • Loading branch information
cwford committed May 21, 2020
1 parent cd2e1bf commit e528e56
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 96 deletions.
Binary file modified Lib/TDAmeritrade.dll
Binary file not shown.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img height="120" src="https://github.com/cwford/TDAmTrade_Zorro_Plugin/blob/master/Documentation/Images/zorro-tda.png">
</p>
<p align="center">
<strong>Version 1.0.1</strong>
<strong>Version 1.0</strong>
</p>
<p align="center">
<em><strong>A C# TD Ameritrade Broker Plug-In for Zorro.</strong></em>
Expand All @@ -18,6 +18,9 @@
</p>

## Overview
TDAmeritrade is a broker plug-in for Zorro, allowing it to communicate with TD Ameritrade using the TD Ameritrade REST API. This plug-in is free for non-commercial use. With this plug-in, you can use Zorro to automatically trade stocks, ETFs and options through your TD Ameritrade brokerage account. For information about getting started with this TD Ameritrade broker plug-in for Zorro, please see [the Wiki Documentation](https://github.com/cwford/TDAmTrade_Zorro_Plugin/wiki).
TDAmTrade is a broker plug-in for Zorro, allowing the Zorro trading engine to communicate with TD Ameritrade through the TD Ameritrade REST API. This plug-in is free for non-commercial use. With it, you can use Zorro to automatically trade stocks, ETFs and options with a TD Ameritrade brokerage account.

**Please note that you cannot trade indices (except through ETFs), futures, future options, or currency pairs (Forex) using this plug-in. The TD Ameritrade API does not allow for the trading of these instruments at the present time.**

For information about getting started with this TD Ameritrade broker plug-in for Zorro, please see [the Wiki Documentation](https://github.com/cwford/TDAmTrade_Zorro_Plugin/wiki).

**NOTE: The TD Ameritrade REST API does not allow for trading indices (except through ETFs), futures, future options, or currency pairs (Forex) through its REST API.**
14 changes: 14 additions & 0 deletions TDAmeritradeZorro.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.29521.150
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TDAmeritradeZorro", "TDAmeritradeZorro\TDAmeritradeZorro.csproj", "{5E3CB65B-FEAE-48C4-B16A-B25729626408}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "..\TDAZTest\Test.csproj", "{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -27,6 +29,18 @@ Global
{5E3CB65B-FEAE-48C4-B16A-B25729626408}.Release|x64.Build.0 = Release|Any CPU
{5E3CB65B-FEAE-48C4-B16A-B25729626408}.Release|x86.ActiveCfg = Release|Any CPU
{5E3CB65B-FEAE-48C4-B16A-B25729626408}.Release|x86.Build.0 = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|x64.ActiveCfg = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|x64.Build.0 = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|x86.ActiveCfg = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Debug|x86.Build.0 = Debug|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|Any CPU.Build.0 = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|x64.ActiveCfg = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|x64.Build.0 = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|x86.ActiveCfg = Release|Any CPU
{9FD803B1-8AA1-4A22-BF40-64BE4CC0246D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
245 changes: 160 additions & 85 deletions TDAmeritradeZorro/Classes/Broker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@
using TDAmeritradeZorro.Structs;
using TDAmeritradeZorro.Utilities;
using TDAmeritradeZorro.WebApi.Classes;
using Microsoft.Win32;
using System.Windows.Forms;
using DBLib.Classes;
using System.Reflection;

namespace TDAmeritradeZorro.Classes
{
Expand Down Expand Up @@ -114,7 +114,29 @@ public static class Broker
//*********************************************************************
private static Dictionary<long, string> jsonByOrderNum;

//*********************************************************************
// Members: Registry sub-key names
//
/// <summary>
/// Various registry ub-key names for the plug-in main registery entry.
/// </summary>
//*********************************************************************
private static readonly string LICENSE_ACCEPTANCE = "LicenseAcceptance";
public static readonly string VERSION_NUMBER = "VersionNumber";
private static readonly string VERSION_BUILD_DATE = "VersionDate";

//*********************************************************************
// Members: DATE_FORMAT_FULL
//
/// <summary>
/// A date format string
/// </summary>
///
/// <remarks>
/// Format date as Thu, 21 May 2020 14:23:39
/// </remarks>
//*********************************************************************
private static readonly string DATE_FORMAT_FULL = "ddd, dd MMM yyy HH:mm:ss";
#endregion PRIVATE MEMBERS

#region PUBLIC MEMBERS
Expand Down Expand Up @@ -286,41 +308,47 @@ public static bool
bool retCode;
AuthToken token = null;

// Is plug-in in test mode?
if (TDAmerAPI.opMode == OpMode.Demo)
try
{
// Has the license been accepted?
if (!LicenseAccepted())
{
// Log the error
LogHelper.Log(LogLevel.Error, $"{Resx.GetString("LICENSE_NOT_ACCEPTED")}");
return false;
}

// YES: Test mode is Demo mode. Run through the tests of the
// broker plug-in.
retCode = Tests.DoTests(settings.ClientId);
// NO: Give user a chance to accept the license; accepted?
if (!ShowLicenseForm())
{
// NO: Log the error
LogHelper.Log(LogLevel.Error, $"{Resx.GetString("LICENSE_NOT_ACCEPTED")}");

// Tests successful?
if (retCode)
{
// YES:
LogHelper.Log(LogLevel.Info, $"\r\n{Resx.GetString("SUCCESS").ToUpper()}: {Resx.GetString("SUCCESS_IN_TESTS")}.");
return false;
}
}
else

// Is plug-in in test mode?
if (TDAmerAPI.opMode == OpMode.Demo)
{
// NO:
LogHelper.Log(LogLevel.Error, $"\r\n{Resx.GetString("FAILURE").ToUpper()}: {Resx.GetString("ERRORS_IN_TESTS")}.");
}
// YES: Test mode is Demo mode. Run through the tests of the
// broker plug-in.
retCode = Tests.DoTests(settings.ClientId);

// Return a failure code, so processing stops with this method.
return false;
}
// Tests successful?
if (retCode)
{
// YES:
LogHelper.Log(LogLevel.Info, $"\r\n{Resx.GetString("SUCCESS").ToUpper()}: {Resx.GetString("SUCCESS_IN_TESTS")}.");
}
else
{
// NO:
LogHelper.Log(LogLevel.Error, $"\r\n{Resx.GetString("FAILURE").ToUpper()}: {Resx.GetString("ERRORS_IN_TESTS")}.");
}

// Return a failure code, so processing stops with this method.
return false;
}

try
{
// NO: Live trading mode
LogHelper.Log($" {Resx.GetString("READING")} {Resx.GetString("SETTINGS")} {Resx.GetString("FILE")}...");

// Initialize the currency interest rate dictionary. Use USD to
// force a read of all rates except HKD. Then, do HKB separately.
LogHelper.Log($" {Resx.GetString("INTEREST_RATE_INIT")}...");
Expand Down Expand Up @@ -2082,7 +2110,7 @@ int parameter
)
{
// Do not accept license
SaveLicenseAccepted(0);
Helper.SetRegistryValue(LICENSE_ACCEPTANCE, "0");

// Review the license
LicenseAccepted();
Expand Down Expand Up @@ -3964,69 +3992,27 @@ private static bool
// Method member
bool acceptance = false;

// Get the registry key for the plug-in
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\TDAmZorroPlugIn");

// Was the key found?
if (key != null)
// Are the app version numbers the same?
if (AppVersionNumbersEqual())
{
// YES: Read the value of "Accept"
using (key)
{
int accept = int.Parse(key.GetValue("Accept").ToString());
acceptance = accept == 1;
}
}
else
{
acceptance = false;
}
// YES: Get the registry value for the license acceptance
string acceptRegistry = Helper.GetRegistryValue(LICENSE_ACCEPTANCE);

// Was the license accepted
if (!acceptance)
{
// NO: Return result of accepting form
return ShowLicenseForm();
// Convert registery value to a boolean
if (!string.IsNullOrEmpty(acceptRegistry))
acceptance = int.Parse(acceptRegistry) == 1;
else
acceptance = false;
}
else
{
// YES: Return accetpance
return true;
// NO: Does not matter whether previous acceptance is on-file.
// New version number requires new acceptance.
acceptance = false;
}
}

//*********************************************************************
// Method: SaveLicenseAccepted
//
/// <summary>
/// Save acceptance of the user license for the plug-in
/// </summary>
///
/// <param name="accept">
/// 0 = not accepted
/// 1 = accepted
/// </param>
///
//*********************************************************************
private static void
SaveLicenseAccepted
(
int accept
)
{
// Get the registry key for the plug-in
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\TDAmZorroPlugIn");

// Was the key found?
if (key != null)
{
// YES: Read the value of "Accept"
using (key)
{
key.SetValue("Accept", accept.ToString());
key.Close();
}
}
// Return the value of acceptance
return acceptance;
}

//*********************************************************************
Expand Down Expand Up @@ -4058,15 +4044,15 @@ private static bool
if (result == DialogResult.Yes)
{
// Save the acceptance
SaveLicenseAccepted(1);
Helper.SetRegistryValue(LICENSE_ACCEPTANCE, "1");

// Return acceptance
return true;
}
else
{
// Save declination
SaveLicenseAccepted(0);
Helper.SetRegistryValue(LICENSE_ACCEPTANCE, "0");

// Return non-acceptance
return false;
Expand Down Expand Up @@ -4121,6 +4107,95 @@ string dateStr
/// </returns>
//*********************************************************************
private static long ToUnixEpoch(DateTime dateTime) => (long)(dateTime - new DateTime(1970, 1, 1)).TotalMilliseconds;

//*********************************************************************
// Method: AppVersionNumbersEqual
//
/// <summary>
/// Get the current app version number and build date.
/// </summary>
///
/// <returns>
/// True if the version (major and minor) has not changed, false if it
/// has changed.
/// </returns>
//*********************************************************************
public static bool
AppVersionNumbersEqual
()
{
// Method member
bool retVal = false;

// Get the app version from the executing assembly
var version = Assembly.GetExecutingAssembly().GetName().Version;

// Get the build date from the app date
var buildDate = new DateTime(2000, 1, 1)
.AddDays(version.Build).AddSeconds(version.Revision * 2);

// Stringify the registry app version
string versionString = version.ToString();

// Get the last app date from the registry
var regVersion = Helper.GetRegistryValue(VERSION_NUMBER);

// Get whether the last version is the same as the current version
retVal = CompareVersionNumbers(versionString, regVersion);

// Are the versions equal?
if (!retVal)
{
// NO: Save the current version number
Helper.SetRegistryValue(VERSION_NUMBER, versionString);

// Save the current build date
Helper.SetRegistryValue(VERSION_BUILD_DATE, buildDate.ToString(DATE_FORMAT_FULL));
}

// Return whether the registry key has changed
return retVal;
}

//*********************************************************************
// Method: CompareVersionNumbers
//
/// <summary>
/// Compare values for two version numbers.
/// </summary>
///
/// <param name="versionA">
/// First version number.
/// </param>
///
/// <param name="versionB">
/// Second version number.
/// </param>
///
/// <returns>
/// True if the major and minor version numbers are the same, false if
/// they are not.
/// </returns>
//*********************************************************************
public static bool
CompareVersionNumbers
(
string versionA,
string versionB
)
{
// Split apart the versions
string[] A = versionA.Split('.');
string[] B = versionB.Split('.');

// Array of version number parts needs to be the same or versions
// are not equal
if (A.Length != B.Length) return false;

// Return comparison of major and minor version numbers
return (Convert.ToInt32(A[0])) == Convert.ToInt32(B[0]) &&
(Convert.ToInt32(A[1])) == Convert.ToInt32(B[1]);
}
#endregion PRIVATE METHODS
}
}
10 changes: 5 additions & 5 deletions TDAmeritradeZorro/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TDAmeritradeZorro")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyDescription("TD Ameritrade - Zorro Broker Plug-In")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("Clyde W. Ford")]
[assembly: AssemblyProduct("TDAmeritradeZorro")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
Loading

0 comments on commit e528e56

Please sign in to comment.