pinescript strategy - different result after script translation v2>v5 - pine-script-v5

v2vsv5i have a simple script , translate the version from v2 > v5 , it should be sucess and work on new ver.v5 but i face a problem that , the strategy entry/exit time is totally different after translate.(refer to photo,should clearly show the different) i double check the script and setting, should be no bug. (you can see the quantity of trade no. are same)
what i guess and want---
is it possible there is problem,some of internal-pine-script-fuction - logic which is different from v5 vs v2?
How to modify the v5 version script in order to get the same result(same strategy entry/exit time) with v2?
Printscreen here:
https://i.imgur.com/6KLSjnJ.gif
https://i.imgur.com/6KLSjnJ.gif
v2 script:
'//Heikin Ashi Strategy
strategy("Heikin Ashi",shorttitle="HA_R01",overlay=true,default_qty_value=1000,initial_capital=100000,currency=currency.USD)
res = input(title="Heikin Ashi Candle Time Frame", type=resolution, defval="1440")
hshift = input(0,title="Heikin Ashi Candle Time Frame Shift")
//Heikin Ashi Open/Close Price
ha_t = heikinashi(tickerid)
ha_open = security(ha_t, res, open[hshift])
ha_close = security(ha_t, res, close[hshift])
//Strategy
golong = (ha_close > ha_open )
goshort = (ha_close < ha_open )
strategy.entry("Buy",strategy.long,when = golong)
strategy.entry("Sell",strategy.short,when = goshort)
v5 script:
//Heikin Ashi Strategy
//#version=5
strategy("Heikin Ashiv5",shorttitle="HA_R01v5",overlay=true,default_qty_value=1000,initial_capital=100000,currency=currency.USD)
res = input.timeframe(title="Heikin Ashi Candle Time Frame", defval="D")
hshift = input(0,title="Heikin Ashi Candle Time Frame Shift")
//Heikin Ashi Open/Close Price
ha_t = ticker.heikinashi(syminfo.tickerid)
ha_open = request.security(ha_t, res, open[hshift])
ha_close = request.security(ha_t, res, close[hshift])
//Strategy
golong = (ha_close > ha_open )
goshort = (ha_close < ha_open )
strategy.entry("Buy",strategy.long,when = golong)
strategy.entry("Sell",strategy.short,when = goshort)here

Related

Looking for current price > previous day high . Works fine but plotting for all the 5 minutes candle

Here is my usecase :
if currentprice of 5 minutes candle is greater than previous day high , plot the chart with the 'x' mark in green .
If currentprice of 5 minutes candle is lesser than previous day low , plot the chart with 'x' mark in green
This script prints the 'x' mark for every 5 minutes but I want to plot only first for the first time when condition is met
I used a counter to check if it is a new day but seems that is not working as expected
//#version=5
indicator("HLPrice", max_lines_count = 11, overlay=true)
emaValue8 = ta.ema(close,8)
emaValue21 = ta.ema(close,21)
vwapValue = ta.vwap(hlc3)
// to highlight the session
timeframe = "1D"
isNewDay = timeframe.change(timeframe)
bgcolor(isNewDay ? color.new(color.green, 80) : na)
[dh,dl,dc] = request.security(syminfo.ticker, "D", [high[1],low[1], close[1]], lookahead=barmerge.lookahead_on)
isNewDayy = time("D") != time("D")[1]
var plotcond = false
greaterThanPreviousDayHigh = false
lesserThanPreviousDayLow = false
if isNewDayy
plotcond := true
if close[0] > dh and plotcond
greaterThanPreviousDayHigh:=true
if close[0] < dl and plotcond
lesserThanPreviousDayLow:=true
plotshape(series=greaterThanPreviousDayHigh , title="Candle on All EMAs" ,color = color.green, size=size.tiny)
plotshape(series=lesserThanPreviousDayLow , title="Candle on All EMAs" ,color = color.red, size=size.tiny)

Pine script - using buy limit/sell limit is not firing at an exact price

