Open Source Build - Big Bar Robot - JOIN IN
29 Oct 2013, 01:49
Ok... I am going to try something different see if people get on board.
I am still learning C# and need to solve many problems to learn.. so I decided to post some open source projects to get people involved share the code openly.
So the first project is a robot that enters trades when the last bar in the timeframe is x times larger than the last y bars in the timeframe above.
That is if the last 15 min bar has a range that is greater than the last 4 30min bars posted and the direction is up it buys if its down it sells. The robot compares all timeframes and the higher the timeframe (e.g 1hr > the last 5 4h bars) would be a stronger signal and the volume would be higher..
At this point I am stuck on using lists.. so anyone wants to help I will post the version as we go..
// -------------------------------------------------------------------------------------------------
//
//
//
//
// -------------------------------------------------------------------------------------------------
using System;
using System.Linq;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.API.Requests;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.CentralStandardTime)]
public class BigBarRobot : Robot
{
[Parameter(DefaultValue = "BigBarRobot")]
public string LabelName { get; set; }
[Parameter("Source")]
// CLOSE, HIGH, LOW...
public DataSeries Source { get; set; }
[Parameter("Periods", DefaultValue = 14)]
public int Periods { get; set; }
[Parameter("Volume", DefaultValue = 10000, MinValue = 1000)]
public int Volume { get; set; }
protected int PositionsCount
{
//Counts the positions made by this Robot
get { return Account.Positions.Count(thisRobotsCurrPos => thisRobotsCurrPos.Label == LabelName); }
}
//variable set outside onBar() to preserve the value on next call
//ERROR HANDLER
private bool LastOrderSuccessful = true;
//POSITIONS
private readonly List<Position> _OpenPositions = new List<Position>();
private Position LastBuyPositionOpened = null;
//TRIGGER
private int TriggerLevel = 1;
//Variables MarketSeries Data
MarketSeries min5;
MarketSeries min15;
MarketSeries min30;
MarketSeries hour1;
MarketSeries hour4;
//Cummulative array of marketSeries Data
private readonly List<double> _Cumm5 = new List<double>(10);
private readonly List<double> _Cumm15 = new List<double>(10);
private readonly List<double> _Cumm30 = new List<double>(10);
private readonly List<double> _Cumm1h = new List<double>(10);
private readonly List<double> _Cumm4h = new List<double>(10);
//Initialising Robot the first time
protected override void OnStart()
{
//Intialise Variables
min5 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute5);
min15 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute15);
min30 = MarketData.GetSeries(Symbol.Code, TimeFrame.Minute30);
hour1 = MarketData.GetSeries(Symbol.Code, TimeFrame.Hour);
hour4 = MarketData.GetSeries(Symbol.Code, TimeFrame.Hour4);
//Initialise the Cummulative Arrays to 0
Print("List initialised");
//_Cumm15[0] = 0;
//_Cumm30[0] = 0;
//_Cumm1h[0] = 0;
//_Cumm4h[0] = 0;
}
//*************************
//called on each onBar() or onTick()
//*************************
protected override void OnBar()
{
//--------------------------
//Do nothing if system is busy
//--------------------------
if (Trade.IsExecuting)
return;
var lastIndex = MarketSeries.Close.Count - 1;
// Get Current ranges
double CurrRng5 = min5.High.LastValue - min5.Low.LastValue;
double CurrRng15 = min15.High.LastValue - min15.Low.LastValue;
double CurrRng30 = min30.High.LastValue - min30.Low.LastValue;
double CurrRng1h = hour1.High.LastValue - hour1.Low.LastValue;
double CurrRng4h = hour4.High.LastValue - hour4.Low.LastValue;
// Print("h {0}", min5.High[min5.High.Count]);
// Print("i {0}", min5.High[min5.High.Count - 1]);
//update array of cummulative ranges of last 30 bars
// Print("Val H {0}", min5.High[min5.High.Count - 1]);
// Print("Val H {0}", min5.High[min5.High.Count - 2]);
//Print("Val H {0}", min5.High[lastIndex - 1]);
//Print("Val H {0}", min5.High[lastIndex]);
for (int i = MarketSeries.High.Count - 1; i > MarketSeries.High.Count - 11; i--)
{
Print("Val H {0}", min5.High[i]);
Print("Val Cnt {0}", MarketSeries.High.Count);
// _Cumm5[i - 1] = min5.High[min5.High.Count - i] - min5.Low[min5.Low.Count - i] + _Cumm5[i];
//Print("Val H {0}", min5.High[min5.High.Count - i]);
// Print("{0}", _Cumm5.Count);
// double H = min5.High[i];
// double L = min5.Low[i];
// double Ct = min5.High.Sum(i);
// Print("Val L{0}", min5.Low[min5.Low.Count - i]);
// _Cumm5.Add(H - L);
//Print("Cumm: {0}", _Cumm5[i].ToString());
// Print("H {0}", H);
// Print("L {0}", L);
// Print("Rng {0}", H - L);
}
Print("ENDDDD");
}
//check if last 5 is greater than x periods of 15
//Start Functions here ...
///
/// Create Conditional Buy Order
///
private void ConditionalBuy()
{
LastOrderSuccessful = true;
//Buy ONCE at each trigger level when the Buy price is under the trigger price
if (LastOrderSuccessful)
{
Print("CO() ***** CONDITIONAL ORDER SUCCESSFUL!! *****");
}
}
///
/// Close all position in list of specified type
///
private void CloseAllPositions(string PosType)
{
if (PositionsCount == 0)
return;
if (PosType == "Buy")
{
foreach (Position position in _OpenPositions)
{
if (position.TradeType == TradeType.Buy)
{
ClosePosition(position);
}
}
}
}
///
/// Add newly opened position to list
///
///
protected override void OnPositionOpened(Position openedPosition)
{
//Add to list
if (openedPosition == null)
return;
_OpenPositions.Add(openedPosition);
if (openedPosition.TradeType == TradeType.Buy)
LastBuyPositionOpened = openedPosition;
}
///
/// Remove closed position from list
///
///
protected override void OnPositionClosed(Position closedPosition)
{
if (closedPosition == null)
return;
if (_OpenPositions.Contains(closedPosition))
{
_OpenPositions.Remove(closedPosition);
}
}
///
/// Trade Statistics
///
private void TradeStats(string Trade_Type)
{
double TotalPipProfit = 0;
double TotalDollarProfit = 0;
double AvgEntryPrice = 0;
double TotalCommissions = 0;
double AvgClosePrice = 0;
double LastTradePrice = 0;
double LastTradeProfit = 0;
int ActivePositions = 0;
if (PositionsCount == 0)
{
Print("Exception - No Orders");
return;
}
if (Trade_Type == "Buy")
{
// foreach (var pos in Account.Positions).where(thisRobotsCurrPos => thisRobotsCurrPos.Label == LabelName);
foreach (Position position in _OpenPositions)
{
if (position.TradeType == TradeType.Buy)
{
TotalPipProfit += position.Pips;
TotalDollarProfit += position.NetProfit;
AvgEntryPrice += position.EntryPrice;
TotalCommissions += position.Commissions;
ActivePositions++;
}
}
}
AvgEntryPrice = Math.Round((AvgEntryPrice / ActivePositions), Symbol.Digits);
Print("*********************************{0}", Environment.NewLine);
Print("Number of Active Buy Orders = {0}", ActivePositions);
Print("Total PIP Profits on all Buy Orders = {0}", TotalPipProfit);
Print("Total $$ Profits on all Buy Orders = {0}", TotalDollarProfit);
Print("Total Commissions Paid on Buy Orders = {0}", TotalCommissions);
Print("Average Entry on Buy Orders = {0}", AvgEntryPrice);
Print("Last Position opened is making {0} (PIPS)", LastBuyPositionOpened.Pips);
Print("*********************************{0}", Environment.NewLine);
}
///
/// Create Market Buy Order, Sets New Target and Sleeps Agent
///
private void Buy()
{
Trade.CreateBuyMarketOrder(Symbol, Volume);
//Reset Trigger and send agent to sleep
if (LastOrderSuccessful)
Print("BO() Buy Order Successful");
}
///
/// Close Single Position
///
///
private void ClosePosition(Position pos)
{
if (pos == null)
return;
Trade.Close(pos);
}
///
/// Error Handler
///
protected override void OnError(Error err)
{
// Print the error to the log
switch (err.Code)
{
case ErrorCode.BadVolume:
Print("Bad Volume");
LastOrderSuccessful = false;
break;
case ErrorCode.TechnicalError:
LastOrderSuccessful = false;
Print("Trade Unsuccessful - Technical Error TradeSuccessful = {0}", LastOrderSuccessful);
break;
case ErrorCode.NoMoney:
Print("No Money");
LastOrderSuccessful = false;
break;
case ErrorCode.Disconnected:
Print("Disconnected");
LastOrderSuccessful = false;
break;
case ErrorCode.MarketClosed:
Print("Market Closed");
LastOrderSuccessful = false;
break;
}
}
public void DrawLine(int TriggerLevel)
{
int lastIndex = MarketSeries.OpenTime.Count - 1;
DateTime now = MarketSeries.OpenTime[lastIndex];
DateTime end = now.AddHours(5);
Colors color;
switch (1)
{
case 1:
color = Colors.Red;
break;
case 2:
color = Colors.Green;
break;
case 3:
color = Colors.Blue;
break;
default:
color = Colors.MediumPurple;
break;
}
//Print("DL() Preparing to Draw Line @ TriggerPrice = {0} from Now:{1} to End {2}", CurrTriggerLevel, now, end);
// ChartObjects.DrawLine("Trigger", now, CurrTriggerLevel, end, CurrTriggerLevel, color);
}
//end class SmartBuy Robot
}
// end namespace
}
Replies
jhtrader
29 Oct 2013, 22:31
RE:
Kate said:
Since you try to save last 11 values you can use array instead of list. I guess something like this:
private const int BarsCount = 11; private readonly double[] _Cumm5 = new double[BarsCount]; ... var index = min5.High.Count - 1; for (int i = 0; i < BarsCount; i++) { _Cumm5[i] = _Cumm5[i] + min5.High[index - i] - min5.Low[index - i]; }
Thanks.. I guess the benefit is that it is less resource intensive right? I will switch it over..since I dont need to dynamically resize the array. I used lists to get more familiar with them..
jhtrader
30 Oct 2013, 17:22
Arrays works fine but...
Hi,
I cannot pass in the parameter Periods when initialising the array
[Parameter("Periods", DefaultValue = 10)]
public int Periods { get; set; }
private const int blah = 10;
private readonly double[] _Cumm2 = new double[blah];
Any idea why??? I tried to set blah to Periods and I tried to put Periods directly but the compiler saw through my wicked scheme and didnt allow it.. .
Can I make the list non resisable and the values on the next bar just overrite the previous and still use lists.. ?? Currently if I want to use lists I have to clear the list at the beginning of the next bar. I cant see any real perf diff in arrays and lists.. have you had any experience with the performance diff?
hichem
30 Oct 2013, 17:41
RE: Arrays works fine but...
That will not work like that. The Parameter attribute will set the Periods variable after the creation of the _Cumm2 variable.
You should initialize the _Cumm2 variable in the Start() method of the robot is you want to use a value set by a parameter attribute.
jhtrader said:
Hi,
I cannot pass in the parameter Periods when initialising the array
[Parameter("Periods", DefaultValue = 10)]
public int Periods { get; set; }private const int blah = 10;
private readonly double[] _Cumm2 = new double[blah];Any idea why??? I tried to set blah to Periods and I tried to put Periods directly but the compiler saw through my wicked scheme and didnt allow it.. .
Can I make the list non resisable and the values on the next bar just overrite the previous and still use lists.. ?? Currently if I want to use lists I have to clear the list at the beginning of the next bar. I cant see any real perf diff in arrays and lists.. have you had any experience with the performance diff?
@hichem
jeex
03 Nov 2013, 16:55
Interesting plan
Interesting approach of prize trading. But why make the code so complex, if the strategyis so simple? I have a few questions:
What is the exit strategy?
What are TakeProfit and StopLoss based upon?
Do you have a fail safe strategy? ie. MacD or SMA?
With the simple piece of code for only the m15 bar, results are sort of promising.
int dezeBar = MarketSeries.Open.Count - 1;
int m30bar = m30.Open.Count - 1;
int shift = 0;
// breedte vorige bar;
double dif = (MarketSeries.Close[dezeBar - 1] - MarketSeries.Open[dezeBar - 1]);
double dif1 = Math.Abs(m30.Close[m30bar - 2] - m30.Open[m30bar - 2]);
double dif2 = Math.Abs(m30.Close[m30bar - 3] - m30.Open[m30bar - 3]);
double dif3 = Math.Abs(m30.Close[m30bar - 4] - m30.Open[m30bar - 4]);
double dif4 = Math.Abs(m30.Close[m30bar - 5] - m30.Open[m30bar - 5]);
MarketOrderRequest ma;
if (dif >= 0)
{
// onderzoek long
if (dif > dif1 && dif > dif2 && dif > dif3 && dif > dif4 && sma20.Result.IsRising())
{
Print("open een trade LONG op " + mooieTijd(MarketSeries.OpenTime.LastValue));
ma = new MarketOrderRequest(TradeType.Buy, 1000);
ma.Label = _LABEL;
ma.StopLossPips = SL;
ma.TakeProfitPips = TP;
ma.SlippagePips = 1;
Trade.Send(ma);
}
}
else
{
// onderzoek short
dif = dif * (-1);
if (dif > dif1 && dif > dif2 && dif > dif3 && dif > dif4 && sma20.Result.IsFalling())
{
Print("open een trade LONG op " + mooieTijd(MarketSeries.OpenTime.LastValue));
ma = new MarketOrderRequest(TradeType.Sell, 1000);
ma.Label = _LABEL;
ma.StopLossPips = SL;
ma.TakeProfitPips = TP;
ma.SlippagePips = 1;
Trade.Send(ma);
}
}
@jeex

Kate
29 Oct 2013, 10:44
Since you try to save last 11 values you can use array instead of list. I guess something like this:
private const int BarsCount = 11; private readonly double[] _Cumm5 = new double[BarsCount]; ... var index = min5.High.Count - 1; for (int i = 0; i < BarsCount; i++) { _Cumm5[i] = _Cumm5[i] + min5.High[index - i] - min5.Low[index - i]; }@Kate