I am trying to enter using a buy limit order at an exact price using pine script eg. 146.090 but even though the price has gone under and over it - it still does not execute.
I do not want to use close/high/low etc, just the exact price.
It would be greatly appreciated if somebody had a workaround for the issue.
Thx.
//#version=5
VERSION = "V1"
SCRIPT_NAME = "Test " + VERSION
InitCapital = 100000
InitPosition = 100.0
InitCommission = 0.025
InitPyramidMax = 1
CalcOnorderFills = false
ProcessOrdersOnClose = true
CalcOnEveryTick = true
CloseEntriesRule = "FIFO"
strategy(title=SCRIPT_NAME, shorttitle=SCRIPT_NAME, overlay=true, pyramiding=InitPyramidMax, initial_capital=InitCapital, default_qty_type=strategy.fixed, process_orders_on_close=ProcessOrdersOnClose, default_qty_value=InitPosition, commission_type=strategy.commission.percent, calc_on_order_fills=CalcOnorderFills, calc_on_every_tick=CalcOnEveryTick, precision=9, max_lines_count=500, max_labels_count=500, commission_value=InitCommission)
var float entry = 145.606
strategy.entry("Long", strategy.long, limit=entry)
Try to replace :
strategy.entry("Long", strategy.long, limit=entry)
By :
strategy.entry("Long", strategy.long, limit=entry, close=entry)

Buy and sell-markers on lower time frames when longer time frame shows uptrend

So, I'm trying to run a trading bot on medium timeframes (1h - 4h) using the KDJ-indicator. I know it's not the most responsive indicator but it is very reliable, at least on higher time frames (8h - 1D).
What I would like to be able to do is use the following script to send BUY/SELL-signals to my bot, BUT ONLY when the asset is not trending down on the 1D-chart. In other words, I would like to run this script:
//#version=4
study(title="KDJ IndicatorTV", shorttitle="KDJ_TV", format=format.price, precision=2, resolution="", overlay=true)
periodK = input(9, title="K", minval=1)
periodD = input(5, title="D", minval=1)
smoothK = input(3, title="Smooth", minval=1)
multiplierJ = input(3.5, title="Jx", minval=0.1)
k = ema(stoch(hlc3, high, low, periodK), smoothK)
d = ema(k, periodD)
j = multiplierJ * k-2 * d
makeShape1 = if (crossover(j,d) or crossover(j,99))
true
else
false
plotshape(series=makeShape1, style=shape.cross, color=#0094FF, transp=10, text="buy", title='buy')
makeShape2 = if (crossunder(j,d) or crossunder(j,99))
true
else
false
plotshape(series=makeShape2, style=shape.cross, color=#FF6A00, transp=10, text="sell", title='sell')
//end
And I would like to add a condition to makeShape1, something like "AND If j>d on 1D-chart", to ensure that buys are only generated while J is larger than D on the 1D-chart of that asset (ie: when the market for that asset is in an uptrend).
Any ideas on if/how I can achieve that?
Thanks!
-Daniel
You can access higher TFs with security() function
//#version=4
study(title="KDJ IndicatorTV", shorttitle="KDJ_TV", format=format.price, precision=2, resolution="", overlay=true)
periodK = input(9, title="K", minval=1)
periodD = input(5, title="D", minval=1)
smoothK = input(3, title="Smooth", minval=1)
multiplierJ = input(3.5, title="Jx", minval=0.1)
k = ema(stoch(hlc3, high, low, periodK), smoothK)
d = ema(k, periodD)
j = multiplierJ * k-2 * d
j_sec = security(syminfo.tickerid, "D", j) // 1 day time frame for j
d_sec = security(syminfo.tickerid, "D", d) // 1 day time frame for d
makeShape1 = if (crossover(j,d) or crossover(j,99)) and j_sec > d_sec
true
else
false
plotshape(series=makeShape1, style=shape.cross, color=#0094FF, transp=10, text="buy", title='buy')
makeShape2 = if (crossunder(j,d) or crossunder(j,99))
true
else
false
plotshape(series=makeShape2, style=shape.cross, color=#FF6A00, transp=10, text="sell", title='sell')
//end

Anylogic Variable Not Updating

I an using a discrete event simulator in AnyLogic. I am having an issue with some code which updates a variable in my simulation. I store both the datetime at which the agent leaves the source block and the datetime at which it enters the sink block. I am trying to record the number of "rule breaks" for all agents. The rule break is defined below (two ways to break):
1) If the agent is received before a certain time (called SDC) and the agent is not completed by 5pm the same day, then the agent has broken the rule
2) If the agent is not completed by the next day at a certain time (called NDC), then the agent has broken the rule
I record a zero or a one for each agent if they break either rule in the variable called RuleBreak. However, in my simulation runs, the variable does not update at all. I hope I am just missing something small. Would appreciate any help! (code below)
Calendar received = Calendar.getInstance();
received.setTime(ReceivedDate);
Calendar completion = Calendar.getInstance();
completion.setTime(Completion);
Calendar SD_at_5 = Calendar.getInstance();
SD_at_5.setTime(ReceivedDate);
SD_at_5.set(Calendar.HOUR_OF_DAY,17);
SD_at_5.set(Calendar.MINUTE, 0);
SD_at_5.set(Calendar.SECOND, 0);
Calendar Tomorrow_at_NDC = Calendar.getInstance();
Tomorrow_at_NDC.setTime(ReceivedDate);
if(Tomorrow_at_NDC.get(Calendar.DAY_OF_WEEK) == 6)
Tomorrow_at_NDC.add(Calendar.DATE, 3);
else
Tomorrow_at_NDC.add(Calendar.DATE, 1);
Tomorrow_at_NDC.add(Calendar.DATE, 1);
Tomorrow_at_NDC.set(Calendar.HOUR_OF_DAY,NDC);
Tomorrow_at_NDC.set(Calendar.MINUTE, 0);
Tomorrow_at_NDC.set(Calendar.SECOND, 0);
int Either_rule_break = 0;
double time_diff_SDC = differenceInCalendarUnits(TimeUnits.SECOND,completion.getTime(),SD_at_5.getTime());
double time_diff_NDC = differenceInCalendarUnits(TimeUnits.SECOND,completion.getTime(),Tomorrow_at_NDC.getTime());
if((received.get(Calendar.HOUR_OF_DAY) < SDC) && (time_diff_SDC <= 0))
Either_rule_break = Either_rule_break + 1;
else
Either_rule_break = Either_rule_break + 0;
if((received.get(Calendar.HOUR_OF_DAY) >= SDC) && (time_diff_NDC <= 0))
Either_rule_break = Either_rule_break + 1;
else
Either_rule_break = Either_rule_break + 0;
if((Either_rule_break >= 1))
RuleBreak = RuleBreak + 1;
else
RuleBreak = RuleBreak + 0;
You haven't really explained where this code is used and what it receives. I assume the code is in a function, called in the sink's on-enter action, where ReceivedDate and Completion are Date instances stored per agent (source exit time and sink entry time, as dates, captured via AnyLogic's date() function).
And looks like your SDC hour-of-day is stored in SDC and your NDC hour-of-day in NDC (with RuleBreak being a variable in Main or similar storing the total number of rule-breaks).
Your calculations look OK except that the Tomorrow_at_NDC Calendar calculation seems wrong: you add 1 day twice (if not Saturday) or 3 days plus 1 day (if Saturday; in a Java Calendar, day-of-week 1 is Monday).
(Your Java is also very 'inefficient' with unnecessary extra local variables and performing logic when you don't need to; e.g., no point doing all the calendar preparation and check for your type 1 rule-break if the receive time is after the SDC hour.)
But are you sure there are any rule-breaks; how have you set up your model to ensure that there are (to test it)? Plus is RuleBreak definitely a variable outside of the agents that flow through your DES (i.e., in Main or similar)? Plus are Completion and ReceivedDate definitely stored per agent so, for example, if your function was called checkForRuleBreaks you would be doing something like the below in your sink on-exit action:
agent.Completion = date(); // Agent received date set earlier in Source action
checkForRuleBreaks(agent.ReceivedDate, agent.Completion);
(In fact, you don't need to store the completion date in the agent at all since that will always be the current sim-date inside your function and so you can just calculate it there.)

PID controller in C# Micro Framework issues

I have built a tricopter from scratch based on a .NET Micro Framework board from TinyCLR.com. I used the FEZ Mini which runs at 72 MHz. Read more about my project at: http://bit.ly/TriRot.
So after a pre-flight check where I initialise and test each component, like calibrating the IMU and spinning each motor, checking that I get receiver data, etc., it enters a permanent loop which then calls the flight controller method on each loop.
I'm trying to tune my PID controller now using the Ziegler-Nichols method, but I am always getting a progressively larger overshoot. I was eventually able to get a [mostly] stable oscillation using proportional control only (setting Ki and Kd = 0); timing the period K with a stopwatch averaged out to 3.198 seconds.
I came across the answer (by Rex Logan) on a similar question by chris12892.
I was initially using the "Duration" variable in milliseconds which made my copter highly aggressive, obviously because I was multiplying the running integrator error by thousands on each loop. I then divided it by another thousand to bring it to seconds, but I'm still battling...
What I don't understand from Rex's answer is:
Why does he ignore the time variable in the integral and differential parts of the equations? Is that right or is it a typo?
What he means by the remark
In a normal sampled system the delta term would be one...
One what? Should this be one second under normal circumstances? What
if this value fluctuates?
My flight controller method is below:
private static Single[] FlightController(Single[] imuData, Single[] ReceiverData)
{
Int64 TicksPerMillisecond = TimeSpan.TicksPerMillisecond;
Int64 CurrentTicks = DateTime.Now.Ticks;
Int64 TickCount = CurrentTicks - PreviousTicks;
PreviousTicks = CurrentTicks;
Single Duration = (TickCount / TicksPerMillisecond) / 1000F;
const Single Kp = 0.117F; //Proportional Gain (Instantaneou offset)
const Single Ki = 0.073170732F; //Integral Gain (Permanent offset)
const Single Kd = 0.001070122F; //Differential Gain (Change in offset)
Single RollE = 0;
Single RollPout = 0;
Single RollIout = 0;
Single RollDout = 0;
Single RollOut = 0;
Single PitchE = 0;
Single PitchPout = 0;
Single PitchIout = 0;
Single PitchDout = 0;
Single PitchOut = 0;
Single rxThrottle = ReceiverData[(int)Channel.Throttle];
Single rxRoll = ReceiverData[(int)Channel.Roll];
Single rxPitch = ReceiverData[(int)Channel.Pitch];
Single rxYaw = ReceiverData[(int)Channel.Yaw];
Single[] TargetMotorSpeed = new Single[] { rxThrottle, rxThrottle, rxThrottle };
Single ServoAngle = 0;
if (!FirstRun)
{
Single imuRoll = imuData[1] + 7;
Single imuPitch = imuData[0];
//Roll ----- Start
RollE = rxRoll - imuRoll;
//Proportional
RollPout = Kp * RollE;
//Integral
Single InstanceRollIntegrator = RollE * Duration;
RollIntegrator += InstanceRollIntegrator;
RollIout = RollIntegrator * Ki;
//Differential
RollDout = ((RollE - PreviousRollE) / Duration) * Kd;
//Sum
RollOut = RollPout + RollIout + RollDout;
//Roll ----- End
//Pitch ---- Start
PitchE = rxPitch - imuPitch;
//Proportional
PitchPout = Kp * PitchE;
//Integral
Single InstancePitchIntegrator = PitchE * Duration;
PitchIntegrator += InstancePitchIntegrator;
PitchIout = PitchIntegrator * Ki;
//Differential
PitchDout = ((PitchE - PreviousPitchE) / Duration) * Kd;
//Sum
PitchOut = PitchPout + PitchIout + PitchDout;
//Pitch ---- End
TargetMotorSpeed[(int)Motors.Motor.Left] += RollOut;
TargetMotorSpeed[(int)Motors.Motor.Right] -= RollOut;
TargetMotorSpeed[(int)Motors.Motor.Left] += PitchOut;// / 2;
TargetMotorSpeed[(int)Motors.Motor.Right] += PitchOut;// / 2;
TargetMotorSpeed[(int)Motors.Motor.Rear] -= PitchOut;
ServoAngle = rxYaw + 15;
PreviousRollE = imuRoll;
PreviousPitchE = imuPitch;
}
FirstRun = false;
return new Single[] {
(Single)TargetMotorSpeed[(int)TriRot.LeftMotor],
(Single)TargetMotorSpeed[(int)TriRot.RightMotor],
(Single)TargetMotorSpeed[(int)TriRot.RearMotor],
(Single)ServoAngle
};
}
Edit: I found that I had two bugs in my code above (fixed now). I was integrating and differentiating with the last IMU values as opposed to the last error values. That got rid of the runaway sitation completely. The only problem now is that it seems to be a bit slow. When I perturb the system, it responds very quickly and stop it from continuing, but it takes a long time to get back to the setpoint (0), about 10 seconds or more. Is this now just down to tuning the PID? I'll give the suggestions below a go, and let you know if any of them make a difference.
One question I have is:
being a .NET board, I don't want to bank on any kind of accurate timing, so instead of trying to work out at what frequency I am executing that method, surely if I calculate the actual time and factor that into the equations, it should be better, or am I misunderstanding something?